首先,网关能为我们做什么?
它能为我们做路由转发,黑、白名单、过滤请求等等等等
网关的本质,其实就是一系列的过滤器,记得我们最开始学习过滤器的时候,servlet的doFilter,有没有小伙伴的DNA动了,哈哈
我们今天要说的就是利用网关的本质,过滤器,来做灰度发布
说之前,先讲讲什么是灰度发布,经常听到这个名词,就是不知道是干嘛的
今天,必须得给他整的明明白白的
灰度发布,也叫金丝雀发布,说的就是能够平滑过渡的一种发布版本的一种方式,在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。
有啥好处呢?
它可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
除了灰度发布还有那种发布方式呢?
蓝绿发布、滚动发布等等
简单说说蓝绿发布的原理:
需要另外在开启三台服务器(承载新的服务)
滚动发布:
就是将新服务替代其中一个服务,被代替的空闲出来继续装载另一个新服务,一个一个替换
灰度发布:
启动相同的服务设置配置文件的版本,例如:启动3个相同服务,一个版本是V2,剩下两个是V1(版本可以利用Eureka注册中心的API来动态修改)
eureka:
instance:
metadata-map:
#自定义属性 版本V1、V2
version: v2
一切准备就绪,回到Zuul网关,Zuul网关的过滤器,分那么几种类型,pre、route、post、error
执行顺序是:pre —> route —> post
想要自定义网关过滤器,继承ZuulFilter,实现其的方法
使用@Component注解,交由Spring容器管理
实现方法是有4个方法,fileType、filterOrder、shouldFilter、run
- fileType方法,指定这个过滤器是什么类型的,pre、route、post、error
- filterOrder方法,决定执行顺序,数越小,越先执行
- shouldFilter方法,决定这个过滤器是否执行,true执行,false不执行
- run方法,过滤器的执行逻辑
自定义网关过滤器,类似这种灰度发布,就尽量使用pre类型的过滤器
在发起请求,请求头携带userId(根据用户ID来区分是否是来访问新的的服务)
@Override
public Object run() throws ZuulException {
//获取请求上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//获取到HttpServletRequest
HttpServletRequest request = currentContext.getRequest();
//获取请求头携带的userId
Integer userId = Integer.parseInt(request.getHeader("userId"));
//查询本地缓存/DB/Redis,来确定这个用户是否需要访问新服务,还是继续访问旧服务
if (userId >= 5000) {
//伪代码,假设这个用户是ID属于比5000要大,就让他访问/体验新服务
RibbonFilterContextHolder.getCurrentContext().add("version", "v2");
} else {
//否则,继续让用户体验旧的服务
//因为V1我们启动了两个所以负载均衡也可以继续使用
RibbonFilterContextHolder.getCurrentContext().add("version", "v1");
}
return null;
}
这里用到了RibbonFilter相关的依赖,也给大家准备好了
<dependency>
<groupId>io.jmnarloch</groupId>
<artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId>
<version>2.1.0</version>
</dependency>
还有一点要注意的是,网关在过滤请求的时候,有可能会使你请求头数据丢失,没错,确实是网关给你吃了
它不是过意的哈,它是想保证安全,一些比较特别的key,他就会给你抹掉,如Authorization、Cookie等
//网关配置好这个,什么都不用填,就可以不让网管把携带的请求头参数抹掉
zuul:
sensitive-header:
嘿嘿,大家喜欢的可以关注我的微信公众号哦,听说现在关注的,以后都是尊贵的老粉了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。