# Spring Cloud Gateway簡介
Gateway是基于SpringBoot 2,構建在Spring生態之上的API網關。提供一種簡單而有效的途徑來轉發請求,并為他們提供橫切關注點。有以下功能:
* 支持動態路由
* 支持內置到Spring Handler映射中的路由匹配
* 支持基于HTTP請求的路由匹配
* 過濾器作用于匹配的路由
* 過濾器可以修改下游HTTP請求和HTTP相應(增加/修改頭部、請求參數、改寫請求路徑)
* 通過API或配置驅動
* 支持Spring Cloud DiscoveryClient配置路由,與服務發現與注冊配合使用
*****
## 網關服務
網關服務提供路由配置、路由斷言和過濾器。網關服務可以與注冊中心配合使用,在安全方面,可以在網關處加上限流、熔斷等功能,依賴文件如下:
```
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 限流 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<!-- 熔斷 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
```
### 路由配置
路由配置支持Router配置類和在application.yml中配置倆種。
#### 1.Router配置類
代碼如下:
```
@Configuration
public class Router {
@Autowired
private AuthFilter authFilter;
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("openid-service", r -> {
return r.path("/openid-service/**")
.filters(f -> {
f.stripPrefix(1);
return f;
})
.uri("lb://openid-service");
})
.route("system", r -> {
return r.path("/system/**")
.filters(f -> {
f.filters(authFilter);
f.stripPrefix(1);
return f;
})
.uri("lb://szyd-system");
})
.build();
}
}
```
#### 2.application.yml中配置
```
spring:
application:
name: citp-gateway
cloud:
gateway:
discovery:
locator:
enabled: false
routes: # 路由過濾
- id: route-id # 唯一標志,自定義
# lb 指向eureka中的服務名
uri: lb://service-name
# 路由配置
predicates:
#路徑匹配
- Path=/service-name/**
filters:
- StripPrefix=1
```
### 限流機制
所謂限流,可以認為是服務降級的一種。限流就是限制系統的輸入和輸出流量,以達到保護系統的目的。為了保證系統穩定運行,一旦達到設定的閾值,就需要限制流量并采取措施完成限制流量的目的。
采用內置的限流過濾器配置實現,基于漏桶算法實現。
引入以下依賴代碼
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
```
限流的配置存放在redis緩存中,還需引入redis的starter。
路由的配置代碼修改為:
```
cloud:
gateway:
discovery:
locator:
enabled: false
routes: # 路由過濾
- id: route-id # 唯一標志,自定義
# lb 指向eureka中的服務名
uri: lb://service-name
# 路由配置
predicates:
#路徑匹配
- Path=/service-name/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
# 使用SpEL按名稱引用令牌bean
key-resolver: '#{@ipKeyResolver}'
# 允許用戶每秒處理多少個請求
redis-rate-limit.replenishRate: 1
# 令牌桶的容量,允許在一秒鐘內完成的最大請求數
redis-rate-limit.burstCapacity: 2
```
key-resolver對應自定義限流,實現keyResolver接口即可。
```
/**
* ip令牌
* @return
*/
@Bean("ipKeyResolver")
public KeyResolver ipKeyResolver(){
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostString());
}
```
### 熔斷降級
在gateway中加入Hystrix的應用,實現熔斷降級的作用。
1.加入以下依賴
```
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
```
2.路由配置修改為
```
spring:
cloud:
gateway:
default-filters: # 默認配置
- name: Hystrix
args:
name: default #Hystrixcommand name
fallbackUri: forward:/defaultfallback
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD # THREAD SEMAPHORE
thread:
timeoutInMilliseconds: 10000
# timeout:
# enabled: true #是否執行超時,默認true
circuitBreaker:
requestVolumeThreshold: 200 #窗口采樣大小20
sleepWindowInMilliseconds: 5000 #短路后休眠時間毫秒
errorThresholdPercentage: 50 #判斷出錯百分比50
```