有没有在北京面试java的小伙伴,每家公司面试问的问题都不一样,昨天面试官问到了
灰度发布
,一脸懵,好像在哪儿听说过,毕竟我都没发布过,之前都是项目组长在干这些事儿,所以聊聊,了解一下
todo这都是为了面试准备的,流程逻辑是对的,但自己还没尝试过,等有时间回来自己实现一下
什么是灰度发布
-
全量发布:把旧服务kill掉,把新服务启动,这个过程就可以理解为全量发布
-
回滚周期长
如果我们更新完应用之后,我们做线上回归测试的时候发现有BUG,这个时候就要做回滚,过程就是把新服务kill掉,再把旧服务启动,这个过程的整个服务是挂掉的,不会提供服务的,那么在这段时间服务就是不可用的,就会导致
一部分的用户群体流失
,这个问题是非常严重的 -
一些BUG可能会导致服务集群雪崩
在实际生产中部署了不止一台机器,因为要做高可用,可能部署了两台以上的机器,假设代码中有一个内存泄漏的代码,内存泄漏可能刚刚部署看不到这个问题,在经过了几天或者一周之后,会导致我们整个新版本的服务集群全线宕机,这个问题也是非常严重的。
我们在新版本上面去做回滚的时候会比我们BUG回归的回滚时间更长, 总的导致一个问题就是我们的服务可用性差了。
我们在一些互联网公司,服务可用性要做到
99.999%
。 -
-
灰度发布
-
降低发布影响面
集群里拿出一台机器部署一个新版本,然后放一部分内测流量(用户)进来,如果在这个新的版本发现了问题之后,就可以直接把那一小部分流量直接转到我们的旧版上面,它的影响面也仅在那一部分小的群体
-
可以做到不停机迁移
从集群中拿一台机器更新到新版再放流量进来,这是不会影响集群中的其他服务的
-
回滚速度快
-
灰度发布, 也叫金丝雀发布。是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。
灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度,而我们平常所说的金丝雀部署也就是灰度发布的一种方式。
具体到服务器上,实际操作中还可以做更多控制,譬如说,给最初更新的10台服务器设置较低的权重、控制发送给这10台服务器的请求数,然后逐渐提高权重、增加请求数。一种平滑过渡的思路, 这个控制叫做“流量切分”
。
核心组件说明
- 注册中心: Nacos
- 网关: SpringCloudGateway
- 负载均衡器: Ribbon (使用SpringCloudLoadBalancer实现也是类似的)
- 服务间RPC调用: OpenFeign
灰度发布代码实现
要实现Spring Cloud项目灰度发布技术方案有很多,重点在于服务发现,怎么将灰度流量只请求到灰度服务,这里我们会使用Nacos作为注册中心和配置中心,核心就是利用Nacos的Metadata设置一个version值,在调用下游服务是通过version值来区分要调用那个版本,这里会省略一些流程,文章末尾提供了源码地址需要自提。
在请求进入网关时开始对是否要请求灰度版本进行判断,通过Spring Cloud Gateway的过滤器实现,在调用下游服务时重写一个Ribbon的负载均衡器实现调用时对灰度状态进行判断。
kerwin:
tool:
gray:
gateway:
## 是否开启灰度发布功能
enabled: true
## 自定义灰度版本请求头
grayHeadKey: gray
## 自定义灰度版本请求头匹配值
grayHeadValue: gray-996
## 使用灰度版本IP数组
grayIPList:
- '127.0.0.1'
## 使用灰度版本城市数组
grayCityList:
- 本地
配置Nacos全局配置文件(common-config.yaml)
所有服务都会使用到这个配置
kerwin:
tool:
gray:
## 配置是否加载灰度自动配置类,如果不配置那么默认不加载
load: true
## 配置生产版本和灰度版本号
version:
prodVersion: V1
grayVersion: V2
## 配置Ribbon调用user-app和order-app服务时使用我们自定义灰度轮询算法
user-app:
ribbon:
NFLoadBalancerRuleClassName: com.kerwin.gray.loadbalancer.GrayRoundRobinRule
order-app:
ribbon:
NFLoadBalancerRuleClassName: com.kerwin.gray.loadbalancer.GrayRoundRobinRule
md看了半天,知识点有点多,有些复杂了,不是我这个水平能够掌握的
总结一下得了,别面试问的时候一句话说不出来就行
在请求进入网关时开始对是否要请求灰度版本进行判断,通过Spring Cloud Gateway的过滤器实现,在调用下游服务时重写一个Ribbon的负载均衡器实现调用时对灰度状态进行判断。
-
配置文件中的自定义属性
- 是否开启灰度发布功能
- 灰度发布的版本(几种匹配情况)
- 自定义灰度版本请求头以及请求值 固定值 gray=gray-996
- 灰度版本IP数组
- 灰度版本城市数组
- 灰度版本用户数组
-
整体的逻辑
在请求进入网关时开始对是否要请求灰度版本进行判断,通过Spring Cloud Gateway的过滤器实现,在调用下游服务时重写一个Ribbon的负载均衡器实现调用时对灰度状态进行判断。
-
利用GlobalFilter和Order接口实现前置过滤器和后置过滤器
-
前置过滤器中判断灰度开关是否打开,判断灰度发布的版本,只要符合其中一项就将灰度状态的枚举设置到灰度的ThreadLocal中
-
后置过滤器是为了在调用完下游业务服务后在响应之前将 GrayFlagRequestHolder 中的 ThreadLocal 清除避免照成内存泄漏。
-
全局异常处理器是为了处理异常情况下将 GrayFlagRequestHolder 中的 ThreadLocal 清除避免照成内存泄漏,如果在调用下游业务服务时出现了异常就无法进入后置过滤器。
-
-
自定义Ribbon负载均衡路由(业务服务也是使用的这个)
-
灰度Ribbon负载均衡路由抽象类,这是Ribbon的一个抽象类,主要作用是获取服务列表,
会对GrayFlagRequestHolder 中存储的当前线程灰度状态枚举进行判断,
如果枚举值为GrayStatusEnum.ALL则响应全部服务列表不区分版本,
如果枚举值为GrayStatusEnum.PROD则返回生产版本的服务列表,
如果枚举值为GrayStatusEnum.GRAY则返回灰度版本的服务列表版本号会在GrayVersionProperties 中配置,通过服务列表中在Nacos的metadata中设置的version和GrayVersionProperties的版本号进行匹配出对应版本的服务列表
它这可以获取到所有服务并判断他们的nacos中的Version进行匹配返回相应的服务列表
-
自定义轮询算法实现GrayRoundRobinRule
直接拷贝了Ribbon的轮询算法,将里面获取服务列表的方法换成了自定义AbstractGrayLoadBalancerRule 中的方法
-
-
自定义SpringMVC请求拦截器
自定义SpringMVC请求拦截器获取上游服务的灰度请求头,如果获取到则设置到GrayFlagRequestHolder 中,之后如果有后续的RPC调用同样的将灰度标记传递下去。
-
自定义OpenFeign请求拦截器
自定义OpenFeign请求拦截器,取出自定义SpringMVC请求拦截器中设置到GrayFlagRequestHolder中的灰度标识,并且放到调用下游服务的请求头中,将灰度标记传递下去。
存在问题
1、如果项目中使用到了分布式任务调度那怎么区分灰度版本
这里其实挺好解决的,就拿xxl-job来说,注册不同的执行器就行,在发布灰度版本时注册到灰度版本的执行器即可。
2、如果项目中使用的了MQ我们收发消息怎么控制灰度
这里和解决分布式任务调度思想是一样的灰度版本的服务发送消息的时候投递到另外一个MQ的服务端,就是弄两套MQ服务端,生产的服务使用生产的MQ,灰度发布使用灰度的MQ
3、这里整个实现流程不是很复杂,但也是很没必要,只是提供一种实现方案可以参考
其实通过Nginx + Lua脚本方式直接路由网关,然后给灰度整套服务都使用一个Nacos灰度的命名空间,生产的使用生产的命名空间,这样就能将两套服务都隔离了,分布式任务调度、MQ等配置都可以独立在自己命名空间的配置文件中岂不美哉
部分内容引用自:
https://www.bilibili.com/video/BV1E84y1q7H7/?spm_id_from=333.337.search-card.all.click&vd_source=64c73c596c59837e620fed47fa27ada7
https://blog.51cto.com/u_6813689/11876044
华为的员工有这个经济基础,有条件比国人先走一步,做一个乐观、开放、自律、正派的人,给周边做个表率。当前一部分华为人反映出来的现象,恰恰相反,令人不安。一部分员工,不知道自己的祖坟为什么埋得这么好,还是碰到了什么神仙,突然富有后,就不知所措了。有些人表现得奢侈,张狂,在小区及社会上表现出那种咄咄逼人,不仅自己,自己的家人也趾高气扬……;一部分人对社会充满了怀疑的眼光,紧紧地捂着自己的钱袋子,认为谁都在打他的主意,对谁都不信任……。这些,都不是华为精神,这些人员不适合担任行政管理职位的,不管高低都不合适。他们所领导的团队一定萎靡不振。
任正非:要快乐地度过充满困难的一生