# 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
```