GateWay和Zuul区别
1.Zuul1.x是一个基于z阻塞 I/o 模型的API网管
2.Zuul1.x是基于Servlet2.5使用阻塞架构它不支持然和长连接(如:WebSocket)Zuul的设计模式和Nginx比较像,每次 I/o都是从工作线程中选择一个来工作,请求线程被阻塞到工作线程完成,但是差别是Nginx是c++实现的,Zuul用Java实现,而JVM本身有一次加载比较慢的情况,是的Zuul性能你相对比较差。
3.Zuul2.x理念比较先进,想基于Netty非阻塞和支持长连接,但是SpringCloud目前貌似目前还没有整和。Zuul2.x相比Zuul1.x有比较大的性能提升。根据官方提供的基准测试,SpringCloud GateWay的RPS(每秒请求数)是Zuul1.x的1.6倍。
4.SpringCloud GateWay建立在SpringFrameWork5.0、Project Reactor和SpringBoot2之上,使用非阻塞API
5.SpringCloud GateWay还支持WebSocket,并且与Spring精密结合拥有更好的开发体验
6.处理模型:
6.1 SpringCloud集成的Zuul版本采用Tomcat容器,使用传统的Servlet IO处理模型
上述模式的缺点:
Servlet是简单的网络IO模型,当请求进入Servlet容器是,Servlet容器就会为其绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发,线程数量就会上涨而线程资源代价昂贵(上下文切换、内存消耗大)严重影响请求处理的时间。在简易的场景下,不希望为每个请求都分配一个处线程来处理。所以说在高并发场景这种传统的模式没有优势。所以Zuul1.x是基于Servlet之上的一个阻塞式额处理模型,即实现了处理所有的请求的一个Servlet(DispatcherServlet)并由改Servlet阻塞式处理。所以SpringCloud Zuul无法摆脱Servlet模型的弊端。
6.2 SpringCloud GateWay就SpringWeb Flux非阻塞式框架
传统的Web框架,比如:Strus2,SpringMvc都是基于Servlet API和Servlet容器基础上运行的。但是在Servlet3.1之后有了对异步的支持。而WebFlux是一个典型的非阻塞异步的框架,他的核心是基于Reactor的相关API实现的。相对传统的Web框架来说,它可以运行在Netty和UnderTow以及Servlet3.1的容器上。非阻塞+函数式编程(Spring5必须让你使用Java8)。WebFlux是Spring5.0引入的新的响应式框架,却别于Spring Mcv,它不需要依赖于Servlet API。它是完全的异步非阻塞,并且基于Reactor来实现响应式流规范。
为什么要选择SpringCloud GateWay
一方面,Zuul已经进入维护阶段,而且GateWay是Google团队研发的,是亲儿子产品。
另一方面GateWay是基于Spring Boot 2.x,Spring WebFlux和Project Reactor 构建的异步非阻塞模型上开发的(参考:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/)。虽然Netflix早就发布了最新的Zuul2.x,但是SpringCloud貌似没有要整合的计划,而且Netflix相关的组件都宣布进入维护期。多方面综合考虑GateWay是很理想的网管选择。
GateWay具有以下特征
1.GateWay是基于Spring Boot 2.x,Spring WebFlux和Project Reactor 构建
2.动态路由:能够匹配任何请求属性
3.可以对路由指定Predicate(断言)、Filter(过滤器)
4.集成Hystrix断路器功能
5.集成SpringCloud服务发现功能
6.易于编写的Predicate(断言)和Filter(过滤器)
7.请求限流功能
8.支持路径重写
使用GateWay
Route:路由是网管的基本模块,它由ID,目标URI和一系列的断言和过滤器组成。如果断言为True则匹配该路由
predicate:开发人员可以匹配Http请求中所有的内容(请求头、参数等等)。如果该请求和断言相匹配则路由改规则
filter:使用过滤器可以在请求被路由前或者之后对请求进行修改
1.依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2.配置
2.1 yml配置文件
server:
port: 9527
spring:
application:
name: cloud-gateway-service
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment-8001 # 名称可以随便取,但是要唯一
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,就是说满足改条件才会进行路由转发。 **表示匹配后面的任意字符
- id: payment-8002
uri: http://localhost:8002
predicates:
- Path=/payment/lb/**
eureka:
client:
#是否从EurekaServer中抓取自己的信息,默认为true。单节点无所谓,集群时候必须开启才能结合ribbon使用负载均衡
fetch-registry: true
#表示是否将自己注册到Euerka中
register-with-eureka: true
service-url:
#defaultZone: http://http://eureka7001.com:7001/eureka #单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
2.2 硬编码实现
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r->r.path("/payment/get/**").uri("http://localhost:8001"))
.route(r->r.path("/payment/lb/**").uri("http://localhost:8002"))
.build();
}
}
以上的路由地址都是写死的,不能实现负载均衡。我们实际的项目中一般都是多台机器跑服务,我们这里有引入了Eureka。下面我们通过配置实现多台机器的负载均衡。
GateWay负载均衡的配置:(主要是routes下面的rui的值换成 lb://服务注册到Eureka中的名称,还有就是把cloud.gateway.discovery.locator.enabled设置成true)
server:
port: 9527
spring:
application:
name: cloud-gateway-service
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment-8001 # 名称可以随便取,但是要唯一
# uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://CLOUD-PAYMENT-SERVICE #匹配或提供的服务的路由地址
predicates:
- Path=/payment/get/** # 断言,就是说满足改条件才会进行路由转发。 **表示匹配后面的任意字符
- id: payment-8002
# uri: http://localhost:8002
uri: lb://CLOUD-PAYMENT-SERVICE
predicates:
- Path=/payment/lb/**
eureka:
client:
#是否从EurekaServer中抓取自己的信息,默认为true。单节点无所谓,集群时候必须开启才能结合ribbon使用负载均衡
fetch-registry: true
#表示是否将自己注册到Euerka中
register-with-eureka: true
service-url:
#defaultZone: http://http://eureka7001.com:7001/eureka #单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
我们在访问http://localhost:9527/payment/lb时就能看到是有8001和8002轮询过请求了。
其他
1. 参考代码:https://github.com/TianLuhua/springCloud2020.git
2. Eureka注册中心:cloud-eureka-server7001,cloud-eureka-server7002
3. 服务端:cloud-provider-payment8001和cloud-provider-payment8002
4. 网管:cloud-gateway-gateway9527
5.SpringCloud官方的11种路由参考:https://cloud.spring.io/spring-cloud-gateway/reference/html/#gateway-request-predicates-factories
6.SpringCloud官方的差不多30种过滤器:https://cloud.spring.io/spring-cloud-gateway/reference/html/#gatewayfilter-factories