一、背景与方案
1、业务连续性挑战
在银行业,业务连续性是一个非常重要的领域。
- 业务系统发生大规模中断会产生资金损失甚至影响公司形象。
- 金融业务关系国计民生,影响大众生活。
- 监管对银行业务连续性能力的检视非常重视,会定期开展巡检。
因此,很多银行都建立了两地三中心的容灾能力。当基础架构层面具有容灾能力后,出现单机房故障时,通过同城机房的切换实现故障恢复是一种非常理想的故障处理方式。
但通过与同行交流发现,在出现单机房故障时,大家还是倾向于在本地进行故障恢复,通过同城切换来实现故障恢复的案例少之又少。主要原因如下:
- 架构治理: 架构层面对双活的技术方案和实现未制定统一的标准,生产环境部署和配置存在不一致的情况。
- 预案维护: 预案维护于文档系统中管理,随着业务的快速发展预案的新鲜度和准确性存在问题。
- 演练验证: 演练本身的生产风险和实施成本巨大,演练覆盖率较低。预案有效性、应急流程和应急人员操作缺乏有效的验证。
所以当有了容灾的基础能力后,距离随时能切,想切就切的实战能力还有一定距离。
2、业务场景切换能力
当业务系统或业务场景出现故障后,快速通过切换实现我们的恢复目标,是我们容灾切换非常重要的能力。
我们往往将业务场景切换过程分为以下三个阶段:
- 机房、网络、存储等基础架构恢复;
- 操作系统、容器平台、信息系统恢复;
- 业务场景对应的应用与数据库恢复。
应用场景恢复过程往往在整个阶段中耗时最久,因为它的切换对象数量极多。另外,业务场景与应用数据库之间的关系非常复杂,维护预案的成本很高,所以当出现预案不准确的情况时,往往会导致故障恢复不能达到预期效果,增加故障恢复时长。
为了解决以上问题,我们会定期对全行业务进行梳理,找出产生故障后会导致巨大资金损失的关键业务,之后根据这些关键业务梳理出业务相关的业务场景,最后定位到这些业务场景所依赖的子系统。
3、面向子系统的容灾能力
当每一个子系统都建成同城容灾的能力后,我们就可以认为我们的业务具备了同城级别的容灾能力。换言之,当我们的业务场景出现故障时,我们可以通过切换对应的系统快速恢复故障。
IT架构往往分成系统、子系统以及应用三个层次,系统由多个实现特定业务功能的子系统组成,每一个子系统又由多个实现特定业务逻辑的应用组成。
我们在建设容灾能力时,目前选择子系统作为容灾建设的最小单位,原因有以下几点:
- 业务边界明确: 子系统有明确的业务功能边界,变动性小,易于建立与业务场景的关联关系;
- 职能管理维度: 在业务开发、版本控制、运维管理有配套的人员和职能支持;
- 维护成本可控 : 相比数千级别的应用数量,数百个子系统在预案维护上成本相对可控;
- 架构管理单元: 子系统作为架构的管理单元,会对架构设计、高可用等进行评估;
- 服务流量入口: 子系统间有提供服务相对独立,内部访问关系高内聚,彼此访问松耦合等特点;
- 数据库独立使用: 子系统在数据库使用上相对独立,架构治理成本相对较低。
二、预案一键切换
1、双活架构模型
上文中我们讲到通过子系统建设容灾能力,子系统在切换时,其实是将故障机房的一些服务全部拉出,然后把流量和服务切换到服务正常的同城机房。
那么对于一个完成改造的子系统而言,它的服务分成三层,切换时需要对这三层的一些组件做解绑动作。最上面的一层是互联网的流量,例如我们公网的GLSB和 HTTP DNS等流量,也有一些广域网的专线,还有一些负载均衡的服务。 当流量进入内网后,我们通过内网的GSLB与负载均衡的切换实现HTTP层的流量调度。 对于一些微服务的流量,我们通过注册中心的 一些流量 拉入拉出实现流量的切换。
除了以上三种,银行中还有一个比较特殊的服务模式——跑批,即晚上对当天的交易进行复核,跑批的结果会直接影响第二天银行能否顺利开门,也会间接影响我们服务的可能性。 在这个过程中,我们会对作业在哪个地方去跑等做一些切换控制。
理论上,当子系统完成了一些架构改造后,通过这些流量的调度切换,就可以完成我们的工程切换。但实际上,也有一些长尾问题,比如有些子系统做一些双活的改造成本很高,或它是一些比较老的外购系统,这样的系统比例不高,但很重要。所以我们支持这些子系统切换的时候,提供了一些更加灵活的切换能力,比如我们支持做一些应用配置的修改,或者执行自定义的脚本,甚至会提供一些数据库层面的数据修改能力,让那些非标的子系统具备自动化、快速切换的能力,提高应急切换效率。 在数据库层面,更多的是像 Oracle、Mysql或MongoDB等数据库组件的切换。
2、原子预案编排
在切换过程中,每一个类型的切换,我们内部都称之为一个原子的预案,切换工具会对这些原子预案进行预案编排。在执行前,我们有一个检查阶段,来确保目前处于适合切换的状态,才能执行。
当完成执行动作后,我们还需要通过验证来确保执行目标的达成,但具体步骤不是由我们的工具提供,这些能力是由数据库团队或平台架构团队的变更能力提供。而我们的平台是通过HTTP的方式,让他们对执行、检查的步骤进行快速编排。这种检查、执行、验证的编排模式,让大家的切换能力变得更加标准化,也更加安全。
当我们完成切换后,往往还需要对服务进行恢复,切换是从双活变到单活的过渡,当故障恢复后或演练要回切时,我们也会把单活的能力回退到双活的模式,这时候会有一个回退的编排。在回退编排中要做一些检查、执行和验证动作的编排。
由于每一个原子预案都是很基础的预案,风险非常大。所以当我们的预案要发布时,会请每个领域的专家对预案的内容进行评估,甚至做一些测试来保证预案能达到相应效果,保证预案本身的安全性。
3、子系统应急预案
1)故障场景关联
当我们有了原子预案能力以及明确的系统切换清单后,我们就可以在子系统层面编排子系统的预案,这个预案内容可能会包含一些应用、网络以及数据库的操作。当做子系统切换时,这些动作需要同步切换。但是我们可以将对应的故障场景进行区分,尽可能降低切换范围。
2)串并执行编排
我们完成双活改造后,切换对象之间的切换都是独立的,所以我们默认通过一些并行切换的方式提升整体切换效率。
但是因为有一些长尾问题,例如有些子系统在切换之前需要先关闭一些流量才能执行后面的切换动作,所以我们最终提供的是串并行结合的编排能力。
3)预案版本管理
因为架构一直在发生变化,当架构发生变化之后,工具能够捕获到这种变化,我们会将这些变化信息同步给对应的预案维护人,他们可以通过这些提示信息对预案进行实时更新,以免发生价格变化后预案更新不及时的情况。
4)演练状态标识
预案维护后是未验证的状态,只有当子系统完成一次演练后,我们才会认为这个预案处于安全有效的状态,所以我们会在预案没有演练前,提示其切换过程中可能存在的风险。
以上4个能力是子系统预案编排过程中比较关键的能力。当我们的子系统具备了预案管理能力后,我们再去做业务场景的编排会更容易。我们只需要明确业务场景中包含了哪些子系统,并按照故障恢复的优先顺序设定切换执行的批次即可。
4、执行过程可视化
在执行过程中我们会提供预案执行过程的看板,展示目前切换的耗时与执行成功与否,以及每一类组件切换的进度和状态。在执行过程中,如果说有一些步骤或一些预案执行失败,我们也可以通过一些下钻查看具体的报错原因。
5、工具可用性
每年的演练非常多,我们希望通过自助的方式,让运维、DBA以及一些演练执行人能够自助解决一些问题。
上文讲的是如何通过工具体系提高业务系统的可能性,其实工具的可用性相比业务系统的可能性要求更高,因为发生故障时,你期望通过工具对业务系统进行恢复。我们在工具建设过程中,提出了更高的可能性要求。
1)多活
切换工具及其关键依赖,我们会在三个数据中心进行部署。这三个数据中心包含我们的同城机房,生产机房,还有第三地机房。我们会默认把主服务部署在第三地机房。这样当同城和生产机房出现问题时,工具可以快速接管服务,实施切换动作。
切换工具,其关键依赖,以及变更能力是工具的核心能力,发生故障时这些能力不能出现任何问题,所以我们会定期对这些强依赖或关键依赖做一些容灾切换演练。
2)降级
登录等能力是切换工具的弱依赖,切换工具的核心能力是切换。当这些能力出现故障时,我们要尽量避免它对我们核心切换能力产生影响,所以我们会定期通过故障注入或者主动降级来做一些弱依赖的降级演练,确保弱依赖发生故障时,核心功能不受影响。
3)性能
我们也会对切换原子预案的执行性能做一些测试。我们在每一个原子预案上线前,会要求预案提供方提供性能测试的基准,明确指出每一个原子预案执行的并行度是多少,以及在对应并行度下切换的SLA是多少。这种情况下,工具可以对原子预案的执行做流控,保证切换过程的稳定性。
三、运行可观测性
在执行切换过程中,切换的实施人要实时关注切换服务的运行状态是否出现异常,以及是否达到相应效果。
1、运行监控
在应急或演练时,我们会有一个切换成功的标准:切换完成后,业务的关键指标没有明显波动,目标机房要承载100%的生产流量,应用层和基础层对应服务的一些能力满足对应的SLA要求。这需要我们给演练的实施人提供信息汇聚的能力,包括业务层、应用层以及基础架构层面的监控能力。
2、架构可观测性
除监控能力外,我们也会以清单形式展示对应组件的情况。异常展示是分层的,只有出现异常时,我们才会下钻查看实际部署的异常展示。另外,我们也会将告警、变更等体现生产系统异常或存在关联影响的动作在服务节点进行标识,及时提示生产变更的潜在风险。
3、运维数据中台
以上提到的展示能力都依赖于运维数据中台实现。
在运维数据中台中,我们会将服务之间的调用关系以及CMDB的一些部署信息组合成一张拓扑关系网,并在每一个拓扑节点上附加一些配置属性、监控的 url 地址以及变更等信息,丰富每一个拓扑节点的数据。当有了拓补和信息之后,我们就可以快速提供可观测性能力,包括预案维护过程中识别架构变化的能力,以及一些自动化验证的能力。
四、演练线上化
当我们有了一键切换能力以及可观测性能力后,我们还需要通过演练验证人员的有效性、预案本身的有效性以及流程的有效性。中间过程中还要解决一些问题。
我们的同城子系统切换演练,其实是一个子系统层面的中高风险生产变更。在变更方案制定过程中,我们要尽可能避免因为方案层面问题产生的影响。
1、方案风险控制
1)影响范围评估
我们的演练是为了提高生产的稳定性,所以我们在演练过程中,会对演练的影响范围做评估,主要包括以下几方面:
- 识别与演练子系统关联的子系统,如是否存在数据库共用的情况;
- 识别关联系统的相关人员,如开发、运维、DBA等;
- 有相关人员协同识别方案风险,并参与演练的验证。
2)实施风险评估
我们也通过工具对实施风险进行评估,主要包括以下几方面:
- 数据库防火墙未开识别;
- 集群部署当前可用容量不对称问题;
- 软件、框架使用版本不符合基线问题;
- 异常识别自动化检查与二次验证。
有了上述能力后,我们就可以大幅度规避方案层面的一些风险。
2、演练流程管控
第二个风险是流程控制层面的风险。一个完整的流程,对降低演练过程的风险非常有帮助。流程的存在,也能够提升演练的有效程度。对于演练过程中发现的一些问题,我们可以通过问题管理的一些流程跟进,关注它的持续解决。
但是流程的存在也会产生一些成本。因为流程本身非常复杂,有较高的学习和培训成本,并且在有制度无管控的情况下,达不到期望的管理效果,同时,完整的流程实施还会产生巨大的人力成本。
所以我们将线下流程变到线上时,对这些信息做了一些梳理,通过一些强流程的控制,对那些存在变更风险或流程风险的地方做了设置的关卡,来规避一些流程中的风险。对于一些本身很复杂的流程,我们通过提示及引导的方式大大降低用户演练门槛。
3、演练效能提升
我们在工具层面做了一些信息优化,来提升流程的效率。没有工具之前,单次演练的累计时长加起来可能长达三天时间,如果考虑它的起始时间,甚至可能长达一个月。当我们将演练线上化后,我们工具从四个方面提升了演练效能,缩短了演练时长。
1)演练人员协同
线上化演练可以通过识别,实现风险评估、方案制定和演练验证等环节的信息协作录入,这样的话我们演练的负责人只需要对结果做review和确认就可以完成演练的制定,大大降低了沟通协同成本。
2)流程信息集成
线上化演练可以集成变更管控、问题管理、审批管理等流程系统,并且在演练过程中自动完成流程信息的关联与状态翻转。
3)辅助技术验证
线上化演练可以通过面向不同演练对象建立标准化的技术验证格式和指标减少验证成本,还能够自动生成验证信息,大幅降低演练中验证信息的填写成本,显著缩短演练时间。
4)运营决策分析
线上化演练可以通过对演练过程信息的埋点,建立数字化的过程度量能力,并且通过多纬度的统计分析建立演练质量的运营分析能力,提高演练流程的质量和效率。
有了上述能力后,单次演练的平均投入时间从原来的3天减少到2小时,效率提升了10倍以上,同时形成了常态化演练的条件,可以大幅提高我们演练的覆盖率。
4、演练模拟执行
上文讲述的内容是通过演练的方式验证切换预案内容本身的有效性,除此之外还应该验证人员的有效性以及流程的有效性。这些有效性往往通过培训或桌面沙盘模拟,以及应急响应演练来实现,因此我们开发了一套模拟执行的机制。通过模拟执行的方式,可以提升我们一线团队、一线同事对于切换流程的熟悉程度,也可以验证我们流程的有效性。
5、演练过程指挥
我们在做大规模演练的时候,会产生一些指挥层面的需求。
比如我们的演练负责人需要关注参加当次演练的人员信息以及所设计业务监控的正常程度,并且需要关注切换过程中数据中心的流量变化。那么通过我们的指挥大屏,指挥官可以清晰看到数据中心运行信息。在演练过程中,我们也会将每个子系统的切换进度在大屏上进行展示。
五、上线后的收益
1、业务连续性能力提升
1)容灾能力提升
我们实现了容灾切换平台后,整个切换时长得到了大幅提升。目前我们一个子系统端到端的切换RTO小于10分钟,缩短至了原来的三分之一。
对于应用类的切换,RTO的值更小,因为应用类切换的成本主要是不同系统之间的操作成本,当我们去按照一个预案批量执行时,基本上几秒钟就可以完成。
2)业务切换能力
那么因为我们建立了业务场景与子系统之间的关系,子系统又完成了预案管理的闭环,所以我们具备了业务场景切换的预案维护的闭环能力。当业务场景出现故障时,我们可以快速通过子系统的切换实现业务场景的一键恢复。
3)应急方式丰富
原来我们发现一些故障的时候,往往是通过重启、扩容、回稳这传统的三把斧方式恢复故障。有了切换能力后,我们有了更快速的方式,可以通过切换来快速恢复服务,同时切换的方式也是经过验证的,所以它也是一种较为安全的故障恢复手段。
2、变更安全能力提升
除了业务连续性能力提升之外,我们还发现了额外的惊喜。
1)常规变更
我们原来去做一些技术架构层面的变更,无论是应用运维还是技术架构的同事都非常担心,变更可能产生一些较大规模的故障。
当我们具备切换能力后,再进行机房维护时,我们就会提前将这些应用的流量及相关一些子系统的流量切换到我们的通讯机房,保障变更过程中的安全性。当我们完成技术架构变更时,再分批将流量切回来,大大提升了安全系数。
2)蓝绿发版
原来我们行业的发版主要集中在周二和周四,对于一些关键系统,这个时间点往往在周二周四的凌晨两三点钟,对于运维人员很不友好。当我们有了切换能力后,发布过程的安全性提升了,可用于发版的时间段延长,同时发版后业务异常支持快速回退。
Q&A
Q1:是否有必要进行以存储为中心的容灾演练,相比应用为中心的容灾演练有什么区别?
A1: 我们在做容灾切换时,不仅做应用层的,也会做数据层的。所以我理解这个切换应该是应用与数据库整体的切换,至于存储部分是由技术架构团队单独实施。
Q2:在演练之前如何确保两边的数据是一致的?
A2: 我们目前在应用层有一些巡检机制,所以我们会定期做一些检查,在切换之前也会做检查工作,我们切换前后不能说一致,但至少生产的机房跟同城机房之间,处于可切换状态,数据库层面通过数据来实现切换。
Q3:切换后增量的数据可以恢复到原生产数据中心吗?
A3: 这个问题在演练跟应急过程中有一些区别,演练过程中我们会尽可能避免数据丢失的行为,因为演练过程中有一个Switch over的切换方式,但是真正发生生产应急的时候,Switch over的方式时间会比较久。真正发生生产应急的时候,我们会用vivo的 方式做切换,这个时候其实会有一些数据丢失,丢失的数据由DBA同学修复。
Q4:一年进行几次容灾切换的应急演练?
A4: 我们有一个要求,两年之内要对我们的核心系统做到演练覆盖,所以每年的演练数量基本多达几百次。
Q5:切换是仅限同城吗?
A5: 我们在建设容灾能力时,有同城能力也有灾备能力,但因为大数据是实时复制的,同城机房与生产机房都有流量,所以切换的安全性更高一些。两个同城机房都不可用的情况之下,我们才会做一些灾备切换,二者的使用频率跟场景是不一样的,所以我们的演练灾备机房也会有,但同城演练的频率可能更高一些。
Q6:平时业务在两个中心同时跑,是按照1:1的比例分配流量,如果是应用层面的问题,一般两中心同时都有问题,那么切换是否就没有意义了?
A6: 我们平时的流量是在生产跟同城机房以1:1的形式部署的,如果一个节点出现一个问题,物理设备出现一些问题,或单机房的PaaS服务出现一些问题,故障往往是单机房的。如果应用层面出现问题,例如容量问题,这种情况通过切换是解决不了的。所以容灾切换只适用于部分场景,并不能解决所有问题。