1.背景
自2018年以来,受"华为、中兴事件"影响,我国科技受制于人的现状对国家稳定和经济发展都提出了严峻考验。目前我国IT架构体系严重依赖国外产品,金融行业尤其明显。大部分传统银行的关键账务系统都架设在IBM的大型机、小型机之上,数据库使用Oracle及DB2,存储采用EMC。在美国不断加大对我国技术封锁背景下,银行IT产业自主可控的必要性和紧迫性凸显。
以银行的核心系统为例,其作为金融监管部门直接管辖的系统,率先被要求进行国产化试点与替换。银行核心作为众多银行系统中最为重要的命脉系统,承担着核心的存、贷、汇业务和监管部门的监控指标。大型银行对其核心系统的性能和稳定性要求之苛刻可谓求全责备,故银行的传统核心通常都采用IOE的技术架构。当传统核心往分布式技术架构转型的过程中充满了挑战,其中,单元化技术架构是目前所有大型银行都会在其新一代核心系统中采用的主流架构体系。本文将从技术架构发展历程开始,一步步介绍每个阶段是如何演变?为什么到微服务阶段还不足以满足大型银行系统的要求?单元化架构与微服务架构的差异?以及腾讯云的单元化解决方案。
2.技术架构发展历程
2.1 单体架构
集中式单体架构,程序和数据库都在一台主机上面。大型金融客户的核心就是在IBM的大型机或小型机上运行,主要基于Cobol语言开发。由于主机的高成本,每年客户都要不断购买MIPS(主机算力)来应对不断上升的业务量,然而对于这类架构而言,垂直扩展方式的边际成本是很高的。
图2.1 单体架构
2.2 应用与数据分离
集中式架构在业务高峰时,由于程序和数据库部署在一台服务器上很容易就出现资源争抢问题,所以第一步就是把程序和数据库分开部署。如下图所示,应对业务量上升导致的同一台主机资源争抢问题,优先采用的是将数据库独立部署来保证应用和数据库资源互不争抢。数据库所在的服务器资源配置通常更高于应用服务器,开放架构下一般是高配C86/ARM服务器。
图2.2 应用与数据分离
2.3 应用集群部署
随着业务量的增大,下一个问题便是应用侧的瓶颈。这块除了应用程序内部的性能调优外,从架构层面可以采用集群化部署模式,将大量的业务流量通过负载均衡服务来分流到多台应用服务器上处理。常见的负载均衡有F5,Nginx和云上的各种XLB服务。这个阶段的架构已经可以具备一定的横向扩容能力,需要注意的是应用需要实现"无状态"化,避免有状态数据存在本地。
图2.3 应用集群部署
2.4 读写分离
当应用侧可以实现横向扩容之后,逐渐对服务器垂直扩容的需求开始减少,因为垂直扩容的边际成本很高,收益却越来越小,大家更愿意通过扩容标准服务器来应对高并发。随着应用层实现横向扩容后,当业务进入到下一个阶段,压力又会回到数据库这边。应用横向扩容,而数据库还是单体。这个时候就需要分析当前系统的读写比。大多数系统的读写交易比是8:2,读多写少的场景可以考虑使用读写分离模式。开启数据库的主从复制能力,并将写交易路由到主库,读交易路由到从库。
图2.4 读写分离架构
我们可以设置多个从库来负载相对较多的读交易,主库与从库间通过数据库的数据复制能力来保证一致性。复制模式有分同步复制和异步复制。同步模式会损耗一定交易性能,因为需要等到多个从库请求落盘才会反馈主库,对性能敏感的写场景需要考虑业务容忍度。而异步复制会存在一定的延时,同样读交易也需要考虑业务容忍度。
2.5 前后端分离
完成读写分离阶段后,这一阶段我们的应用系统和研发团队已经初具规模。通常这个阶段会开始更注重用户体验,前端技术迭代会逐渐增快,前端技术栈也日益增多(H5/IOS/Android/小程序)。为了让整个研发团队分工更加明晰,系统迭代更加顺滑,前后端分离是趋势。通过前后工程的分离,以开放接口进行交互,实现前后端独立迭代与演进。
图2.5 前后端分离架构
2.6 NOSQL运用
在能承接当前业务量的情况下,从优化角度引入Redis、MongoDB等NoSQL中间件。Redis具备很高的读写QPS,可以有效提升系统整体性能,在秒杀、热点数据查询、数据缓存场景中运用广泛。MongoDB具备灵活的文档存储能力,在存储对象,非关系型数据,地理数据等非强事务类场景下具备独特优势。
图2.6 NoSQL的运用
2.7 数据垂直切分
随着业务的持续增长,主库已经难以支撑所有的写请求,这个阶段优先需要做的是数据库的垂直切分。即按领域把"产品数据"、"订单数据"、"用户数据"拆到不同的数据库中,这样写交易就被按照各自的业务量分流到不同的库上。需要注意的是这种拆分可能会引起分布式事务产生。如果存在一次事务跨了多个业务域的数据库,那就需要考虑多个数据库间的数据一致性问题。我们可以借助分布式数据库的产品能力解决,或在应用层引入分布式事务框架解决,也可以通过消息中间件实现最终一致性,取决于不同场景下的业务接受度。
图2.7 数据垂直切分
2.8 应用垂直切分
在上面的架构基础上,数据已经按领域切分而应用还没有。这就显得有点怪异,每个应用都需要连到3个库上才能操作,这显然是不合理的。数据库的连接数和应用后期的扩容都会存在问题。通常情况下2.7数据拆分后会同步考虑2.8的应用拆分。
图2.8 应用垂直切分
到这个阶段,最初的系统已经被按照不同业务领域,从设计到落地都实现了解耦。基于这种架构已经可以初步支持不同模块的独立迭代与演进,很贴近我们现在所了解的"微服务"架构。
"分而治之"的架构思想在分布式领域得到广泛运用,小到各种排序算法,大到MapReduce、单元化架构等等。
2.9 SOA
刚我们把一个巨石应用拆分为多个子应用时,随之而来的问题是这几个子应用间的通讯问题。在微服务架构之前,银行普遍采用消息总线来做多个系统间的"衔接"。它就像一根通道,集成不同的应用、不同的协议,承担消息解释与路由职责,实现互联互通。属于早期分布式的经典架构。
图2.9 SOA架构
微服务架构和SOA架构同样都是面向服务的架构设计。微服务更强调了去中心化思想,而ESB作为全行的消息总线在一定程度上是形成了单点和瓶颈。微服务架构就是从本质上去掉了ESB,通过注册中心来实现服务发现能力。以发布和订阅服务目录的方式,让应用间通过服务目录来实现点对点的直连通讯。
2.10 聚合查询
在按领域拆分之后,另一个麻烦的问题出现了。原业务中那部分跨多业务表的复杂查询能力由于底层库表的拆分导致无法运行,这时便需要引入聚合查询技术。它和分布式事务一样,是大型金融业务系统在集中式往分布式架构演进的过程中必然会遇到的一种场景。比较好的方法是从企业架构角度将查询业务从联机系统中剥离,即OLTP和OLAP业务分离,因为两种业务所需要的底层技术栈截然不同。
图2.10 聚合查询库
聚合查询指的是一种能力需求,它可以由不同的技术来实现。比如采用ElasticSearch来实现搜索引擎,也可以采用Flink实现流批一体的数据处理与分析引擎,这更大程度上取决于企业架构整体的规划。在银行的实际案例中,规划层面的确会把查询类业务从核心系统剥离到大数据平台处理。但往往会由于大数据平台或周边系统的技术能力或因为各种现状无法很好地承接核心的查询业务。落地时更多的是一种妥协方案,比如核心处理3天或7天内的查询请求,大于3天或7天的请求由大数据平台查询。这里也体现出新核心系统的建设不仅仅是换一颗心脏,而是要从企业架构的整体角度,结合实际情况对周边及配套系统同步进行评估与升级改造。
2.11 数据水平切分
在系统按领域切分之后,如果某一领域内的业务量依然大到主库无法承载。那么接下去就需要在垂直拆分的数据库上再进行一次水平拆分。水平拆分可以将落到一台主库的压力分摊到多个分库上。这个阶段设计时需要注意数据路由和扩容场景:
1)数据一旦被按照一个维度进行了分库,那应用在请求时就需要在请求中带上该维度的值,进行路由判断,识别该数据在哪个分库上;
2)其次是扩容问题,假如当前为10个分库,一开始的路由算法为 hash(客户号)%10,后面扩容到12个分库,那计算规则就要变成 hash(客户号)%12。这样,所有分库上的数据都需要按照新的路由规则重新计算并进行数据迁移,这个过程称为"数据重分布",成本和代价都很高。建议在设计阶段提前与各方约定好路由规则和扩容策略。
图2.11 数据水平切分
2.12 微服务架构
在2.11的基础上,从架构视角已经是我们所熟悉的微服务架构:业务按领域拆分,模块间相互解耦,具备独立演进的能力。现在我们回过来看一个问题,从一开始的集中式架构往分布式架构演进的过程中,对底层技术能力会提出怎样的要求?
回顾前面各阶段,我们可以初步总结如下能力:
1)由于系统被拆成多个服务,所以需要具备:服务注册和相互发现的能力;
2)为了提供可用性,采用了集群部署模式,所以需要具备:应用实例的故障发现与隔离能力;
3)采用分布式部署后,多个服务间需要具备:统一的配置发布与热生效能力;
4)系统拆分后有多个应用端点,对外需要:统一入口来收敛访问端点并提供统一鉴权等能力;
5)集中式系统内部通过内存地址引用可以直接调用,在分布式架构下则会变成网络调用,因此需要具备:点对点通讯能力,由于服务都是集群形态,调用还需要支持软负载均衡的能力;
6)考虑到标准服务器的故障率、大量网络通信带来的稳定因素,以及可能存在的突发大规模流量等场景需求,分布式架构需要具备:服务的限流、熔断和降级等处置能力;
7)由于多模块间调用会导致系统请求链路的增长,降低了系统的性能与不稳定性,增加了运维复杂度,因此需要增加:全链路可观测与故障节点定位的能力;
8)应用拆分部署后,由于一次交易变成了多进程访问数据库,从而产生事务一致性问题,需要具备:分布式事务能力;
【1-8】是根据架构演进过程中针对应用服务侧所需要具备的通用技术能力,对标TSF的产品能力。
9)为降低数据库压力,需具备:读写分离能力;
10)数据的垂直拆分属于业务领域设计与数据库能力关系不大,但数据库或中间件需要具备:数据的水平分片能力;
11)同样由于数据库的拆分,需要数据库或中间件具备:分布式事务能力以及聚合查询能力;
12)集中式数据库拆分为多个数据库集群后,需要具备数据库或中间件具备:统一的数据库集群运维、监控告警与故障检测能力;
【9-12】为数据层所需要具备的通用技术能力,对标TDSQL产品能力。从产品规划来看,LibraDB可通过列式存储特性来支持查询业务,使TDSQL同时支持联机与分析能力,可以应对聚合查询场景。
上述内容侧重系统在运行态架构所需要具备的能力。除此之外,一个分布式系统的设计还需要考虑研发效能体系、生产运维体系、混沌测试能力,以及计算、存储、网络、调度的底座能力,还有偏场景的能力,如:服务编排、分布式序号生成、批量任务调度能力等等。因为与本文主题关联不大,便不展开叙述。
那么,当具备上述能力之后,微服务体系还有哪些能力需要增加?下一章节,我们重点讲一下微服务架构在大型银行核心系统中落地时面临的挑战。
其它能力体系与对应产品关系说明:
13)研发效能体系包括从需求->设计->研发->测试->发布->生产的全链路生产工艺与价值流增效能力对标Coding/蓝鲸DevOps;
14)生产运维体系包括从数据采集与分析->定制化监控->自定义监控->自动化运维->智能化排障等能力对标蓝鲸;
15)混沌测试体系包括从场景设计->原子故障编排->故障半径控制->故障分析与复盘等能力对标Oscar;
16)底座与安全体系,即TCE/TCS,TCE侧重全栈云,TCS侧重云原生,以客户实际情况选择输出即可。
17)通用场景能力像服务编排、分布式序号、批量调度等,一般由ISV侧平台产品输出,形成联合方案。
3.大型微服务系统面临的问题
目前绝大多数银行客户来讲,两地三中心是未来的标准架构。即:同城为双活,异地为灾备,一共三个数据中心。
**"同城双活"从架构角度解释:一个系统分布在同城的两个数据中心,两边都能同时接收业务请求并进行处理。**假如在与客户的数据库团队交流,这里就会出现一个讨论场景:他们可能会问数据库如何双活?没错,对于同一份数据副本没有办法实现两边双活。但从整个系统角度,并不妨碍它成为双活架构。
图3.1 某银行核心系统同城双活架构图
如图3.1所示中,流量从两个数据中心进入,到微服务网关层时,网关通过注册中心获取目标服务的可用地址,基于软负载策略发起点对点调用。应用在处理数据时,由于数据库主本是单边活,所以同城中心的应用需要跨中心访问到另一个中心进行数据操作。
分布式数据库一样也是架构层面实现数据多点可用,而并非是一份数据在多点同时多活。以TDSQL为例,我们可以指定一些库的主本在A中心,一些库的主本在B中心。这些库都隶属于一个分布式数据库实例,在AB两个中心同时提供服务,以此实现"整体上的双活"。在上图的案例中,账务库和公共库的主本在A中心,而历史库的主本在B中心,对应用是一个分布式数据库实例。
使用微服务框架和分布式数据库的能力来可实现同城双活,图3.1是最常见的微服务双中心部署架构。
但在极端情况下,这类架构可能会存在两个问题:
1)应用服务之间的横向流量;
2)应用与数据库之间的横向流量;
以目前的网络基础设施情况,同城内多个机房间的网络情况在大部分情况下稳定性和性能都是有保障的,50公里的延时一般都在1ms以下。这对于跨中心访问来说问题并不大,足以应对大部分银行客户的要求。一般城商行的日常TPS可能就只有几十,峰值可能也就几百到一千左右。横向流量对网络带宽压力并不大,抖动和时延对业务的影响也较小。可对于大型国有银行和头部股份制银行来说,横向流量的问题则会被放大。这类行的日常TPS大多上千,活动峰值可能接近1W。每一笔交易进入,核心平均需要进行50-80次的数据库操作,所以在应用到数据库这一层横向流量会被放大数倍。其次,在应用层微服务之间的访问也会出现横向流量。因为默认的SpringCloud体系中没有提供就近访问能力,需要自行在负载策略中增加规则来实现同中心优先调用,否则就会有流量被调度到另一个中心,而每次服务间的调用都会面临反复来回调度的情况,这部分无谓的消耗是完全应该避免的。
因此,在大型金融系统进行分布式转型时,是得考虑其系统内部在实现微服务化和数据分布式化之后,大量横向流量在两个机房间穿梭的问题,这对基础设施的要求是很高的。从设计角度出发,我们并不应该把宝都压在基础设施的稳定性上,这显然不可靠。单元化架构的出现也正因如此,它可以很好地减少数据中心间的横向流量,进一步提升微服务架构的性能与稳定性。
4.腾讯云单元化架构体系
随着银行技术架构逐渐迈入分布式领域,单元化架构开始流行。早在2015年微众银行首次提出并落地了按DCN(数据中心单元化)的设计理念,按照业务和用户维度进行水平拆分,将银行核心账户体系、核心客户体系、核心业务处理等打包在一个DCN,业务流量经全局路由转发至DCN,成为国内银行业核心系统单元化架构的首个案例。
国外银行没有像国内如此大规模的用户群体,很多国家的核心系统用户量仅仅和我们一个城商行的用户量差不多。所以,19年国有大行在启动新核心分布式改造时,全球范围内都没有可参考案例。经过这几年沉淀,我们联合ISV已经可以把整套方法论与交付工艺进行同业复制。
4.1 什么是单元化架构
遵循分布式系统"分而治之"的设计思想,我们可以将一个系统分为多个"标准处理单元"。每个处理单元由一组计算资源与一部分数据资源组成。每个处理单元的计算容量保持基本一致。如图4.1所示,采用这种模式,我们可以把一个大型系统拆分为若干个单元。单元内实现闭环处理,单元之间互不影响,减少了故障半径的同时,还大大降低了无效的横向流量,提升了性能与稳定性。
图4.1 单元化技术架构图
4.2 与微服务架构的区别
微服务架构和单元化架构并不冲突,单元化是微服务架构的能力增强。微服务架构更注重利用微服务的设计理念来解耦应用系统,以及利用微服务技术手段来重建系统内外的互联和治理模式。而单元化架构更侧重整体性规划,它在微服务体系之上加强了标准化治理,包括标准化扩容、标准化路由,尤其对跨中心流量做了治理,让微服务中的负载调用变得更加有序。微服务像是在微观层面把功能体系建立起来,单元化则更像是在宏观层面把架构体系完善起来,两者相辅相成,相互促进。
微服务架构通过服务注册和发现模型,重新定义了服务间的交互模型,解决了大规模集群下服务的自动发现和故障服务自隔离的能力,还包括集群中配置的推送、链路的监控、服务的治理等等。这些机制是微服务系统运作的基石,如果没有这些机制,那可能就要回到从前ESB的时代,通过企业总线进行服务间的互通。其次,没有单元化,微服务一样可以运行起来,因为底层的功能机制已建立,大部分能力都能在这套机制下运转起来。但以SpringCloud为标准的微服务体系也并非万能,和大多数开源框架一样,其只针对微服务落地中的关键共性问题提供解决方案,在方案完整性和运维运营层面覆盖是不足的。在异地多活的支持和分布式事务等方面使用方更需要提前规划,做好相应解决方案。
单元化架构通过合理的数据切分,把计算与数据进行绑定处理,来控制业务流量单元内闭环,提供了异地多活架构的基础条件。同时提供了大规模系统的标准化管理、扩容、灰度等方案,其更像是一种架构设计思想,而非一种具体技术。这种架构思想也并非只能运用于微服务上,只要有底层原子能力的支撑,也是可以被运用于其他架构上的,只是微服务恰巧提供了这种底层原子能力。
所以,微服务和单元化之间并不是一个包含关系,而是一种加强关系:单元化是微服务架构在宏观架构层面的增强,而微服务是单元化架构在微观机制层面的支撑。
客户该如何选择?
微服务架构相关方案的成熟度高,建设难度和成本都相对较低,建设过程中客户可以更多地关注业务和应用架构的设计,比较适合体量中等和初创的客户。
单元化架构相关方案难度较大,不仅需要产品支持单元化能力同时还需围绕单元化的应用场景做一部分制定化开发。采用这个方案的客户更关注在自主可控能力,避免绑定。建设难度和成本都相对更高,更适合体量较大的客户,或者追求架构先进性的客户。
4.3 单元化架构优势
1. 解决大型分布式系统中集中式数据库的连接数问题
在分布式数据库还未成熟时,应对大型分布式系统中集中式数据库的连接数瓶颈问题而采用的一种处理方式。因为数据库连接数的增长会消耗数据库物理服务器的内存,而对于集中式数据库来讲,单台服务器的物理内存是有上限的。如图4.3.1所示,当分布式系统在进行水平扩容时,集中式数据库便会成为整个系统扩容的瓶颈点。通过采用计算与数据绑定处理的方式,来解决应用在不断扩容时对单一数据库产生的连接数压力。
图4.3.1 应用扩容与数据库连接压力
此问题也可以采用分布式数据库来解决,通过可扩容的proxy层来收敛上层连接,并在数据库内部实现数据库实例的扩容。对于中小客户是一个很好的选择。但也有一些大型银行,如中行、招行、邮储等依然采用了集中式数据库实例来实现其新一代核心系统。他们更关注其自主可控性,通过单元化架构自研实现数据层路由与数据分片能力,这样就不会对分布式数据库产品的特定能力产生依赖。
2.跨数据中心交互的性能与稳定性问题
当微服务系统跨多个数据中心部署时,无状态的应用和路由机制将导致大量的横向流量, 尤其是应用到数据库的访问会被放大数倍。如下图所示,当这在两个数据中心距离超过100公里时,时延问题将被放大,导致系统内部交互出现频繁超时、中断,从而引起一系列系统性问题。单元化的设计思想可以通过计算与数据绑定的方式让流量在单元内部闭环,减少跨单元交互,增加微服务系统的稳定性与性能。
图4.3.2 两种架构对跨中心横向流量的影响
3.标准化扩容与运维容灾问题
每个单元计算容量与所处理的数据量大致相等,可作为统一的扩容单位。避免微服务使用过程中出现随机的扩容与不统一的运维动作。通过提炼不同的单元特征,可定制出针对不同类型单元的标准化运维动作和容灾方案。
4.4 单元化架构的挑战
在《云上核心转型最佳实践》一文中有提到,大型金融核心系统分布式设计时需要考虑的六大要点。其中,有三点与单元化架构设计紧密相关,分别是:数据切分策略、技术架构策略和业务连续性。从这几点可以推导落地单元化时会面临的几大问题:
4.4.1 海量映射关系维护
前面讲到单元化架构主要应用在大型分布式系统中,我们假设目标系统用户约3亿,按照设计要点一拟定如下策略: 1)切分维度:采用客户号作为分片键,即将数据以客户维度放到各单元的数据分片中; 2)分布规则:采用客户号Hash方式分散存储; 3)扩容策略:采用TDSQL自动扩容能力; 4)容量评估:单分片存放500万客户数据,约64个数据分片。
在这个策略前提下,数据分片、路由、扩容、容灾均可交由TDSQL实现,业务侧仅仅需要提供客户号给TDSQL即可。但现实往往并没有这么简单,我们希望通过客户号来串接业务,这样会让架构设计更为简单。可现状是大多数银行系统并没有客户号设计,而是采用客户三要素(姓名、身份证、银行卡号)或其他存折号、汇款号进行交易。所以,有两种方案:关联系统跟着核心做客户号改造,或者在新核心前面做映射关系转换。显然,第二种方案从安全可控角度更具落地性。那么假设一个客户有10个业务要素,3亿客户就有30亿映射关系。好在是相对简单的K,V存储,落地时可以采用缓存集群。较为复杂的点是:任何一个客户做类似开销户的动作,都得及时地、可靠地更新到映射关系缓存中,否则就可能导致后续交易的失败。由于是在核心的入口处发生的映射,其可靠性直接影响着整个核心系统的可用性。
4.4.2 流量打标与标记路由
流量打标是实现单元化的核心能力之一。首先,应用实例在启动时就需要带上单元标记到注册中心注册,其次负载均衡时需要优先按标记过滤服务目录,再执行负载策略。在设计规划阶段,就要设计好单元标签等相关字段,注册中心也需要支持元数据注册能力。通过扩展负载均衡组件来解析遍历约定好的标签来过滤实例。当请求进入网关时,先通过映射缓存找到其所属客户号,再按照客户号进行Hash计算得出其所属分片,进而得到所属单元信息,再以单元号作为标记进行路由,来实现在指定单元内的调用,完成流量在单元内部闭环。
4.4.3 路由一致性
单元化架构的目标是实现流量在一个单元内部闭环,涉及到数据切分是否合理,从业务角度是否能让一次请求在一个数据分片内完成。其次是一次请求中发生多次路由时,能否对同一个客户的路由结果前后保持一致。在技术层面可能存在发生路由的有网关层、数据访问层,还有业务层(比如转账业务:完成当前账号取款后需要对对手账户的单元信息发起存款操作,如果两个客户恰巧没有被分在同一单元)。所以,这三个层面的路由元数据、路由算法都得保持一致。如果数据访问层是由TDSQL实现,那么微服务层面的路由得和TDSQL-Proxy层的路由保持一致。当发生扩容时,TDSQL的分片数也必须和单元数保持一致,才能实现路由元数据的一致。
4.4.4 中间件的单元化
在一次交易过程中,除了微服务框架与数据库,比如会涉及其它中间件。这里需要同步考虑Redis、MQ、任务调度中心的单元化能力。中间件可以采用逻辑隔离,比如Redis可以通过封装客户端使用单元标记进行访问隔离;MQ可以通过把类似Tag的标签能力使用到单元隔离上;任务调度中心则需要先根据客户计算其单元,再根据单元信息发起调度。需要遵循单元标记这个设计逻辑,各组件通过自身的标签能力,或者修改部分逻辑来接入单元化体系。
4.4.5 保障业务连续性
为了实现路由一致性,我们会把缓存映射和路由计算都封装到一个组件中,称为:全局路由组件。当网关层调用全局路由进行计算时,一旦出现任何问题都将影响后续的整个链路。所有和路由相关的操作都需要考虑对应的兜底机制,比如缓存更新失败转异步,又比如寻址失败转随机分发机制等。
在高可用方面除了要考虑实例级、机房级、地域级容灾之外,还需要增加对单元级高可用的设计。并将单元灾备关系及属性在系统上下文中保持传递,确保在任何路由环节都能在当前单元故障时找到容灾单元。
4.4.6 单元化的可观测性
为了更好地维护这套机制,需要在传统监控中加入跨单元和跨机房调用的路由情况。通过采集相关埋点数据,对比分析后做可视化展现。包括将单元化的观测性接入全链路体系中,形成一体化监控。
4.5 腾讯云单元化架构TCUA
腾讯通过参与微众银行、国有大行和头部商业银行等各大核心系统设计,从中归纳提炼形成符合银行核心系统特点的单元化架构体系,TCUA(Tencent Cloud Unitization Architecture)。
图4.5 腾讯云单元化架构(TCUA)
腾讯单元化架构(TCUA)是一种针对金融分布式核心系统技术架构的分层次、分领域、体系化的架构思想:
接入单元(ADU) :Access Deployment Unit ,负责接收流量,识别流量,转发流量。识别后的流量被转发至应用层对应的单元处理。 标准单元(SDU) :Standard Deployment Unit,SDU默认按照客户维度拆分,单客户交易实现单元内闭环处理。跨客户交易会存在一定比例的跨单元协同处理。数据默认被分为64份,被均匀放置在若干个单元内。可通过灰度/旁路机制将指定标签的客户放置在旁路单元实现生产旁路与灰度运行或验证。
本地单元(LDU) :Local Deployment Unit,用于存放无法按客户维度拆分的服务,如:核算、产品定价、机构柜员等。LDU的服务均为单数据中心集群,应用于单数据中心架构。
同城单元(RDU) :Region Deployment Unit,用于存放无法按客户维度拆分的服务,如:核算、产品定价、机构柜员等。RDU的服务均为地域级服务集群,应用于同城多活架构。
全局单元(GDU) :Global Deployment Unit,用于存放无法按客户维度拆分的服务,如:核算、产品定价、机构柜员等。GDU的服务为全国性服务集群,应用于异地多活架构。
旁路单元(BDU) :Bypass Deployment Unit,又称灰度单元。用于生产的旁路或灰度验证,有独立的数据分片,一般用生产测试数据,或指定范围的生产验证(常用于银行内部员工)。
在规划时,需要根据客户实际情况进行选择。除了SDU是必选,其他单元类型均为可选。比如LDU/RDU/GDU,只用选择其中一个到两个。如果客户没有灰度或旁路需求,也就不用规划BDU。单元化的架构体系是用于在进行单元化设计时,从设计框架层面提供指导与参考的作用。
4.5.1 接入层路由设计
接入层架构主要依托于TSF微服务框架Gateway网关实现单元化路由。TSF单元化管理平台(TCUA)中,主要包括了配置单元路由规则、灰度路由规则、标签路由、单元容灾等能力。Gateway通过获取路由规则和元数据对不同单元内的服务进行调用。
图4.5.1 接入层单元化路由
TSF不负责处理业务数据,即上文中提到的客户映射要素。如上图所示,应用厂商需要基于TSF的SPI自行扩展来获取客户号。
4.5.2 数据层路由设计
数据层架构主要依托于TDSQL分布式数据库实现数据层的单元能力。主要包括数据分片、数据路由、自动扩容、容灾切换等能力。
图4.5.2 数据层单元化路由
TSF的网关层路由与TDSQL的Proxy层路由必须保持一致。单元扩容时,在TSF先执行单元扩容规划,其次触发TDSQL分片扩容,完成后同步更新TCUA中的路由元数据,实现整体路由一致性。
4.5.3 应用层路由设计
应用层路由设计主要依托于TSF-Feign实现就近调用与跨单元调用。同样,业务在调用Feign接口时需要传入客户号,Feign与Gateway一样到单元化平台TCUA获得路由规则和元数据后,对目标单元发起调用,从而实现与网关和数据层的路由一致性。
图4.5.3 应用层单元化路由
4.5.4 MQ单元化设计
MQ的路由单元化能力主要依托于各产品自身的Tag原子能力。在TDMQ中,单独为单元化设计了一个独立的标记。消息需要在消息头中设置对应单元标记,默认为本单元标记,来实现单元内外的消息投递与消费。
图4.5.4 MQ单元化消息
如果目标单元不是本单元,则TDMQ-Router组件会识别并将消息复制到目标单元,由对方单元的Comsumer进行消费。和使用普通MQ一样,业务侧需要具备消息防重或接口幂等的设计。
4.5.5 灰度(旁路)单元设计
灰度单元的本质是"特殊的路由规则",即在一般的单元规则之前,优先检查"灰度单元规则"。举例:我们约定所有本行的行员为灰度群体,将其存入灰度表,那么请求中的客户号只要命中灰度表,就触发到灰度单元的路由。一旦执行灰度规则,则不再进行一般的单元路由规则。在TSF中,对灰度单元的管理有独立的规则配置。
图4.5.5 灰度单元通用方案
需要注意的是,灰度单元需要业务提前规划灰度维度和灰度方式,提前做好数据迁移。同时,应用层还应具备客户锁定能力,在数据迁移时锁定客户,不允许其进行业务交易。在迁移完成后,更新TCUA路由信息成功后,再接触锁定。保障前后的业务一致性。
4.5.6 单元扩容设计
单元扩容,也叫单元分裂过程,由一个单元变为两个单元。核心点是总分片数(数据分片)不变,单元和分片之间是映射关系,一个单元包含若干分片。
如下图所示,总分片数为64,假设初始4个单元,每个单元各16个分片,分布在AB两个数据中心。扩容到二阶段时,单元数量增加到8,单元内分片数量缩减到8,同时还新增了两个数据中心C和D。分为8个单元后,遵循开闭原则,原来1-4单元和数据中心的映射关系保持不变,只增加新增单元与新数据中心的映射关系。
图4.5.6 单元扩容逻辑
4.5.7 单元容灾设计
在TCUA单元管理平台中配置"容灾单元",来建立两个单元间的容灾关系。当其中一方单元出现故障时,通过更新故障单元状态来识别并指向其容灾单元ID,从而实现路由的调整。代表容灾关系,连接了两个互为备份的单元。
图4.5.7 单元容灾逻辑
容灾关系的配置,与扩容关系一样,建议在设计之初就做好规划,尽量减少关系的变更,近对新增的单元做容灾关系配置,对存量单元关系保持不动。便于简化运维管理,减低变更成本和故障率。
4.5.8 全局单元化架构
以上几点是TCUA对于单个系统单元化设计要点,其改善了单个系统内部跨多中心后的无效横向流量的治理。但在实际场景中,一次交易是先从渠道系统进入中台系统,再进到核心系统。如果仅仅是核心系统做了单元化改造,从整体链路上其效果并非最优,跨系统调用时一样会出现随机和无序的流量。为了解决系统间流量治理问题,TCUA提出了全局单元化概念。
在原来某国有大行的架构中,单元的概念小于系统,一个系统可以被拆分为多个单元,这是大行目前主流的单元化落地形式。而此次在四川省某商业银行的单元化架构中,TSF首次将全局单元的概念落地。将单元提升到全局维度,用单元来包含系统。可以实现全行级端到端的单元化能力,用来解决系统间调用的跨中心流量治理问题。
图4.5.8 全局单元化概念
全局单元化架构对业务特征有一定要求:进行全局单元化改造的系统,需要保持同样的数据分片维度、同等的单元数量、采用全局统一路由算法。比如:核心系统采用客户号维度切分,共分了8个单元,采用Hash散列计算路由。那么其它渠道系统、中台系统是否也符合这种策略是需要调研的。有一些管理类、分析类系统就无法按照此模式设计,像这类系统通常也不在关键交易链路中,可以放到RDU中部署。
标准微服务方案中,技术能力更多采用产品来实现,在技术路线选择上没有单元化方案丰富。但由于方案成熟度高,建设难度和成本都相 对较低,建设过程中更多关注业务和应用架构的设计,比较适合体量一般的银行。
单元化方案中,技术能力多采用自研+产品标准能力实现,更关注自主可控,尽可能不去依赖产品自身能力,避免绑定。建设难度和成本 都相对更高,更适合体量较大的银行,以及有多活架构规划或追求同业架构先进性的银行。
单元化是微服务架构的强化,两者在核心六大设计要点上存在一些差异,主要集中在数据切分、扩容与路由、交易处理机制、灰度实现机 制等能力的实现方式上。