编辑
2023-12-25
实用工具
00
请注意,本文编写于 465 天前,最后修改于 465 天前,其中某些信息可能已经过时。

目录

简介
使用场景
工作原理
过滤器
转发路由
处理响应
项目使用
依赖
yml配置
自定义过滤器
启动类

简介

Zuul 是 Netflix 提供的一个基于 JVM 的网关服务,其主要作用是将所有请求转发到相应的后端服务。Zuul 主要有以下几个特点:

  • 路由和过滤:Zuul 可以通过定义一些路由规则,让请求转发到不同的后端服务,并且可以在路由前和路由后进行一些过滤操作。
  • 负载均衡:Zuul 内置了 Ribbon 负载均衡机制,可以自动地将请求分发到不同的服务器上,实现负载均衡的功能。
  • 可插拔性:Zuul 采用了过滤器链的机制,可以在处理请求的不同阶段中插入不同的过滤器,实现不同的功能。

在Zuul的组件中,主要由以下几个部分组成:

  1. 核心模块:包含了Zuul的核心代码,负责接收和处理外部请求,并进行路由、过滤等操作。其中,核心模块还包含了Zuul的主要配置类和启动类,用于对整个系统进行配置和启动。

  2. 路由模块:负责请求的路由功能,可以根据不同的路径或请求头信息对请求进行分发,并将请求发送到后端对应的服务实例中。

  3. 过滤器模块:提供了基于拦截器的过滤功能,可以对请求进行鉴权、限流、重试等操作,并对响应进行处理和转换。

  4. 发现模块:用于注册和发现后端服务实例,可以通过各种服务发现机制(如Eureka、Consul等)实现服务的自动发现和负载均衡。

  5. 监控模块:提供了一系列的监控指标和报告,可以帮助用户对系统进行实时监控和分析,以便及时发现和排查问题。

使用场景

  • 负载均衡:Zuul 可以将请求分发到不同的后端服务上,实现负载均衡的功能。
  • 路由转发:Zuul 可以根据请求的 URL,将请求转发到不同的后端服务上,实现路由转发的功能。
  • 鉴权和安全:Zuul 可以对请求进行鉴权和认证,保障系统的安全性。
  • 限流和熔断:Zuul 可以在高并发的情况下,通过限流和熔断机制,保障后端服务的可用性。

工作原理

简单讲,就是浏览器向网关发出请求,网关对请求进行过滤、路由转发、返回结果,从eureka Service中找到请求信息中的客户端,先客户端发送请求信息获取结果

Zuul 网关主要由以下几个组件构成:

  1. Filter:过滤器,可以在请求被路由前或者之后添加一些处理逻辑。
  2. Route:路由,将请求路由到不同的后端服务上。
  3. Ribbon:负载均衡器,Zuul 默认使用 Ribbon 进行负载均衡。
  4. Hystrix:容错处理器,可以实现限流和熔断机制。

Zuul 的过滤器链是整个网关的核心部分,它由多个过滤器构成,每个过滤器都负责不同的处理逻辑,比如请求的鉴权、转发等操作。过滤器链在处理请求的过程中,会依次执行这些过滤器,从而实现对请求的全生命周期管理

过滤器

过滤器是 Zuul 中最重要的组件之一,它可以拦截和修改请求和响应的内容,实现各种功能。在 Spring Cloud 中,所有的过滤器都必须继承抽象类 ZuulFilter,并实现其中的四个方法:

  • filterType() 方法:返回过滤器类型,包括 pre、post、route 和 error 四种类型。
  • filterOrder() 方法:返回过滤器执行的顺序,值越小越先执行。
  • shouldFilter() 方法:判断过滤器是否需要执行,默认返回 true,表示全部需要执行。
  • run() 方法:过滤器的主要业务逻辑,实现具体的过滤逻辑。
java
public class MyFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { // 过滤器的业务逻辑 return null; } }

转发路由

在 Zuul 中,我们可以通过配置 ZuulProperties 和 RouteLocator 实现路由转发的功能。其中 ZuulProperties 主要用于配置 Zuul 服务的一些相关属性,比如缓存时间、URL 的前缀和后缀等;而 RouteLocator 则用于定义多个路由规则,将请求映射到不同的后端服务上。 具体的路由转发逻辑如下图所示:

java
客户端请求 --> Zuul网关 --> ZuulFilter1 --> 路由规则1 --> 服务1 | --> ZuulFilter2 --> 服务2 | --> ZuulFilter3 --> 路由规则2 --> 服务3 | --> ZuulFilter4 --> 服务4

当请求进入 Zuul 网关之后,首先会经过一系列过滤器的处理,然后根据路由规则将请求转发到对应的后端服务上,最终返回响应结果。在转发请求时,Zuul 可以自动地根据负载均衡策略选择相应的服务器,实现负载均衡的功能。

处理响应

在 Zuul 中,如果后端服务响应异常或者错误,那么 Zuul 会将这个异常封装成一个 ZuulException 对象,并交给其它的过滤器进行处理。当所有过滤器执行完毕之后,Zuul 会根据 ZuulException 中的状态码和错误消息,返回相应的响应结果。

项目使用

依赖

xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>

yml配置

简单配置

yml
eureka: client: serviceUrl: defaultZone: http://127.0.0.1:8081/eureka/ server: port: 8009 spring: application: name: service-zuul zuul: routes: api-a: path: /api-a/** serviceId: service-provider_a api-b: path: /api-b/** serviceId: service-provider_b

将api-a请求开头的转发到a服务,将api-b请求开头的转发到b服务

详细配置

yml
eureka: client: serviceUrl: defaultZone: http://127.0.0.1:8081/eureka/ server: port: 8009 spring: application: name: service-zuul zuul: routes: #api-a: #path: /api-a/** #serviceId: service-provider_a #api-b: #path: /api-b/** #serviceId: service-provider_b #第二种配置样式 service-provider_a: /api-a/** service-provider_b: /api-b/** sensitive-headers: #加密http头部信息 ribbon: ReadTimeout: 30000 #表示Ribbon客户端在等待服务器响应时的最大等待时间,单位为毫秒。在这个例子中,最大等待时间为30000毫秒(即30秒) ConnectTimeout: 30000 #表示Ribbon客户端在建立连接时的最大等待时间,单位为毫秒。在这个例子中,最大等待时间为30000毫秒(即30秒) hystrix: command: default: #表示使用默认的Hystrix命令配置。 execution: #表示配置命令的执行部分 isolation: #表示配置命令的隔离策略 thread: #表示使用线程隔离策略 timeoutInMilliseconds: 1200000 #表示线程隔离策略的超时时间,单位为毫秒。在这个例子中,超时时间为1200000毫秒(即2分钟)

Ribbon和Hystrix在微服务架构中起着不同的作用。

首先,Ribbon主要用于实现客户端负载均衡。它在通过Eureka服务治理组件注册的服务实例中进行选择,基于某种策略(如轮询、随机等)从一个服务的多台机器中挑选一台来发起请求。

而Hystrix则是容错管理组件,它实现了断路器模式,为延迟和故障提供了保护机制。当依赖的服务出现延迟或故障时,Hystrix可以自动切换到备用服务,避免系统崩溃,并能提供降级方案。

至于两者的超时时间配置,如果同时使用了Ribbon和Hystrix,那么Hystrix的超时时间会等于Ribbon的重试次数(包含首次)乘以(ribbon.ReadTimeout + ribbon.ConnectTimeout)。这里的重试次数是Ribbon对失败请求进行重新发送的次数。

自定义过滤器

根据需要可以自定义过滤器,比如来记录日志信息等等

java
@Component public class MyFilter extends ZuulFilter { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Value("${isEnable}") private boolean isEnable; /** * 类型包含 pre post route error * pre 代表在路由代理之前执行 * route 代表代理的时候执行 * error 代表出现错的时候执行 * post 代表在route 或者是 error 执行完成后执行 * @return */ @Override public String filterType() { return FilterConstants.PRE_TYPE; } /** * filter 为链式过滤器,多个filter按顺序执行 * javaee中根据filter先后配置顺序决定 * zuul 根据order决定, 由小到大 * @return */ @Override public int filterOrder() { return 1; } /** * 是否启用该过滤器 * @return */ @Override public boolean shouldFilter() { return isEnable; } @Override public Object run() { //业务逻辑 } }

启动类

需要加上注解

java
@EnableZuulProxy @EnableEurekaClient

Zuul 的过滤器链是整个网关的核心部分,通过添加不同的过滤器,可以实现不同的功能,比如鉴权、转发、限流等。同时,通过合理地配置路由规则,可以将请求快速地转发到相应的后端服务中,实现负载均衡和服务治理的功能。

本文作者:Weee

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!