目录
前言
千里之行始于足下。
一、灰度,让上线更有底
1.1 资源较优解
现实中有bug的概率肯定是尽量趋近于0,但是绝对不会等于0。
系统质量的目标自然也不是0 bug投产,而是在人力成本、项目周期、业务目标和系统质量之间权衡后的较优解。
1.2 什么是灰度
灰度,就是通过一定的系统资源冗余,将投产的影响先控制在该独立的系统内,并通过特征导流来提前验证、发现和修复问题的一种技术解决方案。
通过灰度部署,可以将bug的影响从时间和空间的维度上控制在一定的范围内,减少其真实对客影响。
二、投产现状
有时候,心里真没底 =。=
2.1 时间固定
每周三晚上十点后开始投产,有时候投产较多的话,时间会拉长。
2.2 验证不便
有些业务晚上十点已经关停不再允许交易、有些需要客户配合验证的可能客户太晚也不再配合验证。需要次日才能真正发现问题。
有些第三方业务只能线上验证、测试环境用的是挡板。
2.3 影响面广
之所以定在十点投产,是因为想避免业务高峰,但是还是不免影响真实客户使用。
三、设计目标
- 灰度的价值在于提前解决90%系统的90%的投产问题,并不是解决所有问题。
- 实施目标不是短时间内解决所有系统的问题,而是分批分步实施直到解决大部分系统的问题。
3.1 投产影响可控
灰度投产后,不影响任何实际客户的任何功能。保证灰度投产的功能只能被指定人员使用。
- 影响可控
- 最坏情况下玩坏了也是自己人。
3.2 投产时间灵活
摆脱两周一次、每次周三晚上十点才能投产的时间限制。有些业务十点之后就不能做了。灰度投产时间理论上不受限制(但是管理上肯定是需要约束的)。
- 摆脱时间限制
- 保障业务验证
3.3 缩短投产时间
使用自动化的工具,将提前在灰度服务器部署的应用和配置全量100%的推送到各个应用服务器。不用重新每台服务器重复手工上线操作。
- 提前灰度部署
- 自动全量推送
3.4 紧急使用
当前生产确认存在紧急bug,客户无法使用该功能,但是客户十迫切的需要使用功能,则可以先灰度修复部署,然后引导客户进行使用。
- 一是可以解决客户问题
- 二是可以帮我们验证该问题是否真正已经得到解决。
3.5 改善员工身体素质和提升家庭幸福感
延年益寿、妻儿绕膝。(都圈起来要考)
四、应用系统结构
4.1 系统组成
灰度的分级和准入条件,将按照以下四个要素进行分析。
- 系统 = 代码 + 参数+ 业务数据
- 运行中的系统 = 代码 + 参数 + 业务数据 + 实时状态数据
4.2 代码
负责执行业务逻辑。例如java的class文件等。
4.3 参数
影响程序行为的数据,一般是人为对进行配置和管理。参数也分为三个类型。
- 本地参数:在服务器本地进行配置的参数。常见的xml、properties和conf等文本配置。
- 实时远程参数:需要去远程获取的参数。例如,数据库参数表、配置中心、redis中进行配置的参数。这类参数是实时读取和生效的。
- 缓存远程参数:和实时远程参数的唯一区别是,这些参数是缓存在本地的,需要重启才能刷新缓存。
4.4 业务数据
描述业务过程、状态和信息的数据。常见的有数据库等。
4.5 实时状态数据
状态数据是程序在运行期间产生和需要进行保持的数据,例如用户会话信息、本地交互文件、条件互斥状态等,凡是任何跨越了两个以上(包含)请求,都需要访问的数据都可以认为是状态数据。
程序一次交易请求期间多数产生的是临时数据,都是一次调用完之后则立即销毁,这些不能算状态数据。
五、灰度系统的组成
- 由独立部署、特征导流、自动同步和有效管理四个功能组成,前三者前后依赖,需要按步实施。
- 应用级灰度架构图(图5.1)- 高清点击这里
5.1 独立部署
在一台独立的服务器上进行提前部署和启动。其部署和启停不影响生产现有集群的任何服务。
5.2 特征导流
根据流量特征,将交易请求导流到灰度服务器提前进行业务验证。
5.3 自动同步
验证完后,上线日将灰度服务器的应用和配置进行全量打包,推送到各个集群生产服务器。该过程的打包、推送、部署和服务启停全由脚本自动完成。无需人工干预。
5.4 有效管理
制定严谨有效的灰度管理流程和实施细则,保障灰度系统和生产系统之间的有序性;同时也要兼顾灰度的灵活性。
六、可行性分析
6.1 独立部署 - 可行性
等同于在集群中新增一台新机器,前提是接入的网络流量是特征流量。不是普通的客户请求流量。
6.2 特征导流 - 可行性
SLB的七层分发能力,目前行内的F5是具备这个能力的。
6.2.1 根据HTTP协议信息分发
SLB对HTTP协议报文可以按照指定规则进行差异性分发,主要是可以根据HTTP的Cookie值和Header进行分发。
- Cookie优先,因为浏览器原生支持Cookie协议。
这个主要应用于外围渠道接入层(例如:手机银行App到其服务端)。因为其IP不固定。
6.2.2 根据调用方IP进行分发
SLB是具备根据请求IP来分发的能力,SLB判断如果调用方是灰度IP则分发到服务方的灰度IP上,这样灰度和生产的调用地址是一致的。
这个主要应用于 内部业务系统之间的转发(例如:手机银行服务端到业务系统)。
6.2.3 灰度配置分离
当SLB的分发能力不能满足时可以采用次方案。
- 调用方系统需要在灰度环境将后端服务提供方的地址替换为其灰度地址,这里需要分离出这部分地址到一个单独的配置文件中进行管理。
例如:
1)App灰度服务端环境调用后端服务的地址替换为其的灰度地址。
2)在打准备推送的生产包时,脚本自动将该配置文件还原为生产地址内容并打包。
3)推送包含正确的生产地址的包到各个生产集群服务器。
6.3 自动同步 - 可行性
使用脚本自动化的打包、推送、备份、部署和启停服务。
主要使用技术为常见的shell命令:
- tar 打包和解包
- ssh 免登录
- scp 远程复制
- cp 命令
1) 减少人工重复劳动,一次部署灰度,自动打包分发到所有生产集群。
2) 精细设计的脚本可以防止操作员误操作生产机器进行灰度投产。
3) 自动还原配置(如有必要)、校验配置和全量打包和推送,用于减少人工出错的可能.同时保证在合适的时候能给出操作恰当的提示。
6.4 有效管理 - 可行性
- 严格控制灰度内容,保障最近窗口上线内容才能投产灰度服务器。
- 对于影响生产的数据库脚本和配置进行分析评审。并落实具体责任。
- 其他细则、机制和辅助工具。
七、灰度的准入条件
由前面的系统组成可以看到,可以对系统组成的三部分进行灰度,分别为
- 应用级灰度
- 参数级灰度
- 数据级灰度(暂不考虑)。
不同级别的灰度对系统的准入要求不一样。 首先我们来了解一下集群的几个性质。
7.1 应用等同性
集群中每台机器提供的服务是无差别的。
例如:
假设其中任何一台机器宕机,集群依旧能正常正确的提供【所有】服务。
- 理论上任何集群架构都应该是满足该特性的,这意味着在集群中随时增减一台服务器是没任何影响的。(吞吐量除外)。
7.2 配置独立性
在集群拥有多个完整配置源的情况下,对一个应用配置源内容的修改并不影响使用另一个配置源的应用。
例如:
1)对于一些本地的xml配置和properties配置文件,进行修改。不会影响另外一台服务器的行为。
2)对于数据库中的参数的修改则会影响其他服务器的行为。
- 灰度环境下一般对本地数据源可以进行修改。
- 对于远程数据源(数据库、redis、配置中心等)则会产生影响,不能进行修改。
7.3 状态相关性
一个系统中如果存在状态数据,则灰度系统也应该能保持该状态。
例如:
1)批量任务根据数据库表中的状态参数来互斥执行定时任务时,当分出两份参数表后,原集群和灰度系统将无法根据同一个状态参数来进行任务互斥,这样导致会执行两次批量任务。
2)例如一些序号发生器采用数据库中的sequece序列或者redis的incr进行序列管理,这类状态数据如果进行了分裂,那么序号将会重复。
7.4 灰度的必要条件
根据灰度级别的不同,其满足的准入条件也不同。
灰度级别 | 应用等同性 | 配置等同性 | 状态相关性 |
---|---|---|---|
应用级灰度 | 必要 | / | 必要 |
参数级灰度 | 必要 | 必要 | 必要 |
数据级灰度 | 必要 | 必要 | 必要 |
7.5 总结和注意
其灰度的安全底线为:对于灰度环境中任何修改都不能影响现有生产集群的任何服务。
- 以上特性质只是对系统的普适性进行了分析,可以覆盖大部分系统,但是具体还是要以实际效果为准,以此作为标准进行分析、改造和实施。
- 特别注意的是参数级灰度需要对状态数据进行分析,当独立部署灰度系统的时候是否会存在状态数据的分裂问题(即会产生两份状态数据,从而导致状态数据无法同步的问题)。
八、灰度系统的等级
根据系统三要素的组成可以知道,灰度系统根据其包含的系统要素可以分为三个等级。
灰度的字面意思可以简单的理解为:我单独为灰度环境准备一份代码或参数或业务数据。从而实现影响隔离。
灰度级别 | 代码 | 参数 | 业务数据 |
---|---|---|---|
应用级灰度 | 包含 | / | / |
参数级灰度 | 包含 | 包含 | / |
数据级灰度 | 包含 | 包含 | 包含 |
8.1 应用级灰度
第一阶段主推的灰度级别,改造成本小,可以解决大部分问题。
8.1.1 系统描述
- 这个最为简单,应该是所有集群系统都能轻松进行该级别的灰度部署。
- 只需要满足【应用等同性】即可进行灰度部署。
- 只对三要素中的【代码逻辑】进行灰度部署。
其实已包含本地参数的灰度(即可以进行投产内容的修改),无法对数据表参数等远程参数进行灰度。
- 【参数配置(远程)】和【业务数据】公用生产的。
8.1.2 使用场景
应用级灰度可以满足:
(1)提前在灰度进行应用部署。
(2)提前在灰度修改本地xml和properties等本地参数配置。
(3)对于仅涉及业务逻辑的修改,但不涉及全局参数和状态的修改的功能可以进行特征导流,提前进行业务验证。
(4)从灰度系统自动推送和发布。
8.1.3 无法满足的场景
任何涉及全局参数和状态修改的场景都将无法满足。例如:
当然要结合实际影响分析,但是为了防止分析不到位,不建议进行修改。
(1)涉及数据库的改动
1. 例如需要修改数据库字段中的某个参数值。用来打开当前生产不允许放开的功能。(但是在上线日投产后可以打开的功能)。
2. 改变字段类型。
(2)涉及redis中参数值的变动
8.1.4 改造工作
(1)分析应用是否满足集群中的应用等同性。
(2)梳理应用中本地使用的所有有效的配置文件。
有效的配置文件定义为:需要在日常投产过程中进行修改的配置文件。
- 这是为了在灰度服务器自动全量打包的时候,能将配置全量打包并推送到目标集群服务器中。
- 如果配置列表不全则可能会在部署生产的时候漏掉这些有效配置文件。
- 但是这些配置文件已经在灰度环境中完成了修改和验证但是未被打包。(即出现生产配置的修改未生效的情况)。
后续打包步骤中会对该过程进行描述。
(3)选择导流策略并配置导流策略。
(4)进行导流验证
这个验证包括两方面:
- 有效性验证,即特征流量可以进入灰度。
- 安全性验证,即正常流量不应该进入灰度环境。
(5)进行脚本部署和测试
脚本需要在灰度环境和生产集群环境都需要进行部署。
8.2 参数级灰度
- 相对复杂
- 需要对三要素中的【代码】和【参数】进行灰度部署。
- 【业务数据】则共用生产的。
- 需要满足【应用等同性】和【配置独立性】才可进行参数级灰度部署。
- 所以集群系统需要进行必要的参数配置源分离改造才能进行参数级灰度部署。
8.2.1 系统描述
对三要素中的代码和参数进行灰度部署。
(1) 既包含本地参数的灰度,也包含对数据表参数进行灰度。
8.2.2 使用场景
(1)包含应用级灰度的所有使用场景。
(2)可以支持全局远程参数的修改。
例如:
对配置源中的数据中参数表的值的修改。
8.2.3 无法满足的场景
(1)无法满足对业务数据的变更。
例如:
无法修改业务数据库表字段的长度和类型。从而无法验证这些修改是否能在灰度系统是正常运行。
8.2.4 改造工作
(1)包含所有应用级灰度的所有工作。
(2)梳理出哪些高频修改的远程配置。
(3)为这些配置单独配置一个数据源。
(4)分析这些数据源是否涉及存储了状态数据。
(5)管理好这些远程参数变更的执行。保证其在灰度环境中执行了,一定也会在生产环境中同样的得到执行。 (6)由于灰度环境和生产的配置源不一致,所以需要是用脚本在打推送包前将所有配置源还原成生产配置源并进行正确性校验。
8.2.5 系统现状
目前所有系统中都未分离配置数据源和业务数据源。
所以,数据库中参数配置表和业务数据表是存储于同一个库中。在这种架构设计下,如果要实现参数级灰度,那么需要将所有参数配置表单独拎出来放到一个独立的库中。从而实现配置数据源和业务数据源分离。
最后实现灰度环境下对数据库中参数表的修改影响控制在灰度环境中。 同样的规则适用于配置中心、redis配置等各类远程配置源。
8.3 数据级灰度
8.3.1 系统描述
十分复杂,需要满足【应用等同性】和【配置独立性】才可进行参数级灰度部署,需对三要素中的【代码】、【参数】和【业务数据】进行灰度部署。
8.3.2 使用场景
满足一切测试场景。
8.3.3 无法满足的场景
无
8.3.4 改造工作
(1)包含参数级灰度的所有工作。
(2)业务数据准备:测试前需要分析测试场景用到的所有业务和流水数据,将其导入到灰度环境。
因为灰度的业务数据源未和生产做实时同步。
所以测试的时候需要将最新的业务数据导入到灰度环境。
相当于手工同步。
(3)根据业务场景制定可行的业务数据合并策略。如果无法合并则需要评估是否可以进行测试。
因为灰度的业务也相当于真实的生产环境。
所以是真实发生过的事件,需要将灰度业务数据新增的数据回写到生产库,以免造成数据污染。造成不可预期的问题。
- 例如灰度环境发生的转账是真实扣款金额和上账金额,不能视为测试事件。
8.4 总结
【应用级灰度】,改造成本小,耗时短,相对可见的收益较高。
【参数级灰度】,需要将参数配置进行合理拆分独立,从而实现影响隔离,改造难度可接受。同时能覆盖大部分投产的验证场景,可以作为长期目标。
【数据级灰度】,改造难度可接受,但是由于业务数据合并回写规则复杂,风险很高,不建议实施。可以作为研究项。
九、缺点和风险
9.1 硬件成本
- 需要更多的硬件资源,并且这些硬件资源大部分时间都是出于空闲状态。只有进行灰度测试的时候才会启用。
- 所以建议,灰度资源视情况可以申请为生产对等配置的1/3到1/2。
- 对于参数级别的灰度,需要一个独立的配置源,这块属于软件成本。
9.2 运维成本
- 这块主要是参数级别灰度的时候,需要执行两次参数管理的操作。对应用级别的灰度没有影响。
- 另外网络策略和SLB的配置策略也需要更多的分析和维护。在系统迁移的时候可能需要付出更多的运维成本。
9.3 管理成本
- 人员操作风险,例如将生产作为灰度进行投产等。这块在服务器提示符中会标识出该环境为灰度环境。同时对于部署脚本,可以限制只有在灰度环境才能执行。但是仍然存在误操作风险。
- 对于灰度投产的内容管理。需要把控好灰度投产的内容,以免造成真实投产内容的错乱和无序。
9.4 改造风险
- 第一,对于应用系统,存在配置文件梳理不到位的问题。导致在灰度修改的配置无法正确同步到生产环境的问题。
- 第二,对于参数级灰度,可能存在状态数据不同步的问题。
十、常用问题解答(FAQ)
1. 灰度环境和准生产环境有什么区别?
最大的区别在于维护成本,从上面可以看出灰度环境的代码、配置和数据和生产的差异是很小的(代码是自动复制的、数据是共享的、可能存在少许配置差异)。而且能轻松自动同步维护。
准生产环境则完全手工维且和生产的一致性关系难以维护。而且准生产的部署和生产的部署完全是两次毫无关系的独立操作,难免会出现操作不一致。其本质无非是多了一套测试环境。
2. 有什么机制防止在操作人员弄错环境,将生产当做灰度进行发布?
灰度环境中的发布脚本在生产环境是无法使用的。而且会在系统的命令提示符中显示当前系统环境为灰度环境。另外,灰度发布操作期间建议运维和开发一起结对部署。
十一、其他补充
- 灰度虽能解决部分问题,但是项目质量更多的还是依赖于日常的设计、开发和管理。
- 系统最初建设的时候就需要考虑灰度化架构。
- 引入统一的配置管理平台进行配置管理有助于灰度的实现。