目录
概况
Git:https://github.com/spring-cloud/spring-cloud-gateway
在Spring Cloud 2.0以上版本中,不再对Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。因些为提升网关的性能,基于WebFlux框架实现了SpringCloud Gateway组件,WebFlux框架底层使用了高性能的Reactor模式Netty通信框架。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
特性
- Filter:过滤器
- Route:路由
- Predicate:断言
Webflux
Webflux模式替换了旧的Servlet线程模型。用少量的线程处理request和response io操作,这些线程称为Loop线程,而业务交给响应式编程框架处理,响应式编程是非常灵活的,用户可以将业务中阻塞的操作提交到响应式框架的work线程中执行,而不阻塞的操作依然可以在Loop线程中进行处理,大大提高了Loop线程的利用率。官方结构图:
Netty是目前业界认可的最高性能的通信框架。而Webflux的Loop线程,正好就是著名的Reactor 模式IO处理模型的Reactor线程。
处理流程
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。
动态路由配置方式
-
基于RUI路由配置
spring:
cloud:
gateway:
routes:
-id: proxy-1
uri: https://proxy-1
predicates:
-Path=/proxy-1
-
基于代码路由配置
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/proxy-1")
.uri("https://proxy-1"))
.build();
}
}
-
和注册中心相结合的路由配置
server:
port: 8088
spring:
cloud:
gateway:
routes:
-id: proxy-1
uri: lb://proxy-1
predicates:
- Path=/proxy-1/**
-id: proxy-2
uri: lb://proxy-2
predicates:
-Path=/proxy-2/**
application:
name: cloud-gateway
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://localhost:8080/eureka/
Predicates匹配规则
Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。
熔断降级配置
spring:
cloud:
gateway:
routes:
- id: proxy-1
uri: lb://proxy-1
predicates:
- Path=/proxy-1/**
filters:
- StripPrefix=1
default-filters:
- name: Hystrix
args:
name: default
fallbackUri: 'forward:/fallback'
分布式限流
Spring Cloud Gateway官方就提供了RequestRateLimiterGatewayFilterFactory这个类,适用在Redis内的通过执行Lua脚本实现了令牌桶的方式。具体实现逻辑在RequestRateLimiterGatewayFilterFactory类中.
- burstCapacity,令牌桶总容量。
- replenishRate,令牌桶每秒填充平均速率。
- key-resolver,用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。
spring:
cloud:
gateway:
routes:
- id: limit_route
uri: http://httpbin.org:80/get
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
filters:
- name: RequestRateLimiter
args:
key-resolver: '#{@userKeyResolver}'
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 3
redis:
host: localhost
port: 6379
database: 0
源码分析
TODO
主流网关对比
| Zuul(1.x) | Gateway | Kong | Nginx |
开源 | 开源 | 开源 | 开源/企业版 | 开源 |
社区 | ||||
协议 | http,https | http,https.websocket | http,https,websocket | http,https |
路由 | path,method,header | before,after,host,path,method,header,cookie,Query... | host,path,method | 正则 |
限流 | 需要开发 | 支持 | 支持 | 支持 |
熔断 | 需要开发 | 支持 | 支持 | 不支持或lua开发 |
重试 | 支持 | 支持 | 支持 | 不支持或lua开发 |
健康检查 | 支持 | 支持 | 支持 | 支持 |
负载均衡 | 轮询,随机,加权轮询,自定义 | 轮询,随机,加权轮询,自定义 | 轮询,哈希 | 轮询,随机,加权轮询 |
权限 | 需要开发 | 需要开发 | 内置 | 不支持或lua开发 |
底层通信 | Servert,IO阻塞 | Netty |
| epoll模型,异步IO |