网关实现灰度发布

220次阅读

共计 2897 个字符,预计需要花费 8 分钟才能阅读完成。

一、背景互联网产品开发有个非常特别的地方,就是不停的升级,升级,再升级。采用敏捷开发的方式,基本上保持每周或者每两周一次的发布频率,系统升级总是伴随着各种风险,新旧版本兼容的风险,用户使用习惯突然改变而造成用户流失的风险,系统宕机的风险,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. 全部发布

正文完
 0