作者:京东物流 冯志文
背景
从研发的流程阶段来看,在确定产品需求后,我们会经历架构设计、编码、测试、联调验证和上线这几个阶段来交付系统。在这个过程中,我们需要特别关注上线环节,因为它是事故高发的阶段。
为了应对这种情况,我们实施了严格的发布标准操作程序,简称为“发布三板斧”。这包括可灰度发布、可验证发布和可回滚发布。通过这三个步骤,我们可以确保在发布过程中尽量减少风险,提高系统的稳定性和可靠性。
一、灰度要有耐心
1、灰度意义
1.灰度发布是为了验证我们的假设,即“还存在我们不知道的问题”。因此,在进行灰度发布时需要更加谨慎,确保即使问题在生产环境中出现,也能控制其对业务和用户的影响。通过灰度尽可能的减少问题的影响面,如果通过灰度过程发现一个线上问题,那么去掉灰度的保护,可能就会产生一个严重的故障。 我们可以逐步验证系统的稳定性和可靠性,减少风险并提高产品质量。
2.我们需要明确一点:灰度从来不是为了测试。它的主要目的是对抗“未知的不确定性” 。在软件开发过程中,我们无法预测所有可能的问题和错误,因此需要通过灰度发布来验证系统的稳定性和可靠性。
3.在分布式系统中常见通用的灰度过程有 beta 发布、蓝绿发布,进行流量级别的灰度过程,能够满足绝大部分变更灰度验证需求。如果变更复杂度较高或者业务比较重要,在方案设计中也需要进行更精细变更影响面控制,例如按照影响用户维度逐步生效的设计,但要注意一次业务完整流程中开关一致性问题。
4.灰度发布是一种有效的风险管理方法,可以帮助我们在软件开发过程中识别和解决潜在的问题,提高产品质量和用户体验。
2、灰度发布
为解决用户手动部署操作耗时高、对人依赖度高、人工容易遗漏等导致线上问题痛点,强烈推荐您使用 【部署编排】 功能,用户可灵活制定部署策略,实现从编译构建到实例部署的自动化运行,提高部署效率!但部署编排第一次使用的时候需要验证好。
3、灰度有效性
在灰度的落地与推进过程中,有效性非常重要。因为灰度是一个很耗时的复杂的过程。如果不注意的话,很容易出现“形式化”的情况,即只是表面上的灰度,而实际上并没有达到预期的效果。
为了确保灰度的有效性,需要注意以下几个方面:
1.制定详细的灰度计划:在进行灰度之前,应该制定详细的计划,包括灰度的范围、时间、节点等信息,以确保灰度过程的可控性和可预测性。
2.逐步推进灰度:在进行灰度时,应该逐步推进,而不是一下子全面铺开。比如,可以先在一个机房的一个分组中部分节点进行灰度,然后再扩大到全部节点和集群,最后再扩展到另外一个机房的相同步骤。
3.监控和反馈:在进行灰度时,应该及时监控和反馈,以发现和解决可能出现的问题和风险。关键点在于时间和流量
时间: 每个灰度阶段至少有 5 ~ 10 分钟的观察时间,这个时间可以根据业务系统的具体情况进行调整。在观察期间,需要密切关注监控、日志和各方反馈等信息,以发现和解决可能出现的问题和风险。只有当这些信息没有异常时,才能扩大灰度范围,进一步推广灰度计划。在灰度过程中,需要保持高度警惕和敏锐的洞察力,及时发现和解决问题,以保证系统的稳定和可靠性。
流量: 在进行灰度时,流量是一个非常重要的因素,需要特别注意。特别是对于一些业务场景,可能需要特定的触发条件才能进行灰度测试,比如只有满足某些条件的用户或订单才能参与测试。 在这种情况下,仅仅通过单位时间内是否存在异常来判断灰度是否成功是不足够的。还需要确保有足够的有效流量来触发这些特定的业务场景。否则,即使系统在灰度测试中没有出现异常,也不能完全保证系统在实际使用中的稳定性和可靠性。 因此,在进行灰度测试时,需要确保有足够的有效流量来触发这些特定的业务场景。同时,还需要注意监控和日志等信息,及时发现和解决可能出现的问题和风险。通过这种方式,可以更好地保证系统的稳定和可靠性,提高灰度测试的效果和价值。
有效的灰度可以把问题影响锁定在一个小范围内,但是同样也降低了问题的“明显性”,所以你要通过监控和日志更加仔细、谨慎地去寻找、观测异常并对比发现问题。灰度是一个复杂的过程,需要仔细考虑和规划。通过制定详细的计划、逐步推进和及时监控和反馈等措施,可以确保灰度的有效性和可持续性。
4、灰度验证
如果灰度发布的时候都是带有开关功能,则全部发布上线后,需要通过DUCC开关来进行灰度验证。
4.1、新功能业务灰度:
适用场景:新的链路功能,比如提供新的API,跟历史代码逻辑无关
操作步骤:代码无开关,代码上线确保不影响老逻辑即可。通过业务线上灰度验证相关逻辑准确性
4.2、核心链路灰度验证
适用场景: 如果是在原有链路添加新功能,则系统上线后,业务需要在生产环境中进行灰度验证。这样可以在生产环境中不影响其他用户体验的情况下去测试新功能,只影响灰度的数据,缩小影响范围。
操作步骤: DUCC功能开关可以配置相关的验证参数组合(比如下单前根据用户pin、百分百、门店ID、下单后订单号、仓库ID等)。DUCC配置如下:
jitSwitch.storeId=1-1,1-2,1-3,1-4,****
4.3、切量灰度
适用场景:比如重构、技术改造、黄金链路上线的重要功能
操作步骤:根据订单号或者pin百分比逐步切量进行线上验证。如下图DUCC配置 :
commonSwith.percent=10
切量比例需要注意hashCode() 返回值为负数,潜在的放大了期望的切量比例
5、灰度注意事项
1.灰度验证要细心 。 其实跟上线一样,主要都是依赖日志&监控&报警规则的建设和配置。只不过灰度的比例小,通过ump监控等报警没有那么敏感,核心还是需要关注灰度对应logbook日志,业务上下游链路可视化相关验证。
2.灰度回滚:灰度过程务必具备整体暂停回滚能力 。 灰度过程中发生问题,立即暂停灰度,并且把之前灰度机器操作回滚,如机器少可JSF下线或者停止机器。如灰度比例高,则不可停服务,需要快速回滚(通过ducc开关代码隔离、或者代码回滚)
3.灰度回滚过程中历史数据需要纠正处理
二、验证需要兼容
1、可监控
完善的监控告警比人工反馈响应更快,也会减少故障的持续时间进而降低影响。在推进监控落地的过程中,你要和团队成员讲明监控的重要性,还要确保监控的完善与有效。对监控的覆盖程度与范围要求越来越细致。一般情况下,我们监控的都是 API 这一层面,但是单纯的技术指标并不能完整发现,往往要结合业务场景去设计,才能够更加精细化地感知异常。
核心接口UMP(TP99、可用率、流量)或者MQ 等,这个没什么好讲的
2、日志
根据日志验证对应场景(新功能场景及之前线上核心流程场景) 。比如promise场景复杂,上线会验证不同订单类型的下传时间等相关的重要场景订单,如下图:
3、向后兼容性
功能A上线,验证A功能没问题后,需要看下其他功能是否有问题(比如系统的核心环节功能)。
三、回滚就是变更的“后悔药”
1、制定回滚计划
故障恢复最好的手段是各种预案,而回滚则是预案中最普遍、也最有效的。
回滚的必要性 : 应用上线应该制定详尽的回滚计划,能够在最短时间内将应用恢复至上一稳定运行版本;然而系统并不是天然可以无缝回滚的,想要系统具备回滚的能力,在设计与实现阶段需要付出额外的精力。可回滚的本质是系统的兼容性设计与实现,比如常见的“只增不改”,一个 API 内要调整很多实现逻辑才能满足新业务的需求,此时不妨直接新增一个 API ,两个 API 保持参数一致,那么一旦新 API 有异常直接通过开关技术切换回旧的 API 即可。一般情况下应用本身可回滚,而数据层面的可回滚性是重要的考量因素之一。遵循安全的增量变更原则所设计的数据变更方案具备可回滚能力,发布过程中所产生的增量数据列存储值要求可废弃。原则上任何应用服务在发布之前都必须具备可回滚的能力,没有回滚能力的系统不允许发布上线。
回滚操作对业务的影响: 由于应用升级的回滚实施,必然会影响本次升级业务所服务的业务需求,同时会直接影响对本次升级有依赖的其他业务系统;回滚方案中必须明确本次发布窗口所有相关性需求项目,明确一旦发生回滚处理受影响范围,提前告知相关项目组及业务方,同时尽可能降低多个业务关联性较强项目同一发布窗口的回滚风险。
涉及重要性较高的服务应用升级方案要求必须提供回滚方案,且此回滚方案事先在线下环境得到完整模拟演练并确认可行;回滚完成后要求不得中断服务,业务运行正常
2、回滚原子性
回滚的复杂性 : 除应用本身及数据层面的可回滚性考虑外,若服务使用客户端已完成同步升级,则必须考量客户端的可回滚性;极端情况下,若客户端的本次同步升级也造成了其作为服务提供方的使用客户端同步升级,则存在多个应用系统复杂的连带可回滚需求;相关系统也需要评估其应用本身及其数据层面的可回滚能力,作为本次应用升级回滚方案的一并考虑项。在升级方案设计中,应该提前预知复杂回滚方案的实施成本,防止发生上述的同步升级的多重强依赖关系。回滚方案包括但不仅限于:应用回滚、数据回滚及清理、代码回滚、运维策略回滚、监控方案回滚等。
切记:代码需要及时回滚,以防在未修复问题前,下次团队其他同事上线把未回滚代码部署到线上导致二次问题发生。
3、代码回滚之开关技术
在大部分场景下,开关技术才是线上代码问题快速止血,快速回滚的最佳方式(需根据业务系统特性而定)。比如作为下单黄金链路,如遇线上问题的话,采用通用的回滚方式需要5-10+分钟(500+台机器)并且回滚如果操作不当会加重问题,而采用开关技术则是秒级。
四、结论:
复杂需求或者高风险需求的前提下,在架构设计阶段,应该将灰度计划、验证兼容和回滚策略等考虑在内,并做好评估与平衡。具体来说,需要考虑以下两个方面:
1.风险程度: 在评估系统稳定性和可靠性时,需要对可能出现的问题和风险进行充分的评估,并根据风险程度制定相应的灰度计划、验证兼容和回滚策略。
2.成本投入: 在进行灰度计划、验证兼容和回滚策略时,需要考虑相应的成本投入,包括人力、物力、时间等方面,以确保实施计划的可行性和经济性。
综上所述,灰度计划、验证兼容和回滚策略等应该在架构设计阶段就进行充分的考虑和评估,以便在实施过程中能够做到有条不紊、稳妥可靠。