金融级系统海量流量下高可用架构的道与术
本文由ITPUB整理自京东科技 康杨 在中国系统架构师大会(SACC2022)的演讲《金融级系统海量流量下的高可用架构道与术》,重点介绍金融级系统高可用方案的实践路径。
本期分享嘉宾
康杨
京东科技备战架构师委员会负责人
京东支付架构师团队负责人
【嘉宾介绍】京东集团认证讲师、京东集团PAAS化架构师委员会成员。整体负责京东支付PaaS化改造、京东支付上云 、京东春晚垂直链路科技侧备战 、京东科技业务中台大促备战 、央行数字人民币、北京消费券、国密改造、数科统一账号、数科开放平台;所负责系统覆盖5亿+用户,支撑京东1000+业务线,大促TPS百万级。
本文整理自SACC 2022中国系统架构师大会上嘉宾演讲,在全球供应链整合和数字化转型的背景下 ,金融系统正在经历一场重大的历史变革 ,如何在保证系统高可用、高稳定性的基础上,通过技术的革新,带来更高的性能和用户体验 ,并兼顾成本的考量。通过本次分享,将从技术视角展示用户最佳体验下的最低成本备战实践路径,以及在数字化转型背景下,如何通过技术的革新更好地赋能业务。
分享大纲:1、高可用与不可用2、复杂业务的可用性挑战3、金融业务的不可用4、不可用的本质5、多长时间不可用6、高可用之数据库
高可用与不可用
我们在日常研发中会面临各种各样的挑战,其中系统的 “高可用”是一个越来越重要的话题。比如:系统能承受多少的TPS,这是衡量应用稳定性的一个基础能力。尤其在大促备战阶段,在海量流量冲击下,如何去保证整个系统的可用性,是我们必须要面对的问题。
问题是,什么是高可用?是什么原因导致了系统的不可用?在数字化时代,高可用对系统开发或者架构设计来说,到底意味着什么?
其实,高可用并不能单纯地理解为整个系统是否能够使用,如果系统架构本身没问题,但却有安全风险,依然不可用。所以,在研究什么是高可用之前,我们先来看什么是“不可用”。
不可用,其实由两个因素造成:第一是风险;第二是条件。我们可以把不可用看成是潜在风险在一定条件触发下的一个结果的呈现。所以,当我们谈不可用的时候,其实说的是一种结果,而且这个结果在不同公司、不同团队、不同阶段,以及针对不同的人的影响不一样。
复杂业务的可用性挑战
针对核心系统来说,日常开发的最大挑战就是高并发。但是,如果真正面临百万和千万TPS,这种高并发其实有成熟的解决方案可以应对。所以,很大一部分挑战是在各种复杂和变化的场景下,如何保证系统高可用?
当所有的事务都处于变化状态,所有事务都不是100%可靠,才会有风险。因为,风险其实是不可见的,可见的时候系统已经是不可用了。而且,并不是所有的风险都处于已知状态,往往越是在关键时刻,那种未知的潜在的风险,带来的影响反而更大。
举个例子,如果所有的服务器都使用的是容器,平时系统运行都很正常,但是你不知道你的系统和哪些应用部署到了一个宿主机上,这个时候很可能在某个关键的一个节点,然后因为那个应用的问题导致你的系统不可用,这些都是我们在日常的开发中很少去关注的事情,但是就是这些事情往往在关键的时候给你带来致命的打击。
所以我们知道,风险可以去远离,可以减少,但是不能把它消灭掉,所以不可用是不可避免的。但是不可用是可以推迟的,而且可以缩小影响的范围,然后去缩短影响的时间。所以我们需要做的就是,要减少风险的数量,而且增加已知的风险,尽量避免未知的一些风险,还要去降低风险触发的条件,尽量影响减少风险的这种影响的范围。缩短整个系统不可用的这个时间。
我们为什么现在越来越强调这个系统的可用性,其实主要有以下几个方面:
1.就是随着这个全球供链体系的建立,我们所建立的已经不是一个业务系,而是一个业务的生态。公司、部门、团队、系统之间的边界不断去被打破,系统之间相互连接,相互影响,关系越来越错综复杂,所以很可能是某一个点的问题,会像多米诺骨牌一样带来一连串的连锁的反应。
2.当一个系统从一维发展到N维,系统的复杂度已经超过了某个人能够掌控的范围了,就是系统的可用性的挑战越来越大,系统失控所带来的这种影响越来越高。
3.对于一个 N 维的这样一个系统,当某个条件出现的时候,就很可能是某些维度的这种系统没有问题,只有某一个维度的系统出现了一个问题。所以,如何在这种复杂的这种系统中快速识别问题,并尽快的修复,成为了一个越来越复杂的问题。
金融业务的不可用
值得一提的是,针对N 维系统,目前大家主要采用的是pass 化或者通过业务身份的方式,把 N 维的这种空间的问题又重新回归到一维,从而极大降低系统的复杂度。这也是通过架构升级,提升系统可用性,降低系统复杂度的一种常用方式。
比如:收银台,是整个京东的复杂场景的一个投影。不管是京东的线上和线下,都是这样一个平台支撑。随着业务的扩张,那么整个收银台的维度也在快速变化。从简单的PC 收银台,某一个 App 的收银台,变化成主站的一个收银台,或者是某一个业务的收银台,而且不同的业务,比如:电影票或者是手机充值,我在 A 这个业务上 A 这个 App 上的一个业务的诉求,支付工具的这种呈现,包括各个部门的风控的这种要求,和他在另外 App 其实根据业务场景要求是完全不同的。而且,这种发展是随着业务的发展是快速变化的。所以,这种情况下,如果在保证系统业务快速发展过程中,保证这个系统依然属于一种非常稳定的一个状态,就是一个很大的挑战。
所以,目前是通过业务拆分的方式,把这种 N 维拆到 E 维,从架构层面来提升系统的这样一个可用性。对于金融系统来说,其实可用性的还有另外一层的一个含义,就是金融资产的这个安全。因为涉及到钱,所以可用性面临的挑战以及不可用性带来的影响,相比一般系统来说都是更大的不可用,不仅意味着用户体验的损失,更有可能带来资金的风险。比如:对用户实名管控的这种缺失,导致薅羊毛。
所以,对于金融系统的开发来说,保障金融系统的安全,也是系统设计中需要重点关注的内容。比如:针对信息泄露、账号盗用、交易欺诈,金融系统不光是通过风控,来从各个维度来进行风险的管控,也需要进行系统的加固,并且在系统的设计中重新去考虑这些潜在的金融风险的一些因素。
所以,针对比如交易的欺诈账号盗用,其实包括一些营销这些所有作弊,一直在加固系统,这是开发金融系统中需要特别去关注的一个点。随着业务的越来越复杂,以及金融系统的加持,导致我们面临的情况越来越复杂。所以,当我们重新去思考系统的高可用的时候,反而需要抛离开现在这种复杂度,而回归到研发或者系统的本质去思考,去从根本上去找到不可用或者提高系统可用性的这种解决方案。
不可用的本质
在谈到不可用的时候,其实是指一个系统的不可用。所以,不可用的本质,我们可以理解为系统的本质。那么,什么是系统的本质呢?其实可以用一句话来理解,核心点是为了满足业务诉求,是基于对业务本质的一些理解,进行一个建模,然后通过编程语言表达这些模型,在这种空间和时间限制下,把它们映射成机器语言。这句话怎么来理解呢?不论我们所使用的说语言是 Java ,还是其他语言,其实只是一种工具,它的核心矛盾或它主要矛盾其实是对业务本身的这种建模。我们是基于这种模型,然后借助机器语言把它翻译成一种可以在某个机上运行的一种语言,来解去解决现实中的问题。随着云原生技术的一些崛起,包括IaaS层、 Pass 层、 SaaS 层的深入应用,其实机器语言的概念也在发生变化,我们越来越需要去关注业务的本质。换言之,一切的本源就是是系统的本质。那么,不可用的本质到底是什么呢?如果拆解的话,那么不可用的本质是由两个方面构成的。第一,是业务模型的不可用。即核心矛盾或者是主要矛盾,就是我们所映射的或者设计的这个模型已经发生变化了,但是我们在系统里其实没有真实的体现出来。第二,是技术实现哪些不可用。技术实现的不可用其实包括所谓硬件层面的,比如网络 、CDN ,还有软件这些层面的,中间件的不可用。所以,业务模型的不可用其实是平时很少被关注的,但是它其实也是非常关键的。目前,基本上我们经常讨论和关注的,都是参数的一些变化或者你有没有这个接口,这个接口能不能复用,如果不能复用,为什么不能复用?但是业务模型,其实本质是这个业务是怎样一个逻辑,真正在代码中体现,逻辑是什么,是业务模型加上对业务的理解和技术实现的这样一个综合体。也就是说,不可用的本质一般是隐性的,但是快速变化的系统,尤其是接近流量端的系统,就是非底层的系统。比如:账务系统,很少发生变化的系统,感觉会比较弱一点,尤其是偏前端的,像收银台、结算这种离用户这个模型越来越近的情况,它其实是对变化感觉非常敏感。这种经常可能会因为需求的一些变化,更导致业务模型就发生变化了,可能导致你最初设计这种高可用的方案,以及系统之间相互兜底的这种方案,已经发生失效了,这也是引发不可用的一个非常重要的一个因素。而且这种问题很难察觉,很多时候需要靠出现客诉以后才能发现。所以,如何在问题发现之初,就能发现和识别问题,也是在设计系统高可用的时候需要重点关注的。但对于技术实现的这种不可用,除了要关注技术本身之外,也要关注其他的因素。比如:使用的中间件是否发生了版本的升级,版本的升级对你的使用有没有什么影响,以及相关的维护团队是否发生变化,相应的变化是否对日常的使用和日常的排查带来影响,这些都是需要重点去关注的。所以这是从另外一个层面去体现出研发需要做的事情。不仅仅是在日常代码中,更是要看到代码之外的这种影响的因素。不可用,最大的风险点,其实最终还会回归到人的本质。可用性最大的挑战来自于,有限的认知和以及世界无限的变化,和我们不知道我们不知道。也许,是因为这种敬畏之心的缺失,才导致各种各样的问题,这才是不可用的核心问题。为了更容易发现和解决问题,我们可以把研发的角色大概分成四类:第一,可以上线的,整个全链路有非常清晰的一些认知,而且是有一个敬畏之心,保持一个非常谨慎的态度;第二,可以进行架构设计;第三,可以进行日常开发;第四,可以辅助进行完成一些事情,把不同认知的人员放在不同的位置。通过这样一个方式,在保证系统安全的前提下,最大程度地做到人才的充分利用,激发大家对系统的学习和了解的动力,可以不断地拓展自己认知的边界。
多长时间不可用
不可用,很难避免的一个问题,就是时间。系统不可用,核心的影响就是在于,其实线上的业务体现的是业务的价值。所以,持续稳定的运行其实是一切的前提,而时间是影响业务连续性的一些关键的因素。
我们知道,1分钟的不可用,和30分钟的不可用,所带来的影响和事故等级,其实完全不一样。我们再回顾一下,整个不可用,从开始到结束,它一定是因为某个条件,发生了这个触发,而且这个条件很有可能是我们平时感知不到的,而且这种条件的触发,可能是在某一个很长的时间点之内,它都是一个很小的这种数量在发生。那可能突然间,某些条件加速了它这种触发的条件,就可能瞬间一个小的问题,从小演变到大,这也是很有可能出现的一些问题。所以从条件出发,我们可以看到几个阶段:
1. 事前。不可用所造成的影响,还比较小的这个阶段的时候,我们有没有对日常的异常的一些跟踪和报警的一些跟踪?其实我觉得整个报警的处理和机制可能都比较多,但是现在最大的问题就可能是说我们日常的报警和异常太多了,所以这种情况导致大家,淹没在这种大量的报警或者异常的这种信息之中,就相当于没有一个处理机制。
2.事中。说明问题已经扩大化了,可能是体现出这种错误码的快速的一些变化。好一点的状况,在监控大屏上能够看到一些关键的信息的一些指标的变化,还有可能是说它是通过一种客诉的方式或单个客诉或者批量客诉的方式来。这个时候也要考验是整个团队的报警的级别,你的响应的机制以及你的指标体系能快速发现问题。所以这个阶段我们可能提到重点作用是报警,这个时候就是能够让需要得到报警的人,能够快速的去知道这个问题,能够进入快速的这个处理阶段。
3. 事后。看起来可能是觉得没有什么,但是其实它也是极其重要一个因素。研发通常有一个固有思维,当我出现问题的时候,那我第一时间或者说我的直觉去说我想知道为什么出现这个问题,我可能会拆日志,然后看系统各种情况,也就相当于这个时候系统已经开始出现问题了。所以很多时候一个惯性思维,先检查一下问题。但这个时候最重要的一点,并不是说如何定位问题,而是快速的止血,采用相应的流程和机制来保证。针对这几种情况,比如说我最近有上线,也就是说我很有可能在我没有办法定位到是我的系统出现问题的时候,那我就先快速进行回滚。当某个链路有问题的时候,先快速的切换到一个可用的链路上。当明确知道是某些情况下,某些原因,所导致的系统出现问题,可以进行一个快速降级,而且这种降级带来的影响有提前的预案。
4.复盘。事后追踪,看似一个很平常的操作,但是其实真正在日常中,是否进行一个标准化的 SOP 的一个建立,其实是影响到你整个不可用的时间的一个非常关键的因素。
从事前、事中和事后包括复盘,这样一个持续迭代的过程,去建立系统的可用性。
高可用之数据库
数据库可以分两种:第一种,比如类似账务类这种系统,它可能就是强依赖数据库的,包括数据库的增删改查。第二种,类似比如说交易类的这种数据库,更多的时候只有插入这种操作,这是其实两种不同的这种业务的场景,其实有不同的这种解决方案的。
那么基于数据库的高可用,其实核心点是依赖于数据库 MySQL 自身的这种高可用,包括主从的这种机制,当然还有一些一定的容灾的设计,比如说热备、读写分离、冷热分离、延时、异步入库,达到最后整体架构的一个高可用。强依赖数据库架构,其实目前来说可能有平台可能经常采用的,也就是说一主一从一备,而且为了避免单点的风险,那可能对数据库进行拆分,叫水平拆分和垂直拆分,就是根据场景和业务身份的区别,进行垂直身份的一个拆分,保证核心数据和非核心数据、热点数据,以及这种相对来说更新频度比较低的数据,这样一个隔离;同时针对数据量比较大的,进行拆分;包括数据库级别的拆分,或者是表级别的一个拆分。相对来说比较成熟的中间件的,可以进行使用和支持。但是除了依赖数据库以外,也依赖其他一些存储,比如说基于对象的存储,基于大数据的这种存储,基于海量日志的信息的一些存储,包括一些运维信息的一些存储,实时性比较强的Redis集群存储,构成了数据库和缓存的整体的高可用。
而针对弱依赖数据库架构的这样一个情况,我们在讲高可用的时候,经常想尽量减少风险的数量,但是这个时候我们反其道而行之,就是说我们从单纯的依赖一个点,增加成多个点。比如:我们可以采用从单纯的依赖数据库到同时依赖数据库缓存和消息队列。
所以,对于一个非常复杂的这个系统来说,很多时候我们有大量的一个需求这个系统也极其复杂,用各种各样的一个场景。这种情况下一个好处,我们可以保证在三个存储单元里,只要其中两个能够存储成功,那么整个系统它就是都是一种可用的状态。当然,还是有一定的限制条件的,就是只适合于纯的插入的场景。尤其是应用于交易类这样一个场景,并不是适用于所有的场景。但是在这种交易的场景,这种解决方案其实是最大的程度,保证了整个交易的这种高可用。
除了数据库的高可用,还有防刷、限流、降级、防护体系、军演等问题。比如:作为对抗恶意流量的常用方式 ,如何通过防刷将影响降至最低?系统承载的总流量有上限,超出上限造成宕机甚至雪崩的时候,怎么办? 当依赖的接口出现问题时,为保证基本服务或重要服务可用,如何及时切断与故障接口的请求 ,避免引发事故?如何根据值班机制和处理机制建立不同的防护体系?如何与数字化的技术对接?
很多时候,高可用要处理的问题,已经超过单人脑能处理的范围,除了上述可采取的措施,如何借助数字化手段,更好更方便地去建立高可用体系,构建全生命周期的服务能力,是系统架构未来演进的重要方向。