灰度发布系统设计

前言

互联网公司在起步阶段一般用户量少,系统处在快速试错与迭代阶段,对于系统部署对用户的影响及系统上线的流程不会有太多的顾虑和投入。相反,当业务量上升,系统承载的流量也因此升高,这时还用起步阶段的部署流程和方式,不仅对用户使用可能带来较大的影响,也对自身产品的品牌形象带来伤害。

这个话题其实已是老生常谈,现在各种微服务治理,k8s等容器编排系统甚至service mesh的普及,将服务上线对现网的影响理论上已经减少到很小,蓝绿发布与canary发布的设计思路也有许多说明文章。但就像Lessons of history这本书阐述的,一种文化在100年没有发展就会自然消亡,如果需要重建该文化,那就必须要从零开始(狩猎、农耕、工业等)。所以写这片文章,也是为了将之前实践过一些经验记录下来,以便在未来的工作中能事半功倍,这也是技术文化的一种延续。

本文记录一些发布系统的思路和设计,供参考。

常见问题

首先,灰度系统(统称)能帮助解决系统工程里的哪些问题。

  1. 服务中断

传统的发布方式,新的系统打包上线后,关闭老系统,重启新服务。这样粗暴的方式通常都会导致服务中断,如果没有充分的测试和验收,上线后再出现故障就会导致更长的中断时间,严重影响用户体验。

这里架构上不论是单点dedicated server还是分布式集群,其实还是有不少工程师是用这种方式来发布的。

  1. 风险不可控

系统总是存在bug,没有100%完美的服务。但是不能因此就容忍故障导致的大面积宕机,设计好的灰度系统可以控制上线版本,将故障控制在一定的子集内,即使出现故障也将影响面控制在最小。

  1. 流量不可控

设想一个问题,即将上线的v2版本新功能我想让北美区的用户先体验,采集使用数据并对用户使用情况做分析,再投放到核心的国内地区。这样的场景需要如何实现呢?如果能有一个灰度系统进行流量的分发,对于产品功能的A/B testing,甚至多地多集群的系统出现故障也能实现跨地域的调度了不是?

几种发布方式

结合上述的几个问题,除了传统的粗暴发布方式,我们还有哪些发布方式,它们又分别解决什么问题?

  1. Rolling updates

这里以k8s为例,一个deployment设置了replicas后,更新新版本的操作就是一次rolling updates的过程,根据官网的说明,rolling updates的操作流程如下:

k8s-rolling-updates-1.png

k8s-rolling-updates-2.png

这样的发布方式存在一些缺陷:

  • 如何控制老pod的优雅下线?(需要在代码逻辑里加一些连接的检测,如果还有存活的前向连接,先维持一段时间等待连接释放后关闭pod)
  • 无法做到精细化的流量控制
  1. 蓝绿发布

见下图blue-green deployment .png

我们需要准备蓝、绿两套环境,前后两个版本的服务在两套环境里不断迭代变换角色。当我们充分验证了蓝色区域的服务后,再将服务上有的load balancer或者domain name切换。

这样可以较好的控制发布的风险,服务经过充分测试,甚至可以做一的shadow packets复制部分线上的流量模拟线上环境测试。但是很明显,蓝绿发布是一个比较耗资源的方式,需要有一个镜像资源,通过物理上的隔离来保证测试,上线稳定性和流量的切换。不过有时这样的投入,相比上线出现故障也是值得的。

  1. canary发布

这样的发布思路,简单来说就是将新版本的服务按最小化可控比例进行上线,同时配合流量调度保证风险的控制和流量控制。见下图。

canary delopment-1.png

canary delopment-2.png

首先,我们屏蔽一台机器的流量,进行新版发布(当然需要先测试过);其次切10%的流量(这里可以精细控制一些IP range,比如公司内网等),验证服务接收线上流量是否正常;最后可以切换100%的流量,用同样的方式更新其他的节点。在实际过程中,我们更新的节点数量可以简单的倍数增加。

A/B testing

单独讨论下A/B testing,它与蓝绿发布并不完全等同,蓝绿发布是技术侧的术语,更多是解决服务更新的问题,并不是在业务层面做多功能的验证。例如两个不同UI风格,同时投放到一类用户群体中进行验证,最后分析哪个UI风格更被用户接受。

A/B testing也需要通过灰度发布系统同时具备风险控制和流量控制的能力才能实现。

实践

先上架构图

gray system.png

我们采用的是openresty的开源框架来搭建内部的灰度系统,架构图中上半区域为我们的控制平面,下半区域为数据平面。

技术点:

  1. 类service mesh的sidecar模式,实现灰度集群发现与调度策略批量变更
  2. consul集群做注册中心,解耦上下游的控制流 (consul的部署与说明)
  3. 对云平台更加友好,新增的服务或者灰度节点都会调用云平台的Load balancer接口进行增删
  4. 流量细化控制,我们可以根据访问设备、IP范围、HTTP header自定义特征等做到流量分发

结束语

我们实现的方式算是比较通用的方案,之前在老东家也是用的类似的解决方案处理了无数次的发版,还因为这个设计在一次跨域故障时很快的把流量切换走,保障用户服务。

当然除了可以使用openresty,大家也可以看看kong(openresty的升级版)和istio(service mesh)。它们都是很不错的开源项目,对大型分布式系统的管理都有充分的理解和设计。

kong

service mesh

[外链图片转存中…(img-FahB80kh-1586262994229)]

[外链图片转存中…(img-oXFdZ36z-1586262994230)]

最后,用了新的画图工具(cloudcraft),感觉比较适用更大型的偏pipeline的架构图。

发布了8 篇原创文章 · 获赞 0 · 访问量 295

猜你喜欢

转载自blog.csdn.net/xiaojax/article/details/105373029
今日推荐