同时也可在网关中提供额外的功能:
- 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
- 熔断:集成 Hystrix 断路器
- 集成 Spring Cloud DiscoveryClient
- Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
- 基于 Filter 链的方式,提供了一些网关的高级功能:
- 动态路由/API 路由管理
- 限流
- 路径重写
- 安全
- 监控/指标
-
总结:网关就是所有项目的一个统一入口:
- 目标是替代 Zuul。
Springcloud中所集成的Zuul版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。如下图所示:
大家知道,servlet由servlet container进行生命周期管理。container启动时构造servlet对象并调用servlet init()进行初始化;container关闭时调用servlet destory()销毁servlet;container运行时接受请求,并为每个请求分配一个线程(一般从线程池中获取空闲线程)然后调用service()。
弊端:servlet是一个简单的网络IO模型,当请求进入servlet container时,servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的,但是一旦并发上升,线程数量就会上涨,而线程资源代价是昂贵的(上线文切换,内存消耗大)严重影响请求的处理时间。在一些简单的业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发的请求,这种业务场景下servlet模型没有优势。
所以Springcloud Zuul 是基于servlet之上的一个阻塞式处理模型,即spring实现了处理所有request请求的一个servlet(DispatcherServlet),并由该servlet阻塞式处理处理。所以Springcloud Zuul无法摆脱servlet模型的弊端。虽然Zuul 2.0开始,使用了Netty,并且已经有了大规模Zuul 2.0集群部署的成熟案例,但是,Springcloud官方已经没有集成改版本的计划了。 - 目标提高性能。
为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的reactor-netty响应式编程组件,此底层使用了Netty通讯框架。。从特征来说,SpringCloud Gateway和Zuul的特征差别不大。SpringCloud Gateway和Zuul最主要的区别,还是在底层的通信框架上。 Webflux模式替换了旧的Servlet线程模型。用少量的线程处理request和response io *** 作,这些线程称为Loop线程,而业务交给响应式编程框架处理,响应式编程是非常灵活的,用户可以将业务中阻塞的 *** 作提交到响应式框架的work线程中执行,而不阻塞的 *** 作依然可以在Loop线程中进行处理,大大提高了Loop线程的利用率。官方结构图: Webflux虽然可以兼容多个底层的通信框架,但是一般情况下,底层使用的还是Netty,毕竟,Netty是目前业界认可的最高性能的通信框架。而Webflux的Loop线程,正好就是著名的Reactor 模式IO处理模型的Reactor线程,如果使用的是高性能的通信框架Netty,这就是Netty的EventLoop线程
网关 = 路由转发 + 过滤器(编写额外功能)
简单说明一下三个术语:
- Filter(过滤器):
- 在Gateway运行过程中Filter负责在代理服务“之前”或“之后”去做一些事情。
- 所有生效的Filter都是GatewayFilter的实例
- Route(路由):
- 接收外界请求,通过网关的路由转发,转发到后端的服务上。
- 一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。
- ID是自定的
-
URI就是一个地址
-
Predicate过滤器
-
Filter过滤器
- 如果断言为真,则路由匹配,目标URI会被访问。
- 注意1:Zuul的路由配置模块类似。
- 注意2:只讨论路由功能的话,它和nginx反向代理服务器很像(外界访问nginx,由nginx做负载均衡,后把请求转发到对应服务器上)。
- Predicate(断言、谓词)
- 简单点理解谓词就是一些附加条件和内容,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
- 断言的输入类型是一个 ServerWebExchange。
- 第一步:客户端向 Spring Cloud Gateway 发出请求。
- 第二步:Gateway中Handler Mapping找到与请求相匹配的路由。
- 第三步:将其发送到 Gateway Web Handler。
- 第四步:Gateway Web Handler 会被Filter进行过滤。
- 第五步:Filter中前半部分代码是处理请求的代码。
- 第六步:处理完成后调用真实被代理的服务,被代理服务响应结果。
- 第七步:结果会被Filter中后半部分代码进行 *** 作。
- 第八步:原路返回:
- *** 作完成后把结果返回给Gateway Web Hanlder,
- 在返回给Gateway Handler Mapping,
- 最终响应给客户端。
- 第一步:Eureka Server:Gateway依赖Eureka,需要从Eureka中获取真实代理项目地址后,在进行访问。
- 第二步:新建普通的Eureka Client项目DemoOne(项目名:demo-one)
- 第三步:新建项目GatewayDemo(项目名:gateway-demo)
- 第四步:新建配置文
server:
port: 9000
spring:
application:
name: gateway-demo
cloud:
gateway:
discovery:
locator:
enabled: true # 开启当前项目服务注册与发现功能
lower-case-service-id: true # 把服务名转换为小写,Eureka中默认都是大写
routes:
- id: demo #自定义唯一标识,只要不重复即可
uri: lb://EUREKA-CLIENT # lb:loadBalance EUREKA-CLIENT 代理项目的名
predicates: Path=/demo/** # 路径规则
filters: StripPrefix=1 # 转发后忽略第一层 - 第五步:访问测试:http://localhost:9000/demo/one
通过结果可以看出,用户虽然访问的GatewayDemo网关项目,但是最后真是访问的是DemoOne项目中/one 控制器
- 方式一:基础URI路由配置方式
如果请求的目标地址,是单个的URI资源路径,配置文件示例如下 - 方式二:基于代码的路由配置方式
转发功能同样可以通过代码来实现,我们可以在启动类 GateWayApplication 中添加方法 customRouteLocator() 来定制转发规则。 - 方式三:和注册中心相结合的路由配置方式
在uri的schema协议部分为自定义的lb:类型,表示从微服务注册中心(如Eureka)订阅服务,并且进行服务的路由。
注册中心相结合的路由配置方式,与单个URI的路由配置,区别其实很小,仅仅在于URI的schema协议不同。单个URI的地址的schema协议,一般为http或者https协议
1)Predicates谓词:当满足条件在进行路由转发。
- 其中Route和Predicate必须同时申明
- 所有的谓词都设置在predicates属性中,
- 当设置多个谓词时取逻辑与条件,
- 且一个谓词只能设置一组条件,如果需要有个多条件,添加多个相同谓词。
- 案例:Path=/demo/** 实际上使用的就是PathRoutePredicateFactory
- 网上有一张图总结了 Spring Cloud 内置的几种 Predicate 的实现:
- 假设 转发uri都设定为http://localhost:9023
2)过滤器规则(Filter)
-
Filter作用:在路由转发到代理服务之前和代理服务返回结果之后额外做的事情。
-
Filter执行了说明谓词条件通过了。
-
Spring Cloud Gateway中Filter分类:
-
内置Filter,都是GatewayFilter实现类
-
自定义GlobalFilter
-
-
GlobalFilter【sxt】:全局过滤器不需要工厂,也不需要配置,直接对所有的路由都生效。
-
自定义FilterFactory【sxt】:可以定义针对于Router的Filter。
- 类名必须叫做XXXGatewayFilterFactory.注入到Spring容器后使用时的名称就叫做XXX。
- 类必须继承AbstractGatewayFilterFactory
- 所有需要传递进来的参数都配置到当前类的内部类Config中
请求超时、异常。请求失败堆积于网关。需要快速失败并返回给客户端。不然系统崩溃。
2 解决方案:熔断降级- Spring Cloud Gateway 可以利用Hystrix实现服务降级等功能。
- 当Gateway进行路由转发时,如果发现下游服务连接超时或产生异常,此时就允许进行服务降级。
- 实现原理:当连接超时时,使用Gateway自己的一个降级接口返回托底数据,保证程序继续运行
- 计数器算法
- 漏桶算法
- 令牌桶算法
现在的请求通过经过gateWay网关时,需要在网关统一配置跨域请求,需求:所有请求通过,有如下配置:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "*"
allowed-headers: "*"
allow-credentials: true
allowed-methods:
- GET
- POST
- DELETE
- PUT
- OPTION
九 具体【网】①:整合Nacos
十 具体【网】②:整合Swagger聚合微服务系统API文档
十一 具体【网】③:整合Sentinel完成流控和降级
十二 参考
SpringCloud gateway (史上最全) - 疯狂创客圈 - 博客园
全网最全讲解 Spring Cloud Gateway,认真看完这一篇就够了!
一篇就看懂:SpringCloud网关 - GateWay详解
SpringCloud Gateway获取body参数(一篇就够了)
Spring Cloud Gateway解决跨域问题【理解跨域】
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)