3

一、背景
互联网产品开发有个非常特别的地方,就是不停的升级,升级,再升级。采用敏捷开发的方式,基本上保持每周或者每两周一次的发布频率,系统升级总是伴随着各种风险,新旧版本兼容的风险,用户使用习惯突然改变而造成用户流失的风险,系统宕机的风险,500错误服务不可用的风险等等。为了避免这些风险,很多产品都采用了灰度发布的策略,其主要思想就是把影响集中到一个点,然后再发散到一个面,出现意外情况后很容易就回退,即使影响也是可控的。
任何脱离实际业务的技术工作都是耍流氓,技术需要服务于业务。因此,本文尽量淡化了业务方面的因素,聚焦于技术层面,建议在实际运用中还是要根据各自的业务场景去变化和调整。

二、什么是灰度
灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
互联网系统,灰度其实就是根据设定的规则将请求路由到我们的灰度版本(灰度机器)上来。比如对于API来说,一般有如下几个需求:特定用户(比如测试帐号)、 特定的App(比如测试app或者合作App)、特定的模块、接口(只有某些接口需要灰度,这种一般是API Container的修改,拿一些不是很重要的API做灰度测试)、特定的机器(某些请求IP转发到灰度机)等。

三、灰度的优势
1、 在发布过程中降低上线风险
2、 降低影响范围,并且范围可控
3、 降低对测试的依赖,减少线下自测的数据构造成本
4、 特定的请求能够指向特定的服务器,方便集中监控日志,方便跟踪完整的调用链路
5、 方便系统流量切入
6、 便于随时回滚
7、 指定特定人群,方便系统回访,方便产品需求收集,完善产品功能,提升产品质量
8、 在无状态的情况下保障用户使用到的版本一致
9、 避免宕机给用户带来不好的体验和使用

四、目标
1、 做到对现有业务系统无侵入性
2、 能够发挥以上提到的灰度的优势
3、 发布系统的灵活配置
4、 发布系统和业务系统的松耦合
5、 和网关系统结合,让操作平滑

五、功能
1、 路由策略管理/配置
2、 灰度规则管理
3、 开启/关闭开关

六、系统设计
需要设计的系统分为两种场景,一种是http方式接入,需要借助网关(gate-way)去实现流量的切换,和系统路由;另一种是rpc接入(目前为dubbo),需要借助dubbo提供的负载均衡策略
来实现,结合自带的qos(dubbo的在线运维命令)实现服务启动/关闭。
【说明】:服务内部执行线程监控待定,sentinel 、 pinpoint or other。

1、http方式接入

图片描述

其中分为几个重要的部分:
接入层网关,接入客户端请求,根据下发的配置将符合条件的请求转发到新旧系统上.
配置管理后台,这个后台可以配置不同的转发策略给接入层网关.
稳定和灰度两种处理客户端请求的业务服务器.

http请求的入口都落在网关上,网关会根据管控平台(admin dashboard)的配置进行uri的选择。此时请求数据会判断当前应用是否已经开启灰度,再次判断是应用级别的灰度还是服务级别的灰度,然后根据管控平台配置的灰度策略进行灰度,可以支持白名单、权重、ip段、业务域等。
管控平台会调用引擎管理执行相应的指令,进行关闭、开启、更新策略和白名单数据等,每次网关重新reload和重启时会从灰度管理系统调用接口读取配置应用的信息,加入缓存。
为了提升性能,应用的基本信息、灰度策略、白名单等数据缓存在内存或者类redis这样的缓冲中,灵活的进行缓存数据的更新。
实现功能:
1、动态路由
2、服务动态编排,实现流量的自由切换
3、启服/停服
4、服务自检

2、rpc(dubbo)接入

如果直接停机重启rpc service会有什么影响:
服务发布时,直接重启Tomcat,导致节点正在处理的请求会受到影响,严重时会有数据异常。
服务发布时如果节点正在作为task_tracker运行lts任务,会导致任务失败并retry。
服务发布时如果节点正在消费RocketMQ中的消息,会导致消息消费异常,甚至进入retry或dlq队列。
服务发布完成后没有即时验证机制,直接暴露给用户,如有异常影响面很广。
线上无法同时存在新老版本的服务来用于长时间的验证。
竟然有这么多问题,想想就可怕,泪崩~,因此必须想法优雅的实现服务的启停,因此引出dubbo 服务的持续发布:
图片描述
dubbo-consumer实现不同的负载均衡,在负载的时候进行白名单校验和策略选择。系统对灰度管控平台非强制依赖,管控平台出现问题不影响系统正常运行。
负载动态路由,阻止后续流量进入,监控服务是否还有执行的线程,加入钩子offline服务或者接口,进行服务升级,自检,启动online,接入负载均衡。

由于很多接口都有在Dubbo中进行注册,因此需要有办法能够对其Provider Service接口进行下线或屏蔽,使其不提供服务,即其它服务无法调用它的接口。
Service接口下线后,此consumer机器自然无任何流量流入,因此也无流量返回,达到下线consumer机器的目的,然后即可部署代码。
官方有提供Dubbo-Admin工具,用于对Dubbo中各APP及其Service接口进行管理,里面自然也包含有实现下线的功能,可以有3种方法:
屏蔽,貌似一直没有效果(尴尬);
禁用,可以成功禁用;
权重调节,可以设置0-100的权重,设置为0时即不提供服务。

图片描述
经过权重调节方案,通过Dubbo-Admin对需要下线机器的APP应用接口权限设置为0。

实现的功能:
1、缓存负载策略
在系统启动的时候要根据系统配置拉取灰度策略,并且保存在内存中,定时获取最新的负载策略,需要提供及时触发的策略更新接口。
2、 负载均衡
在系统上线之前选择运行时使用的负载均衡进行调用。
3、系统配置
系统在上线前需要录入管控平台,并且完成相应的配置,在启动的时候作为唯一标识能够拉取相应的配置。
4、监控和统计
系统在内存中缓存统计信息,定时上传管控平台,监控出现问题不影响系统正常使用(sentinel,or dubbo-amdin模块扩展)。
5、qos运维工具
系统的启动使用qos,停服采用延时关闭结合jvm钩子。

七、检查机制

为了平滑发布的顺利进行,检查确认机制不可或缺,即确保Dubbo/Http中的下线都已生效,并且无流量发生,我们从以下两个维度去检查:

接口检查,调用Dubbo、Http的API接口,检查业务服务机器状态,是否为已经下线。当然,在做了下线功能的同时,我们也有检查功能和上线功能,可供调用。
监控检查,调用监控平台(ELK)的API接口,检查业务服务机器的请求访问数和日志流量是否都已经为0,已经处于下线状态。
经过上述改造后,我们新的发布流程如下,基本解决了平滑发布问题,发布时对业务的影响降到了最低;

八、停服/启服后小范围验证
1.灰度验证--不影响线上用户
2.部分实例发布-- 导部分流量到新实例(可通过网关路由规则:用户ID取模,区域限制等等)
3.全部发布


kevin
215 声望28 粉丝

stay hungry stay foolish


« 上一篇
java编程规范