程序员都应该掌握的微服务网关:ZuulFilter的扩展功能实现

2022-10-28 15:07:51 浏览数 (1)

本节内容给大家介绍的是微服务网关:Zuul Filter扩展功能实现。

Zuul Filter扩展功能实现

在Zuul的工作原理中,我们已经看到Zuul主要采用基于Filter链的工作调用模式,通过自定义Filter机制可以动态扩展网关服务功能。网关的一个重要作用就是提供公共服务组件,而这些组件的功能也大都与Filter的拦截机制有关。下面我们以网关中经常会使用的灰度发布、服务限流为例,来说明如何通过Filter机制结合Ribbon和其他模块来实现。

实现灰度发布

目前常见的发布策略有蓝绿发布和灰度发布(金丝雀发布)。服务发布策略本质上是一种流量切换和流量导流策略。

● 蓝绿发布:在发布的过程中用户对服务的重启无感知,通常情况下通过新旧版本并存的方式实现,也就是说在发布的流程中,新的版本和旧的版本是相互热备的,通过切换路由权重的方式(非0即100)实现不同应用的上线或者下线。

● 灰度发布:在线上运行的服务中加入少量的新版本服务,然后从这少量的新版本服务中快速获得反馈,根据反馈决定服务最后的交付形态。

灰度发布要做的就是修改Ribbon的负载策略,基本的思路是,根据Eureka的Metadata配置设置自定义元数据(服务版本信息)与网关中设置的路由负载策略(Ribbon的Rule规则)进行匹配,选择符合路由条件的后端服务进行导流操作。

具体而言,因为Zuul使用的是基于同步线程的请求处理模式,所以我们可以通过ThreadLocal变量记录当前HTTP请求的特征数据,将特征数据与Ribbon中维护的后端服务实例的元数据进行模式匹配,再根据当前路由设置的负载策略就可以将HTTP请求映射到对应的后端服务实例。下面是主要的实现过程。

在实现灰度发布策略前,需要保证后端服务实例注册在Eureka中,并设定元数据的服务实例的版本信息。

Zuul主要依靠Filter实现HTTP拦截,执行灰度发布过滤功能,其中 ribbonHolder 存 储 的 是 后 端 路 由 ID 对 应 的 路 由 策 略 信 息 。

ribbonHolder在初始化时加载Admin配置的路由策略,篇幅所限,此处省略加载过程。routeribbonholder通过设置的路由策略可以动态执行蓝绿发布策略或者灰度发布策略,代码实现如下:

说 明 # :灰 度 发 布 Filter 中 的 核 心 方 法 就 是 给RibbonFilterContextHolder设置当前线程上下文的后端服务版本信息。RibbonFilterContextHolder主要利用ThreadLocal变量来解决如何将灰度发布的信息传递给本地线程变量,然后当HTTP请求经过灰度发布Filter时,它可以通过Ribbon的元数据路由规则匹配对应的服务ID。下面是RibbonFilterContextHolder的实现代码:

根据Ribbon的路由规则设置,Zuul基于Spring Boot的自动化配置机制,加载spring.factories实现自定义的路由规则配置加载,主要步骤如下。

● 第一步,在 /META-INF/spring.factories下加载自动配置:

● 第二步,实现自动配置类:

然后将元数据与后端服务(Original Server)建立映射匹配规则:

● 第三步,根据元数据匹配后端服务(Original Server)规则:

● 第四步,基于元数据匹配的断言:

说明#:上述代码是元数据匹配的断言逻辑,可以看到它从Filter中设置的线程上下文中获得对应的后端服务版本信息,然后与HTTP请求中后端服务版本信息进行比对,当HTTP请求经过这个Filter时就会根据apply中设计的断言逻辑来选择符合条件的后端server,实现灰度发布功能。

实现服务限流

服务限流是微服务网关对API流量进行保护的一种常用手段,可以防止网络攻击,限制客户端的请求速度,在一定程度上可以保证后端服务不因为流量过载而宕机。后面的容错和隔离相关章节也会进一步说明限流的策略有哪些,下面说明如何通过Zuul Guava RateLimiter实现服务限流功能。RateLimiter是Google开源的实现了令牌桶算法的限流工具。

首先引入 spring-cloud-zuul-ratelimit组件的Maven依赖:

然后自定义实现Filter类:

RateLimiter基于Guava提供的令牌桶算法的实现类,可以依据系统的实际情况来调整生成token的速度。RateLimiter.create(1000)可以理解为:每秒往桶里放入1000个令牌。RATE_LIMITER.tryAcquire方法尝试获取令牌桶里的令牌,如果有令牌表示目前流量未达上限,则返回true,同时总的令牌数减1。如果没有令牌,说明令牌桶已达到阈值,则返回false,并设置HTTP状态码返回的信息。

本文给大家讲解的内容是微服务网关:Zuul Filter扩展功能实现

  1. 下篇文章给大家讲解的内容是微服务网关:Zuul源码解析
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

0 人点赞