文章目录
Gateway 能干什么?
- 反向代理
- 鉴权
- 流量控制
- 熔断
- 日志监控
Gateway 是什么?
Gateway 是在 Spring 生态系统之上构建的API网关服务,于 Spring 5, Spring Boot 2 和 Project Reactor 等技术。Gateway旨在提供一种简单而有效的方式来对 API 进行路由, 以及提供一些强大的过滤器功能,例如: 熔断、限流、重试等。
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,基于 Spring 5.0+ Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul, 在 Spring Cloud 2.0 以上版本中,没有对新版本的 Zuul 2.0 以上最新高性能版本进行集成,仍然还是使用的 Zuul 1.x 非 Reactor 模式的老版本。而为了提升网关的性能,SpringCloud Gateway 是基于 WebFlux 框架实现的,而 WebFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty。Spring Cloud Gateway 的目标是提供统一的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标和限流。
Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。
Gateway 在微服务架构所处的位置
Spring Cloud Gateway 具有如下特性:
- 动态路由:能够匹配任何请求属性
- 可以对路由指定 Predicate(断言)和 Filter(过滤器)
- 集成 Hystrix 的断路器功能
- 集成 Spring Cloud 服务发现功能
- 支持路径重写
Spring Cloud Gateway 与 Zuul 1.x 的区别:
- Zuul 1.x 是基于阻塞 I/O 的 API Gateway
- Zuul 1.x 基于Servlet 2. 5使用阻塞架构,它不支持任何长连接(如WebSocket) Zuul的设计模式和Nginx较像,每次|/ 0操作都是从工作线程中选择一个执行, 请求线程被阻塞到工作线程完成,但是差别是 Nginx 用 C++ 实现,Zuul 用 Java 实现,而 JVM 本身会有第一次加载较慢的情况,使得 Zuul 的性能相对较差。
- Zuul 2.x 理念更先进,想基于 Netty 非阻塞和支持长连接,但 SpringCloud 目前还没有整合。Zuul 2.x 的性能较 Zuul 1.x 有较大提升。在性能方面,根据官方提供的基准测试,Spring Cloud Gateway 的 RPS (每秒请求数) Zuul 的 1.6 倍。
- Spring Cloud Gateway 建立在 Spring Framework,Project Reactor 和 Spring Boot 2 之上,使用非阻塞
- Spring Cloud Gateway还支持WebSocket,瓶与Spring紧密集 成拥有更好的开发体验
Spring Cloud Gateway 的三大核心概念
- Route (路由): 路由是构建网关的基本模块,它由 ID,目标 URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
- Predicate(断言):参考的是 java8 的 java.util.function.Predicate 开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
- Filter(过滤):指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
Spring Cloud Gateway 的工作流程
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。
Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前( “pre” )或之后( “post” )执行业务逻辑。
Filter 在 “pre” 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在 "post” 类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。
核心逻辑是:路由转发 + 执行过滤器链
使用 Spring Cloud Gateway 的步骤(需要新建微服务9527做为网关)
1. 导入 POM 文件
<!--新增gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2. yml 文件
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/** #断言,路径相匹配的进行路由
eureka: # 注册到 Eureka 中
instance:
hostname: cloud-gateway-service
client:
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://localhost:7001/eureka
3. 测试使用网关访问服务
添加网关前:http://localhost:8001/payment/31
添加网关后:http://localhost:9527/payment/31
此时前后两个链接都可以提供服务,即网关 9527 将请求映射到了 8001 微服务上。
需要注意的是 uri 的协议为 lb,表示启用 Gateway 的负载均衡功能。 lb://serviceName 是 spring cloud gateway 在微服务中自动为我们创建的负载均衡uri