什么是 Zuul?
- 服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供 REST API 的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。
- Spring Cloud Netflix 中的 Zuul 就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。
为什么需要 Zuul?
- 客户端会多次请求不同的微服务,增加了客户端的复杂性。
- 存在跨域请求,在一定场景下处理相对复杂。
- 认证复杂,每个服务都需要独立认证。
- 难以重构,随着项目的迭代,可能需要重新划分微服务。
- 某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问会有一定困难。
- 易于监控。可在微服务网关收集监控数据并将其推送到外部系统进行分析。
- 易于认证。可在微服务网关上进行认证。然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
- 减少了客户端与各个微服务之间的交互次数。
- Zuul 提供了不同类型的 filter 用于处理请求,这些 filter 可以让我们实现以下功能:
- 权限控制和安全性:可以识别认证需要的信息和拒绝不满足条件的请求
- 监控:监控请求信息
- 动态路由:根据需要动态地路由请求到后台的不同集群
- 压力测试
- 负载均衡
- 静态资源处理:直接在 zuul 处理静态资源的响应而不需要转发这些请求到内部集群中
Zuul 的执行过程
- Zuul 内部的处理使用 ZuulServlet 完成,ZuulServlet 继承 HttpServlet,重写了 service 方法,service 方法内部分别是 pre、route、post 和 error 类型的 filter 进行调用。
- filter 的执行顺序:先执行 pre 类型的 filter;如果 pre filter 执行失败那么执行 error 和 post 类型的 filter,pre filter 执行成功的话执行 route 类型的 filter;如果 route filter 执行失败那么执行 error 和 post 类型的 filter,route filter 执行成功的话执行 post filter;如果 post filter 执行失败那么执行 error 类型的 filter,post filter 执行成功的话,结束。上述过程中执行失败指的是 ZuulException 被 catch,如果是其他 Exception 的话,那么执行 error 类型的 filter,然后结束。
- 要在 SpringCloud 中使用 Zuul,需要加上
@EnableZuulProxy
注解。加上这个注解之后 SpringCloud 会构造一些 bean,比如 ZuulHandlerMapping、DiscoveryClientRouteLocator、各种 filter 等。其中DiscoveryClientRouteLocato
r 是一个基于服务发现的路由规则生成器,它会基于 zuul 的配置构造路由规则。ZuulHandlerMapping
是一个 HandlerMapping 的实现,它跟基于路由规则注册 handler,其中 key 为路由规则对应的路径,handler 都是 ZuulController,ZuulController 内部使用 ZuulServlet 进行请求的处理。
- Zuul 把真正的服务调用放在了 filter 中实现。它提供了
SimpleHostRoutingFilter
和RibbonRoutingFilter
这 2 个 route 类型的 filter 用于执行服务。从名字也可以看出来,SimpleHostRoutingFilter 用于执行基于 host 方式的调用 url 接口,RibbonRoutingFilter 基于服务发现的方式调用服务。一般我们都建议使用 RibbonRoutingFilter,因为它内部使用 ribbon,更加健壮。
参考资料
SpringCloud 网关服务 zuul 介绍
服务网关 zuul 之一:入门介绍