zuul 1.x 源码解析 (结合本人过去2年工作经历整理,超详细)

本文详细解析了ZuulGateway的启动配置项,包括`@EnableZuulProxy`和`@EnableZuulServer`的区别,ZuulServlet的作用与初始化,以及Zuulfilter的初始化过程,特别是动态过滤器的实现和请求处理流程,包括前置、路由、error和后置过滤器的详细介绍。

1 启动配置项

1.1 @EnableZuulProxy

在这里插入图片描述
作为zuul网关,需要配置@EnableZuulProxy注解,这个注解表明,嵌入该注解的类将自动成为 Zuul 服务器的入口。当然这个注解还有着其他的非常强大的功能,我们可以基于此注解来使用 Zuul 中的各种内置过滤器实现复杂的服务路由。此注解,由
@Import({ZuulProxyMarkerConfiguration.class})修饰。

1.2 @Import({ZuulProxyMarkerConfiguration.class})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以发现,ZuulProxyAutoConfiguration
是通过ZuulProxyMarkerConfiguration 中 Marker 类是否存在,当做是否进行自动装配的开关。

1.3 ZuulProxyAutoConfiguration

ZuulProxyAutoConfiguration生效原理:
SpringBoot自动装配,启动的时候要加载大量的spring.factories文件,并扫描获得EnableAutoConfiguration的值,其中就包含ZuulServerAutoConfiguration
以及ZuulProxyAutoConfiguration。ZuulProxyAutoConfiguration继承自ZuulServerAutoConfiguration。这两个配置都有共同点,使用@ConditionalOnBean({Marker.class})注解修饰。前者ZuulProxyMarkerConfiguration.Marker的创建来源于@EnableZuulProxy注解, 后者ZuulServerMarkerConfiguration.Marker的创建来源于@EnableZuulServer注解。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3.1(延伸)@EnableZuulServer、@EnableZuulProxy两个注解的区别

@EnableZuulServer - 普通Zuul Server,只支持基本的route与filter功能.
@EnableZuulProxy - 普通Zuul Server+服务发现与熔断等功能的增强版,具有反向代理功能.
@EnableZuulProxy简单理解为@EnableZuulServer的增强版,当Zuul与Eureka、Ribbon等组件配合使用时,我们使用@EnableZuulProxy。

2 ZuulServlet创建

2.1 ZuulServlet作用

1.ZuulServlet - 处理请求(调度不同阶段的filters,处理异常等)

ZuulServlet类似SpringMvc的DispatcherServlet,所有的Request都要经过ZuulServlet的处理。三个核心的方法preRoute(),route(), postRoute(),zuul对request处理逻辑都在这三个方法里。

2.作为激活ZuulServerAutoConfiguration创建的前提条件
在这里插入图片描述
3.作为ZuulController创建的前提条件
在这里插入图片描述
在这里插入图片描述

2.2 ZuulServlet初始化

在项目启动阶段,会完成ZuulServlet的初始化,并调用init方法,此方法中,包含了对ZuulRunner的初始化。zuul对request处理会交给ZuulRunner去执行。由于ZuulServlet是单例,因此ZuulRunner也仅有一个实例。

在这里插入图片描述

3.Zuul filter的初始化

3.1:filterRegistry的初始化

在ZuulServerAutoConfiguration配置类内部,包含了
ZuulFilter的配置项,该配置项,内部注入了map类型的filters,
业务自己定义的filter只要交给spring托管, 就可以加载进来,并成为map容器的元素,key为ZuulFilter的bean的名字,值为对应的ZuulFilter。该配置项,在内部定义了ZuulFilterInitializer这个bean,在启动的时候,会完成FilterRegistry、FilterLoader以及ZuulFilterInitializer的初始化。

在这里插入图片描述

3.2:Zuul filter初始化到内存

在ZuulFilterInitializer类的内部,有@PostConstruct注解修饰的contextInitialized方法,该方法会在上述private Map<String, ZuulFilter> filters 依赖注入完成后调用。方法内部,遍历了所有的ZuulFilter,并将其放在了单例FilterRegistry内部维护的
ConcurrentHashMap容器中。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.2.1(延伸)Zuul组件实现动态过滤

上述Zuul filter初始化到内存的方式,是常规的初始化方式,Zuul设计的初衷是ZuulFilter是存放在Groovy文件中,可以实现基于最后修改时间进行热加载。即可以让服务在不停机的情况下,对过滤的条件进行变更。即动态过滤功能。
。使用示例如下:
1.将过滤器的java文件,放置到指定的一个文件夹:(C:\Users\Lenovo\Desktop\custom-zuul-filter)
2.由于动态路由是基于文件扫描的机制,所以需要手动去启用。如下是基于服务启动后去做的这个事情。

在这里插入图片描述
3.若要更新文件内容,可以直接对指定文件进行修改,然后丢回到指定目录(C:\Users\Lenovo\Desktop\custom-zuul-filter)即可。添加过滤器也是采用类似的方式。

3.2.2 Zuul组件实现动态过滤原理概述

1.总的来说是通过通过FilterFileManager来对过滤器进行扫描以及加载,如下是FilterFileManager的结构,在调用init方法时,会调用manageFiles方法。

<

<think>嗯,用户现在想了解Zuul 1.x版本中线程池隔离的实现方式、配置方法以及原理。首先,我需要回忆一下Zuul 1.x的相关知识。记得Zuul是Netflix的网关服务,负责路由、监控、安全等。在微服务架构中,它作为前置网关处理所有请求。 用户提到的线程池隔离,可能和Hystrix有关,因为Zuul默认集成了Hystrix来实现容错和隔离。Hystrix有两种隔离策略:线程池和信号量。默认情况下,Zuul使用的是信号量隔离,但用户可能想了解如何配置成线程池隔离。 根据引用[2],Zuul默认使用信号量隔离,而Hystrix默认是线程池。所以用户的问题可能涉及到如何将Zuul的隔离策略从信号量改为线程池。需要查看配置属性,比如zuul.ribbon-isolation.strategy,默认是semaphore,改为thread的话应该就能启用线程池隔离。 另外,线程池隔离的原理是通过为每个依赖服务分配独立的线程池,避免一个服务的延迟影响到其他服务。Zuul在处理路由转发时,会使用Hystrix的Command模式,将请求封装成HystrixCommand,这样就能利用线程池来隔离不同的请求。 配置方面,需要设置zuul.ribbon-isolation.strategy=thread,同时调整线程池的大小,比如hystrix.threadpool.default.coreSize和maxQueueSize。这些参数控制线程池的核心线程数和队列容量,防止资源耗尽。 还要注意,线程池隔离会增加上下文切换的开销,可能影响性能,所以需要根据实际场景权衡。信号量隔离更适合内部调用,而线程池适合外部依赖,防止雪崩效应。 用户可能还关心如何验证配置是否生效,或者如何监控线程池的状态。这部分可能需要结合Hystrix Dashboard或Turbine进行监控,但用户的问题主要集中在配置和原理,所以可能需要简要提及。 总结一下,回答应该包括线程池隔离的原理、配置方法(属性设置)、与信号量隔离的区别,以及注意事项。同时,需要引用相关的引用内容,比如引用[2]中提到Zuul默认使用信号量,而Hystrix默认是线程池,说明需要显式配置才能切换。</think>### Zuul 1.x 线程池隔离的实现与配置 #### 一、线程池隔离的实现原理 Zuul 1.x 默认集成 Hystrix 实现服务容错和隔离,其隔离策略支持两种模式:**信号量(Semaphore)**和**线程池(Thread Pool)**。 - **线程池隔离**通过为每个服务依赖分配独立的线程池,避免因某个服务延迟导致线程资源耗尽,从而保障系统稳定性[^2]。 - **Hystrix Command**:Zuul 的路由转发逻辑会被 Hystrix 封装为 `HystrixCommand`,通过线程池执行请求,实现资源隔离[^3]。 #### 二、配置线程池隔离的步骤 1. **启用线程池隔离策略** 在配置文件中设置隔离策略为 `thread`: ```properties zuul.ribbon-isolation-strategy=thread ``` 2. **配置线程池参数** 调整 Hystrix 线程池的核心参数: ```properties # 线程池核心线程数 hystrix.threadpool.default.coreSize=20 # 最大队列容量(默认-1使用SynchronousQueue,建议设为有限值) hystrix.threadpool.default.maxQueueSize=100 # 队列拒绝阈值(当maxQueueSize > 0时生效) hystrix.threadpool.default.queueSizeRejectionThreshold=50 ``` 3. **超时时间配置** 设置 Hystrix 超时时间(需大于Ribbon超时): ```properties hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000 ``` #### 三、线程池隔离 vs 信号量隔离 | **特性** | **线程池隔离** | **信号量隔离** | |----------------|-------------------------------|-------------------------| | 资源消耗 | 高(需维护线程池) | 低(基于计数器) | | 适用场景 | 外部服务调用(如HTTP请求) | 内部高速调用(如内存操作) | | 阻塞影响 | 线程池满则拒绝请求 | 计数器满则直接拒绝 | | 配置复杂度 | 需调整线程池参数 | 仅需设置信号量大小 | #### 四、注意事项 1. **性能权衡**:线程池隔离会增加上下文切换开销,需根据业务负载调整核心线程数[^2]。 2. **队列管理**:避免无界队列导致内存溢出,建议设置 `maxQueueSize` 并监控队列堆积。 3. **与信号量对比**:若网关主要处理轻量级转发,信号量隔离(默认)可能更高效[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值