程序员都应该掌握的微服务网关:ZuulFilter的扩展功能实现
本节内容给大家介绍的是微服务网关: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扩展功能实现
- 下篇文章给大家讲解的内容是微服务网关:Zuul源码解析
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持!
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。
相关文章
- 架构设计 9-可扩展架构之分层架构
- Kubernetes 中 Descheduler 组件的使用与扩展
- 【说站】php安装grpc扩展的方法
- 微服务架构开发实战:微服务的高级主题一自动扩展的定义及意义
- Linux - 结构化语句及参数扩展
- 【Groovy】Groovy 扩展方法 ( 静态扩展方法配置 | 扩展方法示例 | 编译静态扩展类 | 打包静态扩展类字节码到 jar 包中 | 测试使用 Thread 静态扩展类 )
- 【Groovy】Groovy 扩展方法 ( 实例扩展方法配置 | 扩展方法示例 | 编译实例扩展类 | 打包实例扩展类字节码到 jar 包中 | 测试使用 Thread 实例扩展方法 )
- 常用短代码插件:WPJAM Basic 的短代码扩展
- oracle创建表空间 扩展表空间文件 修改表空间自动增长详解数据库
- 以Yum一步到位安装MySQL扩展(yum安装mysql扩展)
- 系统Linux扩展技术:重新定义系统极限(linux扩展)
- Windows与SQL Server 2012/2018扩展支持服务已延长3年
- Linux虚拟空间:服务无限扩展可能(linux虚拟空间)
- Redis服务扩展包:快速下载(redis扩展下载)
- 实现PHP的Redis扩展安装(php安装redis扩展)
- 增强Redis性能,实现更高效能化(扩展redis能力)
- 灵活运用abs函数,扩展Oracle数据库功能(abs函数 oracle)
- sqlserver数据库危险扩展删除和恢复代码
- 不使用web服务(Service)实现文本框自动完成扩展