Gateway网关
Gateway 网关
1、Gateway 简介
1-1、官网
上一代 zuul 1.X:https://github.com/Netflix/zuul/wiki
当前 gateway:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
1-2、是什么
SpringCloud Gateway 是 SpringCloud 的一个全新项目,基于 Spring5.O+Springboot 2.0 和 ProjectReactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
SpringCloudGateway 作为 SpringCloud 生态系统中的网关,目标是替代 Zuul,在 SpringCloud2.0 以上版本中,没有对新版本的 zuul2.0 以上最新高性能版本进行集成,仍然还是使用的 Zuul 1.x 非 Reactor 模式的老版本。而为了提升网关的性能,SpringCloud Gateway 是基于 WebFlux 框架实现的,而 webFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty。
springCloudGateway 的目标提供统一的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
1-3、能干嘛
- 反向代理
- 鉴权
- 流量控制
- 熔断
- 日志监控
微服务架构中网关在哪里?
1-4、有 Zuul 了怎么又出来了 gateway
neflix 不太靠谱,zuul2.0 一直跳票,迟迟不发布,一方面因为 Zuul1.0 已经进入了维护阶段,而且 Gateway 是 SpringCloud 团队研发的,是亲儿子产品,值得信赖。而且很多功能 Zuul 都没有用起来也非常的简单便捷。Gateway 是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然 Netflix 早就发布了最新的 Zuul 2.x,但 Spring Cloud 貌似没有整合计划。而且 Netflix 相关组件都宣布进入维护期;不知前景如何?多方面综合考虑 Gateway 是很理想的网关选择。
5、Gateway 特征
- 基于 Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建
- 动态路由:能够匹配任何请求属性
- 可以对路由指定 Predicate(断言)和 Filter(过滤器)
- 集成 Hystrix 的断路器功能
- 集成 Spring Cloud 服务发现功能
- 易于编写的 Predicate(断言)和 Filter(过滤器)
- 请求限流功能
- 支持路径重写
1-6、SpringCloudGateway 与 Zuul 的区别:
在 SpringCloudFinchley 正式版之前,SpringCloud 推荐的网关是 Netflix 提供的 Zuul:
- Zuul 1.x 是一个基于阻塞 I/O 的 APIGateway
- Zuul 1.x 基于 ServIet2.5 使用阻塞架构,它不支持任何长连接(如 WebSocket),Zuul 的设计模式和 Nginx 较像,每次 I/O 操作都是从工作线程中选择一个执行,请求线程阻塞到工作线程完成,但是差别是 Nginx 用 C++实现,Zuul 用 Java 实现,而 JVM 本身会有第一次加载较慢的情况,使得 Zuul 的性能相对较差。
- Zuul 2.x 理念更先进想基于 Netty 非阻塞和支持长连接,但 SpringCloud 目前还没有整合。Zuul2.x 的性能较 Zuul1.x 有较大提升。在性能方面,根据官方提供的基准测试,SpringCloudGateway 的 RPS(每秒请求数)是 Zuul 的 1.6 倍。
- SpringCloudGateway 建立在 SpringFramework5、ProjectReactor 和 SpringB00t2.之上,使用非阻塞 API
- SpringCloudGateway 还支持 WebSocket,并且与 Spring 紧密集成拥有更好的开发体验
1-7、Zuul1.x 模型
springcloud 中所集成的 zuul 版本,采用的是 tomcat 容器,使用的是传统的 servlet IO 处理模型。
Servlet 的生命周期?servlet 由 servlet container 进行生命周期管理。
- container 启动时构造 servlet 对象并调用 servlet init()进行初始化,
- container 运行时接受请求,并为每个请求分配一个线程(一般从线程池中获取空闲线程)然后调用 service()
- container 关闭时调用 servlet destory()销毁 servlet
上述模式的缺点
servlete—个简单的网络 IO 模型,当请求进入 servlet container 时,servlet container 就会为其绑定一个线程在并发不高的场景下这种模型是适用的。但是一旦高并发(比如抽风用 jemeter 压),线程数量就会上涨,而线程资源代价是昂贵的(上线文切换,内存消耗大)严重影响请求的处理时间。
在一些简单业务场景下,不希望为每个 request 分配一个线程,只需要 1 个或几个线程就能应对极大并发的请求,这种业务场景下 servlet 模型没有优势。
所以 Zuul 1.x 是基于 servlet 之上的一个阻塞式处理模型,即 spring 实现了处理所有 request 请求的一个 servlet(DispatcherServlet)并由该 servlet 阻塞式处理处理。所以 springcloudzuul 无法摆脱 servlet 模型的弊端。
1-8、GateWay 模型
传统的 Web 框架比如说:struts2,springmvc 等都是基于 Servlet API 与 Servlet 容器基础之上运行的。
但是,在 Servlet3.1 之后有了异步非阻塞的支持。而WebFlux 是一个典型非阻塞异步的框架,它的核心是基于 Reactor 的相关 API 实现的。相对于传统的 web 框架来说,它可以运行在诸如 Netty,Undertow 及支持 Servlet3.1 的容器上。非阻塞式+函数式编程(Spring5 必须让你使用 java8)
SpringWebFlux 是 Spring5.0 引入的新的响应式框架区别于 SpringMVC,它不需要依赖 ServletAPI,它是完全异步非阻塞的,并且基于 Reactor 来实现响应式流规范。
2、Gateway 工作流程
2-1、三大核心概念
(1)Route(路由)
路由是构建网关的基本模块,它由 ID,目标 URI,一系列的断言和过滤器组成,如果断言为 true 则匹配该路由
(2)Predicate(断言)
参考的是 Java8 的 java.util.function.Predicate,开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
(3)Filter(过滤)
指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
web 请求通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。
predicate 就是我们的匹配条件;而 filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标 uri,就可以实现一个具体的路由了。
2-2、Gateway工作流程
官网总结
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。
Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。
Filter 在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。
核心逻辑:路由转发+执行过滤器链
3、入门配置
3-1、Gateway9527 搭建
新建 Module:cloud-gateway-gateway9527
pom.xml
1 |
|
application.yml
1 | server: |
主启动类
1 | package com.jcvv.springcloud; |
3-2、9527 网关如何做路由映射呢?
我们目前不想暴露 8001 端口,希望在 8001 外面套一层 9527
YML 新增网关配置
8001 看 controller 的访问地址,我们目前不想暴露 8001 端口,希望在 8001 外面套一层 9527。这样别人就攻击不了 8001,有网关挡着
1 | server: |
3-3、测试
启动 7001
启动 8001:cloud-provider-payment8001
启动 9527 网关
访问说明:
加入网关前:http://localhost:8001/payment/get/1
加入网关后:http://localhost:9527/payment/get/1
两者访问成功,返回相同结果
3-4、Gateway 配置路由的两种方式
Gateway 网关路由有两种配置方式:
在配置文件 yml 中配置
代码中注入 RouteLocator 的 Bean
自己写一个案例:通过 9527 网关访问到外网的腾讯新闻网址:http://new.qq.com/ch/tech/
添加配置类
当访问地址 http://localhost:9527/ch/tech 时会自动转发到地址:http://new.qq.com/ch/tech/
1 | package com.jcvv.springcloud.config; |
4、通过微服务名实现动态路由
4-1、以前的配置说明
路径写死了
默认情况下 gateway 会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。
4-2、配置动态路由
application.yml
对 yml 进行配置:让其先通过 gateway,再通过 gateway 去注册中心找提供者
1 | server: |
测试
启动:一个 eureka7001 + 两个服务提供者 8001/8002
结果:8001/8002 两个端口切换
5、GateWay 常用的 Predicate
5-1、Route Predicate Factories 是什么?
启动 idea
Spring Cloud Gateway 将路由匹配作为 Spring WebFlux HandlerMapping 基础架构的一部分
Spring Cloud Gateway 包括许多内置的 Route Predicate 工厂,所有这些 Predicate 都与 HTTP 请求的不同属性匹配,多个 Route Predicate 工厂可以进行组合。
Spring Cloud Gateway 创建 Route 对象时,使用 RoutePredicateFactory 创建 Predicate 对象,Predicate 对象可以赋值给 Route。 Spring Cloud Gateway 包含许多内置的 Route Predicate Factories。
所有这些谓词都匹配 HTTP 请求的不同属性。多种谓词工厂可以组合,并通过逻辑 and。
5-2、常用的 Route Predicate
接下来讨论几个 Route Predicate Factory
After Route Predicate
在这个时间之后这个路由才生效
1 | spring: |
这个时间通过以下代码产生
1 | public class T2 { |
测试:访问报错
Before Route Predicate
在这个时间之前这个路由才生效
1 | spring: |
Between Route Predicate
在这个时间之间路由生效
1 | spring: |
Cookie Route Predicate
Cookie Route Predicate 需要两个参数,一个是 Cookie name,一个是正则表达式。
路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由;如果没有匹配上则不执行
1 | spring: |
用 curl 测试,命令行输入
1 | curl http://localhost:9527/payment/get/2 --cookie "username=jcvv" |
Header Route Predicate
两个参数:一个是属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。
1 | spring: |
配置说明:请求头要有 X-Request-Id 属性并且值为整数的正则表达式
1 | curl http://localhost:9527/payment/get/2 -H "X-Request-Id:123" |
Host Route Predicate
1 | spring: |
Host Route Predicate 接收一组参数,一组匹配的域名列表。
它通过参数中的主机地址作为匹配规则
1 | curl http://localhost:9527/payment/get/2 -H "Host: news.another.org" |
Method Route Predicate
1 | spring: |
Path Route Predicate
1 | spring: |
Query Route Predicate
支持传入两个参数,一个是属性名,一个为属性值,属性值可以是正则表达式
1 | spring: |
6、Filter 的使用
6-1、是什么
路由过滤器可用于修改进入的 HTTP 请求和返回的 HTTP 响应,路由过滤器只能指定路由进行使用。Spring Cloud Gateway 内置了多种路由过滤器,他们都由 GatewayFilter 的工厂类来产生。
6-2、Spring Cloud Gateway 的 Filter
生命周期
pre
post
种类
具体看官方文档
- GatewayFilter:有 31 种 Spring Cloud Gateway
- GlobalFilter:有 10 种 Spring Cloud Gateway
常用的 GatewayFilter
AddRequestParameter
1 | spring: |
自定义过滤器
2 个主要接口:GlobalFilter,Ordered
能干嘛?
- 全局日志记录
- 统一网关鉴权
- 。。。。
自定义全局过滤器配置类:
1 |
|
测试
相关链接:Config分布式配置中心