cover_image

技术干货 | 网易云商灰度发布实践

周洛阳 网易智企技术+
2022年03月01日 00:30
图片


图片

导读:软件开发过程中,测试环境和线上环境存在的天然差异,是否让你的每个版本的上线都变得提心吊胆,导致你只能在夜深人静的晚上,偷偷地点击发布按钮?如何让每次发布变得更加自信更加平稳,相信灰度发布将会带给你答案。

图片

文|周洛阳

网易云商高级 Java 开发工程师



图片

引言


你是否在开发过程中遇到过如下这些问题:明明在测试环境已经验证通过的代码怎么上到线上之后就出 bug 了?这个新加的功能是否受用户喜欢,老功能重新设计之后用户能不能接受新的产品思路和操作习惯?带着这些问题,接下来给大家介绍一下网易云商平台的灰度发布方案。希望阅读本文后,能帮助大家解决这些问题。



图片

什么是灰度发布?


灰度发布也叫金丝雀发布,起源是矿井工人发现,金丝雀对瓦斯气体很敏感,因此为了安全起见,矿工会在下井之前,先放一只金丝雀到井中,如果金丝雀不叫了,就代表瓦斯浓度高,此信号也代表了危险。对于互联网软件产品,线上环境的稳定基本等同于产品的命脉,所以为了上线能够平滑,保证线上环境的安全,我们就需要一只"金丝雀",灰度环境就是这样一只"金丝雀"。


从流程上讲,灰度发布,即黑与白之间的灰色地带,仅能被极其少数的人感知的发布动作。即让小部分用户先体验新特性 A,一部分用户无感知,当特性通过了测试验收,且在灰度期(灰度发布开始到灰度功能合并到线上环境这一段时间,称为灰度期)内没有用户对特性 A 持有反对意见,那么扩大范围,让所有用户都感知到功能 A。灰度发布可以促进整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。


图片


灰度发布的好处有哪些?


  • 发现重大问题,可回滚“旧版本”;

  • 提前获得目标用户的使用反馈;

  • 快速验证产品的 idea;

  • 避免停服发布给用户带来不便;

  • 让用户参与产品测试,加强与用户互动



图片

灰度发布设计方案


为了实现灰度发布的功能,我们需要解决以下四点:目标用户的选取策略,不同服务打标签的姿势,中间件支持多环境的设计方案,入口流量(接口请求,MQ 流量,延迟队列)灰度路由的方法。是不是看上去和把大象放进冰箱里的难度差不多?我们再来看一看具体细节。


 目标用户的选取策略 


选取策略即选取哪些用户先行体验新版本,是强制升级还是让用户自主选择等。针对 C 端用户来说,可考虑的因素很多,包括但不限于地理位置、用户终端特性(如分辨率、性能)、用户自身特点(性别、年龄、忠诚度等)。如果你的客户是 B 端用户,则选取的目标“用户”的粒度往往会大一些,通常以一个企业为粒度,企业下的所有员工同时体验到版本的升级,考虑的因素往往是企业规模和该企业的意愿、忠诚度等等,当然你也应该将你的测试企业加入灰度环境当中。


 不同服务打标签的姿势 


为了实现新功能和老功能同时存在的效果,每一个服务都应该同时在线上存在 new/old 两个版本的实例,以供服务发现框架在识别出请求应该归属的环境后,根据灰度和非灰度标签转发到正确的实例上。如网易云商的 node 端和 web 端的服务,在将服务注册到注册中心的时候会添加 online 和 online-gray 这两个自定义元数据到 metadata-map 中,service 端将服务注册到 RPC 的时候将 dubbo.registry.group 分别配置为"/online"和"/online-gray"。如下是云商需要打标签的服务:


图片


 中间件支持多环境的设计方案 


配置中心、消息队列等中间件需要能支持多环境的设计。配置中心有线上组和灰度组。消息队列通过 topic 主题前缀包含 gray 和不包含 gray 进行区分。如下是云商需要处理的中间件:


图片


 入口流量灰度路由的方法 


将你选取策略选中的用户发起的请求转发到拥有灰度标签的服务上,称为一次灰度路由。如在网易云商架构中,使用网关+负载均衡器对请求进行灰度路由。



图片

网易云商灰度落地实践


网易云商是典型的 2B 应用,所以在网易云商中,灰度用户的粒度大部分情况下是一个一个的企业,小部分情况下,对于管理后台的灰度用户是 QA 同学。


先看一下云商的简化后的架构图,带着前面说过的三点,思考一下需要在哪些环节进行改动。


图片


可以清晰的看出需要在哪些入口做灰度路由,需要在哪些中间上进行环境的区分,对服务层打上不同标签。


图片


在网关中,对于不同的请求端,使用不同的选取策略,企业用户端获取用户的企业信息,系统管理端获取登陆者邮箱信息,OpenAPI 获取企业 appkey,其他页面判断是否存在强制灰度标示。


图片


灰度逻辑上线计划


第一次将满足灰度发布的代码逻辑上线的时候总是让人心惊胆战。但只要在上线的过程中满足下面这几点,就能将风险控制到最小。


  • 流程文档化。永远不要相信在压力情况下,自己的记忆水平。将上线的每个环节(细到每个服务的发布动作)变成 checklist 放在文档当中。
  • 步骤可验证。如 service 服务启动后,RPC 是否新增一个生产者,消息队列的 topic 是否多了一个消费者。Web 服务启动后注册中心是否新增一个生产者,RPC 是否新增一个消费者。
  • 可回滚。当出现问题的时候,能及时切断灰度的流量。



图片

灰度发布带来的变化


项目引入灰度环境后,上线的流程多了一个灰度验证,同时你需要管理维护的 git 分支,永久的多了一个 online-gray,灰度环境的代码版本永远早于或等于线上的代码版本。这些将导致之前的发布流程和代码合并流程发生变化,同时代码合并的过程中可能会引入新的问题。


  • 新的需求发布流程

    定义目标->选定策略->筛选用户->部署系统->发布总结->产品完善->新一轮灰度发布或完整发布


  • 新的 git 分支合并流程图

    每个需求开始时从线上分支拉一个独立的需求分支,当需求环境提测通过后,合并到灰度分支,灰度验证后,再合并到线上分支发布上线。


图片


  • 防止灰度代码错误上线

    如果你们的项目团队也是敏捷开发的,请格外留意这一点。在敏捷开发的一个周期过程中,往往存在多个独立交付上线的需求。这时候灰度环境会同时存在多个待测试和用户验证的小需求。如果在无意中,将灰度的代码合并到线上去。这时候线上就会被未经过验证的功能需求所污染。


    如何解决这个问题?关键点在于禁止将灰度环境的代码直接合并到线上代码中去,保证所有线上的代码只能来自 feature 分支。云商解决这个问题的思路是在灰度代码中放一个特殊文件”error.log“,GitLab 监听线上分支代码提交后进行扫描是否存在 error.log 文件,如果存在则触发告警。


图片
图片



图片

总结


灰度发布是可以帮助你平稳更新发布的工具。其主要思想就是把影响集中到一个点,然后再发散到一个面,出现意外情况后,将问题控制在一个点之内,让问题变得可控,同时具有容易回退的特点。当新版本发布的时候,为了减少发布的风险和影响面,就可以使用灰度发布策略,在流量的入口侧将指定测试人员的流量转发到新版本上,然后当新版本内部测试通过后,就可以将需求合并到线上环境。引入灰度之后,必然会带来发布流程的变化和新的问题,但是这些问题和带来的好处相比是可以接受的。小步试错,大步快跑。



 作者介绍 


周洛阳,网易云商高级 Java 开发工程师,负责云商平台公共业务模块和内部中间件的设计与开发。



 相关阅读推荐 


技术干货 | WebRTC ADM 源码流程分析

技术干货 | JDK、Spring、Dubbo SPI 原理介绍

技术干货 | C++ 四大特性之三:concept 特性详解



图片
图片


图片


继续滑动看下一个
网易智企技术+
向上滑动看下一个