gateway和zuul的区别
spring-cloud-Gateway
是spring-cloud
的一个子项目。而zuul
则是netflix
公司的项目,只是spring将zuul
集成在spring-cloud中使用而已。
因为zuul2.0
连续跳票和zuul1
的性能表现不是很理想,所以催生了spring团队开发了Gateway
项目。
Zuul:
- 使用的是阻塞式的 API,不支持长连接,比如 websockets。
- 底层是servlet,Zuul处理的是http请求
- 没有提供异步支持,流控等均由hystrix支持。
- 依赖包spring-cloud-starter-netflix-zuul。
Gateway:
- Spring Boot和Spring Webflux提供的Netty底层环境,不能和传统的Servlet容器一起使用,也不能打包成一个WAR包。
- 依赖spring-boot-starter-webflux和/ spring-cloud-starter-gateway
- 提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter限流。
相同点:底层都是servlet,两者都是web网关,处理的http请求
不同点
- 内部实现:
1: gateway对比zuul多依赖了spring-webflux,在spring的支持下,功能更强大,内部实现了限流、负载均衡等,扩展性也更强,但同时也限制了仅适合于Spring Cloud套件。
2: zuul则可以扩展至其他微服务框架中,其内部没有实现限流、负载均衡等。
- 是否支持异步:
1: zuul仅支持同步。
2: gateway支持异步。理论上gateway则更适合于提高系统吞吐量(但不一定能有更好的性能),最终性能还需要通过严密的压测来决定
- 框架设计的角度:
1:gateway具有更好的扩展性,并且其已经发布了2.0.0的RELESE版本,稳定性也是非常好的
- 性能:
1:WebFlux 模块的名称是 spring-webflux,名称中的 Flux 来源于 Reactor 中的类 Flux。Spring webflux 有一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好。使用非阻塞API。 Websockets得到支持,并且由于它与Spring紧密集成,所以将会是一个更好的 开发 体验。Zuul 1.x,是一个基于阻塞io的API Gateway。
2:Zuul已经发布了Zuul 2.x,基于Netty,也是非阻塞的,支持长连接,但Spring Cloud暂时还没有整合计划。
核心概念:
Route(路由):构建网关的基本模块,由ID,目标URI,一系列的短语和过滤器组成,如果断言为true则匹配该路由。
Predicate(断言):输入类型是一个ServerWebExchange,用于匹配HTTP请求中的所有内容,如请求头,请求体
Filter(过滤器):指的是Spring框架中的GatewayFilter实例,使用过滤器,可以在请求被路由前后缀之后对请求进行修改.
工作流程:类似SpringMVC
1: 客户端向Spring Cloud Gateway发出请求,然后在Gateway Handler Mapping中找到与请求匹配的路由,将其发送到Gateway Web Handler。
2: Handler再通过指定的过滤器链将请求发送到我们时间的服务执行业务逻辑,然后返回。
3: Flieter在执行业务逻辑前可以做参数校验、权限校验、流量监控、日志输出、协议转换等,
4: 在执行业务逻辑后可以做响应内容、响应头的修改,日志的输出,流量监控等。
快速入门
1: 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
注意!有个小坑,引入gateway时,需要排除springboot-web包,因为gateway内置用springWebFlux实现,不需要web包,否则会报错
2: 配置路由
通过服务地址简单路由
server:
port: 9527
spring:
application:
name: cloud-gateway-service
cloud:
gateway:
routes:
#路由id,没有固定规则,但要求唯一,建议配合服务名
- id: payment_routh
#匹配后提供服务的路由地址
uri: http://localhost:8001
predicates:
#路径断言,路径匹配就进行路由
- Path=/payment/get/**
面向服务的配置动态路由:
以上配置路由方式虽然实现了网关跳转,但还是存在缺陷:配置时必须知道被调用服务的ip和端口,一个服务存在多实例时每个实例都得配置。而服务的相关信息在注册中心都有,所以可以结合注册中心完成动态配置路
spring:
application:
name: cloud-gateway-service
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能
routes:
#路由id,没有固定规则,但要求唯一,建议配合服务名
- id: payment_routh
#匹配后提供服务的路由地址
uri: lb://cloud-payment-service
predicates:
#路径断言,路径匹配就进行路由
- Path=/payment/get/**
或者通过bean的方式配置(不推荐):
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
RouteLocator routh1 = routes.route("routh1",
r -> r.path("/payment/get/**")
.uri("lb://cloud-payment-service")).build();
return routh1;
}
}
3: 测试
启动网关服务和我们的测试服务
访问:http://localhost:9527/payment/get/1也可以正常访问。