
2019年秋天的一个晚上,我在某股份制银行总部的会议室中做分布式银行系统架构的研讨,会议室中除了银行方负责技术的领导,还有几个阿里的P8和P7。我们针对两个技术专题已经讨论了一整天,大家已经非常疲倦。会议室突然安静了下来,这时,银行领导突然感叹道:难道我们只能“摸着石头过河”吗?
这个问题当时我们不知道如何作答,只能感受到领导心里沉甸甸的压力,还有对新技术的陌生感,以及对未知问题的忧虑。现在4年多时间过去了,我也做了4个银行核心系统,其中有分布式的、有单元化的,也有云原生的。不少银行已经完成分布式、单元化系统建设,也有很多银行正在做云原生转型。现在我们已经探索出分布式、单元化,以及云原生的完整技术方案,以及沉淀了一大批技术产品。
本文我将对分布式、单元化、云原生架构中的主要技术产品逐一剖析,对于没有单元化及云原生核心实践经验的读者,本文也许能成为您跨越“信创大河”的垫脚石。对于有实践经验的读者,我姑且抛砖引玉。
01
分布式、单元化其实是必由之路?
大约自2017年开始,国内中小银行开始铺开JAVA银行核心的建设,这时采用服务注册发现机制JAVA银行核心开始号称为分布式银行核心。随后大行业逐渐建设分布式核心,由于数据量较大,不得不模仿支付宝的单元化架构。在客户数据量达到亿级的时候,IBM的小型机处理起来的确很吃力,而大型机则过于昂贵。“堆x86或RAM服务器”成为了大家不约而同的选择,支付宝率先遇到海量数据问题,所以它先探索出解决单元化解决方案。
还记得2016年底我们上线贵州农信核心系统,客户量是7千万,数据库服务器采用IBM的两台E880服务器,配置是80核1T内存。2018年初我们上线河北农信,客户量是1个亿,数据库服务器也是采用两台E880服务器,配置是88核1T内存。这样的小型机在国内当时已经是顶配了,我们还是非常担心无法支撑系统上线,经过程序的大量调优后才上线的。对于农信尚且如此,对于国有大行和股份制银行其实是很难支撑的,所以说单元化架构也是大型银行必然的选择。
另外,银行的老机房一般是建设在市中心地段,所在区域的房价和地价太高,不宜在原地址扩建机房,必须在其他地方建立新机房。单元化架构正好能协调两个机房的流量,这也是单元化架构被选择的必然原因。
02
单元化、云原生架构是空穴来风?
技术风潮从来都不是空穴来风。最初,我以为单元化这个词是英文翻译过来的,加入阿里之后才发现是我们团队前辈创造的。为了打造技术话语权,占领技术高地,引领技术风潮,最终售卖技术服务和产品。顶尖的布道者们每个周会都会讨论技术方向、技术方案,以及技术名词,他们是就是风的起点。
单元化架构的推广离不开布道者的努力,云原生架构的成熟也离不开云厂商的大力宣传。无论是布道还是商业宣传,无疑都大大推动了国内IT技术发展。但是,靠跟风很难做好大型IT系统设计,大型IT系统建设周期和使用周期都很长,一般长达十多年。在十多年间互联网巨头的宣传日新月异,其战略可能发生了巨大调整。犹记得两年前某互联网巨头大力进军银行核心系统,现在已经解散团队、战略收缩,这给正在实施其核心系统的银行带来不少麻烦。
本文尽量阐述清楚相关技术的来龙去脉及其本质,使我们能在纷繁复杂的商业宣传与布道中认清技术方向、去伪存真,做好大型IT系统的技术选型和规划。
03
皇冠上的明珠
阿里的一位老领导曾说:“如果金融系统是IT业的皇冠,那么银行核心系统则是皇冠上的明珠”。银行核心的技术架构是最为规范的,其对技术组件的技术要求也是最为严苛的,本文主要剖析银行核心的架构和组件,期望管中窥豹,看到技术发展的一些脉络。云原生架构分为IaaS、PaaS、SaaS三层,其中IaaS为基础资源层,PaaS为中间件、开发运行运维组件层,SaaS为应用层,最近两年在PaaS层与SaaS层中间出现了aPaaS层。
04
IaaS层
长治久安之道
对于私有云来说IaaS层本质是计算、存储、网络的虚拟化管理,公共云的IaaS则是使用这种虚拟化管理方式向大众提供共享计算服务。两者有本质区别,公共云重点采购便捷灵活、’初期成本低,私有云讲究融入企业IT管理现状中,企业人员方便好用。对于大型企业来说,采用云来对整个企业的IT资源进行管理,能大幅度提升资源利用率,这的确是一种不错的选择。目前需要大量算力的应用只有数据处理、风控、客服等,未来随着人工智能应用的普及大型企业对算力的需求会越来越高,采用私有云来对算力进行动态管理和分配是必由之路。
大型企业绝不能把希望寄托在公共云上,这无异于假焉托质。首先是数据在生产运营中的重要性越来越高,未来数据安全将等同于企业的命脉;其次是公有云的水位一般都在90%以上,发达地区Region的水位还会更高。目前上海地区使用公有云的部分大型企业都不得不提前采购一些ECS,以备业务高峰期使用,所以按需采用节约成本也是不成立的。从长期来看,大型企业建立自己的私有云平台,才是长治久安的战略。
量体裁衣自建云
国内IaaS做得好的厂商有华为、阿里、腾讯,其中阿里是最早研发云的厂商,其技术体系较成熟,但也比较老。华为和腾讯是基于OpenStack进行深度二开实现的,技术较新,也是比较主流的实现方式。近两年基于OpenStack二开的云厂商如雨后春笋在国内蓬勃发展,这体现云的门槛已经没有几年前那么高,稍微大一点的企业完全可以基于OpenStack构建自己的私有云。
OpenStack是一系列IT资源管理的开源软件组合而成。其主要组成部分有负责计算资源管理的Nova、负责对象存储管理的Swift、负责块存储管理的Cinder,以及负责网络的Neutron。
简单的来看,云就是对计算、存储、网络的管理。在计算方面OpenStack采用的是Nova进行管理,其负责虚拟机创建、开机、关机、挂起、暂停、调整、迁移、重启、销毁等操作,以及配置CPU、内存等信息规格。真正对物理机做虚拟化(VM)的组件是hypervisor。相当于Nova负责调度hypervisor生成虚拟机,并管理虚拟机。
在云上要支持动态的扩缩容,容器里的本地磁盘是随时可能被释放的,所以必须有专门的存储管理软件。OpenStack支持对象存储和块存储,对象存储是一种扁平化和离散化管理文件的方式,简单的看就是把文件拆分成多份,分散到各物理存储中存放,以提升读写速率,并能实现备份。由于是采用扁平化的管理结构,文件查找效率也远高于块存储。云上的块存储类似于传统的本地磁盘存储,采用树状的文件目录管理模式,通常挂载为云服务器的本地盘。
云上的网络是虚拟网络,简单的理解就是利用网络传输软件对物理路由和交换机传入传出的数据进行包头解析,根据包头信息发送到相应的目标服务器上去。相当于在物理网络包头的基础上封装一段软件可以解析的报文头,用该报文头来实现虚拟网络层的数据包传输。这样就能用软件控制网络传输,通过复杂的控制可以模拟出一个虚拟的网络(VPC)。OpenStack是采用Neutron实现的虚拟网络传输,它的功能比较简单,没有较全面的模拟物理网络,目前比较成熟的开源虚拟网络传输软件是Overlay。国内不少云厂商的虚拟路由和虚拟交换机都是基于这个款开源软件打造的。用软件定义路由器和交换机后,就使得在云上部署复杂的软件系统集群,甚至是部署整个机房得以实现。不过,虚拟网络在物理层数据传输是不隔离的,数据传输的安全性是需要重点关注的。
OpenStack还有身份服务Keystone、镜像服务Glance、测量服务Metering、部署编排Heat、数据库服务Trove。本文就不再一一列举,以便重点分享我愚钝的见解和有限的经验。
私有云本质上是一种企业IT资源管理方式,上述的IaaS组件其实是企业IT物理资源管理的工具。在使用这些组件时一定要无缝对接企业自己的管理系统,把企业的日常IT管理架融入云中。只有“量体裁衣”建立私有云,才能让云提升企业的管理和运营效率,才是成功的云原生转型。
05
PaaS层
PaaS发展的三个阶段。
第一阶段、利用云便捷的建立技术组件实例
应用的运行环境从物理机到虚拟机再到容器,支持应用运行的技术组件也逐渐增多,从最初的一个weblogic全部搞定,到现在的统一网关、消息队列、分布式事务、分布式缓存、内存级缓存、数据库中间等等。随着云技术的发展,各种技术组件被云厂商封装成技术能力在云上呈现和售卖,从而形成的云原生架构中的PaaS层。
PaaS借用IaaS层对物理资源的管理能力,对应用提供便捷的技术能力。例如以前我们项目中若使用到MQ需要在物理机或虚拟机中手工搭建一个MQ环境。在PaaS中只需要点击一个按钮能获得一个MQ环境,其他技术组件亦是如此,这极大的提高了效率,减低了时间成本。
第二阶段、采用平台统一管理技术组件
人们对效率的追求是永无止境的,人心总是难以满足,这是人的本性,也是技术发展的原始动力。近些年随着各种技术组件越来越多,各大云厂商对PaaS技术组件进步进行了集成,形成了更便捷的应用运行平台,他们把各种技术中间件、监控运维组件等集成在一个统一的运行平台上,让应用只需连接到统一运行平台上,就能使用平台上的所有中间件,省去了大量中间件和运维监控组件的适配调试工作。阿里的SofaStack、腾讯的TSF、aws的BeanStalk就是目前典型的统一运行平台。
第三阶段、新增aPaaS层,进一步降低业务开发的复杂度
随着低代码或零代码开发的思想逐渐成熟,云厂商和国内IT服务提供商们发现还能进一步封装和集成通用的技术能力,进一步减低业务开发的复杂度。于是逐渐产生了aPaaS的概念,aPaaS基于PaaS能力进一步集成并且新增服务编排、批量调度、参数缓存、分布式序列、热点资源、对外供数等组件,以及其他辅助业务逻辑实现的技术组件。形成了国内具有特色的大型IT系统开发、运行、维运体系,这些aPaaS组件也许会成为未来10年国内大型IT系统建设的基石。
注册中心
注册中心本质上是一个服务列表管理组件。在注册中心普及之前服务集群采用负载均衡进行负载和调度,负载均衡分为硬负载和软负载。金融系统对性能和稳定性要求较高而且预算充足,一般采用硬负载,反之则采用软负载。
2015年~2017年期间,分布式、微服务架构在国内金融领域应用的初期,有些银行甚至提出把服务注册发现机制做到硬负载中去,现在看来是很荒谬,但它体现了注册中心和负载均衡功能重叠的问题。二者都管理服务列表,只是管理方式不一样。负载均衡的服务列表需要手工配置,注册中心的服务列表是自动注册的。其次交易流量不过注册中心服务端,而会经过负载均衡。
简单的说,注册中心是应用启动时把服务注册到其服务端的服务列表,并且同步到消费端的内存中,同时保存一份本地文件。在调用服务的时候直接从内存的服务列表中挑一个服务进行调用。从这个角度来看,我们其实还可以把其他种类控制系统运行的信息推到本地内存中,从而创造其他技术组件,例如我们把业务参数推送到应用系统内存中,从而创造了后文介绍的“缓存同步”。
注册中心有满足ACP理论中的AP和CP两种,目前对性能要求较高的都选满足AP的注册中心。注册中心的功能一般有服务注册、服务发现、服务注销、心跳探活、服务订阅、服务查询、服务修改等。在单元化架构下注册中心需要支持单元间注册信息同步,大部分开源注册中心是不支持的。单元间服务切换,开源注册中心也不支持,例如实现当本单元的某个服务存活量低于百分之多少时,流量切换到备单元。另外,一个企业级注册中心,一定要跟企业的运维监控平台打通,这要求注册中心必须提供服务查询、服务修改、服务注销等接口,以便于运维管理集成,获得企业级的服务管理能力。
最早的注册中心通常是注册服务接口,这种注册方式很难实现企业级注册中心,因为大型企业的服务接口达到几万甚至十万个,这个量级的服务注册和发现存在效率问题。这些年大家逐渐采用IP和端口的方式注册应用实例,这种注册方式才可以满足大型企业几十万服务接口的注册发现。在性能方面除了服务注册发现的规模和效率,同时启动进行注册的节点数量也是重要的考量点,极端情况下的大规模启动会考验这个性能点。
配置中心
配置中心和注册中心本质是一样的技术组件。当配置信息是服务列表,由服务启动的时发送通讯进行配置,配置参数消费逻辑改为服务发现逻辑,配置中心则变成注册中心。开源的配置中心只是一个demo级的参数管理组件而已,其只能管理key-value类型的参数,多参数间的关系没法管理,多参数组合的版本也没法管理,多消费节点间的参数一致性也没有保证。
大型复杂系统的业务参数是按版本发布的,每个版本中有大量参数,业务参数的管理和下发开源配置中心无能为力。随着分布式、单元化系统的普及,大型系统的技术参数越来越复杂,在用配置中心下发参数的时候经常遇到下发不及时、每个节点使用的参数版本不一致、复杂的json参数可读性和可维护性差等问题。在下文中我们自研的参数缓存同步组件已经解决这些问题。
开源的配置中心在大型IT系统中使用时存在着不少问题,但我们为什么还把它奉若神器。原因之一是很多人研究源码但没有研究原理;其二是不重复造轮子的风气盛行(什么情况不用造,什么情况需要造,在下文将进行论述);其三是国内的IT技术始终在跟风国际,没有形成完善的理论体系和产研生态体系。
配置中心一般有配置模板管理、配置值管理、配置订阅、配置拉取、配置自动推送、配置手动下发等功能。有的配置中心也支持灰度发布,即配置手动下发时指定单元下发和指定IP和端口下发。企业级的配置中心需要支持多环境多应用管理,以及环境间的参数导入导出。配置中心应提供参数管理接口,以便运维系统集成,让运维系统实现可监可管。形成类似于军事领域的查打一体的能力,如此才能快速处理系统故障。
在性能方面,企业级配置中心至少要支持一万个参数以上的配置,同时要支撑几千个节点拉取参数,参数下发的时效性也不能太长,在实际项目中我们经常发现开源配置中心下发参数太慢,而且没有下发任务进度管理,导致修改参数后无法知道参数是否已经生效,这对紧急问题处理非常不利。
MQ消息队列
系统间的通讯一般有同步、异步、文件批量。异步交易主要是用消息队列实现,也可以用其他方式实现,例如传统银行核心采用数据库记录实现异步处理。在单元化架构下,分布式消息组件需要在传统消息系组件进行一定的封装,才能为开发人员提供更简洁的消息队列使用方式。例如实现可靠消息机制、分布式事务消息机制,以及提供多单元、多应用、多环境管理能力、消息交易的路由分发能力。
消息队列通常的功能有Topic管理(包括Topic的新增、修改、删除、查找)、消息查询、消息订阅关系查询、手动消息发送等。还有消息重新投递及设定消息重试投递次数、设置队列深度,以及消息类交易的链路跟踪。为了防止极端情况下消息丢失,在金融场景中通常会对消息进行落库,以便对消息内容进行查询、重新处理、存档。
在监控运维方面,开源的消息队列组件是比较弱的。企业级消息队列直接使用开源消息队列的demo级管理界面显然是不够的。未来的系统重在一体化的运维管控,监和控一体的系统管理,这要求消息队列提供一系列的查询和控制接口。
在性能方面,消息的投递耗时主要在于网络速度和消息体的大小,消息组件自身耗时通常低于1毫秒。消息消费的速度与队列深度有关,队列深度一般不设置太深,就能确保消息获取的速度小于1毫秒。
Redis缓存
Redis 从2024年3月21日开始“不再开源”。其宣布从 Redis 7.4 版本开始,Redis 将采用 SSPLv1 和 RSALv2 双重许可证,这种许可下托管 Redis 产品的服务提供商将不再允许免费使用 Redis 的源代码。这件事现在对很多云服务提供商产生影响,更深层次的影响是其他开源软件也有可能随时“闭源”。如何完成“自主可控”这个课题?这个事件又给我们敲了一记警钟。
各种中间件,本质上只是辅助我们完成业务逻辑开发的组件,有这些中间件我们能更标准、更便捷的使用各种技术能力,所以只要我们分析透彻各中间件的能力,完全可以自主开发出各种中间。这就是我在文中明确定义和分析各组件功能及性能的意图,接下来我们详细分析一下Redis的功能。
Redis其实是一个很鸡肋的中间件。在分布式单元化的大型IT系统中,一般有几千个JVM节点,每个节点都去访问Redis缓存,其压力显然是很大的,它不适合在大型IT系统当做缓存组件使用。而且Redis在同城双活架构中无法实现双活,缓存刷新也需要根据业务系统情况写代码进行控制。再则,把缓存放在Redis中,必须通过网络去获取,在跨机房访问场景下需要1~2毫秒,在耗时上完全失去了缓存的高效性。其实它只是在小型系统中使用得较多,例如简单的锁场景、简单的抢购场景、简单的技术参数或业务数据缓存场景。
在银行核心系统中,我们一般都不会直接使用Redis。我们在银行核心系统中一般使用自研的参数缓存同步组件,把缓存直接推送到JVM的内存中去,实现微秒级的缓存获取能力。
目前的中间件是近10年互联网技术发展过程中,前人在解决问题过程中沉淀下来的技术组件,我们在解决我们自己遇到的新问题时,也一定会沉淀一批技术组件。特别是在微服务化、单元化、云原生架构下,我们遇到的问题是10年前的中间无法解决的。其实,在国内银行核心建设过程中已经沉淀了大量新的“中间件”,但因下文中提到的一些原因并没有开源出来。Redis已经是10年前的产物,而且在两地三中心和多地多中心架构下问题频出,性能受网络限制并不高。我们为什么还会奉若神器?也许是人总善于崇拜,不善于创造。
Redis的闭源事件,更多的是警示,它不会影响我们解决现在和未来的技术问题。它警示我们要打破现有软件资产管理方式,创造商业软件开源环境和生态。尽快在国内源码管理网站,用我们自己的协议开源一批我们自己的中间件,形成产品级开源软件生态体系。
负载均衡
在系统中能形成负载能力的有很多组件,一般大家讲的负载均衡是F5,nginx,SLB等。实际上网关、服务编排、注册中心等组件进行服务外调的时候,在服务列表中根据算法选择某个服务进行调用,这过程也能形成负载均衡效果。
在分布式架构流行之前,应用集群部署主要靠负载均衡来分发流量,集群的全部流量都经过负载均衡,使其变成了架构中的‘单点’,该点出现故障全系统都会瘫痪。在之后的分布式架构中,采用服务注册发现的方式,通过下发服务列表到消费端,使消费端与服务端直接进行点对点通讯,避免了流量集中经过负载均衡的情况。
负载均衡除了有能按IP和端口转发流量的四层负载均衡,还有能按报文内容转发流量的七层负载均衡,四层负载均衡转发逻辑简单,流量转发效率较高,通常可以作为机房级或大型IT系统入口级负载均衡。七层负载均衡通常需要解析报文,才能根据报文要素进行流量转发,其处理逻辑复杂,流量转发效率低,通常用于小型微服务架构系统进行流量分发,在公共云上的小型互联网系统常用七层负载均衡。
总之,七层负载均衡看似灵活强大,实则复杂低效。实际项目中,很多架构师总是喜欢灵活强大的组件,抱着既要又要还要的态度,把系统做得极其复杂。其不知架构之道在于平衡,大型IT系统的架构,重在稳定可靠。
在云原生架构中,网关前面一般由负载均衡GSLB(Global Server Load Balancer)接入流量转发到网关集群。其功能一般有监听配置、后端服务信息配置、心跳探活、顺序循环轮询、加权轮询、一致性哈希、会话保持等。通常四层和七层负载均衡都支持,四层的TCP协议的负载均衡,即根据IP和端口做负载均衡,七层的HTTP和HTTPS协议的负载均衡,即根据报文信息进行负载均衡。
负载均衡是最重要的流量管控组件,也是服务治理的关键节点。有的人认为服务治理可以用一个产品来实现,实则不然。我见到某公司的一个团队花了两年时间做服务治理产品,目前为止还没做出可用的产品。根本原因是服务治理不是一个产品,是一系列的规则和理念。需要全系统甚至全企业的各种技术组件配合完成,服务治理的主角其实是监控运维系统,负载均衡为监控运维系统提供流量控制规则的配置接口,监控运维系统根据监控情况自动或手动调整流量分发规则,才能保障系统长期稳定运行。
在性能方面,四层负载均衡耗时通常在1毫秒内,七层负载均衡则一般需要5毫秒左右。四层负载均衡集群最大可以支持连接数达10万以上,新建连接数 (CPS)达一万以上,每秒查询数 (QPS)达十万以上;七层负载效率则低很多,同样运行资源的情况下,可达到的最大性能指标几乎是四层负载均衡的十分之一。
分布式事务
分布式事务和服务编排有着密不可分的集成关系。某国内互联网巨头的服务编排产品最初没有分布式事务管理,分布式事务管理需要在分布式事务产品中再配置一遍服务流程。我当时给了他们一套分布式事务管理方案,并建议他们直接把分布式事务集成到流程编排中。无论是可视化服务编排,还是硬编码服务编排,只要调用远程服务就需要分布式事务组件管理分布式事务,服务编排可以根据远程调用服务是否为非查询交易,自动开启分布式事务的子事务,再根据交易最终状态调用分布式事务的回滚或提交,如此则实现分布式事务的自动管理。
目前,分布式事务必须跟服务编排结合已基本形成共识,但采用哪种分布式事务还存在分歧。分布式事务有XA、AT、SAGA、TCC模式,XA模式性能太低在大型系统中鲜有采用,AT模式在银行核心系统的自动冲正有采用,但由于它需要登记SQL语句执行的前后值,性能也不高,所以只在对性能要求不高的交易的自动冲正中使用。SAGA和TCC是在大型系统中采用得比较多的,其中建设银行、中国银行、邮储银行、民生银行等银行核心采用的是SAGA模式,支付宝、平安银行、四川农信等采用的是TCC模式,大家从采用这两种模式的使用方应该就能感受到两种模式的优劣。
SAGA采用DO和UNDO一对效果相反的接口,服务编排中的每个节点都先执行DO接口,如果全部执行成功则交易成功返回,如果有某个节点执行失败则交易返回失败,然后异步逆序逐个调用UNDO接口,把所有成功的交易都撤销回原来状态,形成没有做过该笔交易的样子,实现事务的最终一致性。
从SAGA的事务管理过程不难看到,它是没有隔离性的,也就是交易还没有最终成功前,部分交易结果已经对外暴露,可以被其他交易修改。如果交易失败需要回滚,则可能回滚失败。不过,这种隔离性问题在具体的场景中是可以规避的,例如在银行的转账场景中,可以采用先转出后转入的方式避免银行资损。多借多贷交易中也可以对金额增加方做部分冻结,最后统一解冻的方式规避事务隔离性问。除了个别场景,大部分场景采用SAGA事务是没有隔离性问题的。
TCC采用Try、Confirm、Rollback三个接口分别实现预留资源、确认资源、回滚资源三个操作。服务编排执行所有节点的Try接口,当全部执行成功时交易返回成功,异步调起所有节点的Confirm接口,对所有资源进行确认。当服务编排中的某个节点执行失败,则交易返回失败,异步调起所有节点的Rollback接口,把所有资源都回滚回去,实现事务的最终一致性。
相对SAGA事务模式TCC事务模式较为复杂,为了隔离性其设计了中间态,在实际的交易开发时中间态不容易界定,并且有些场景是不宜设置中间态的。例如登记明细,不宜登记一条中间状态记录然后再修改为确定态,因为明细表的更新效率很低。另外,在实际使用中,对TCC理解不到位的架构师总喜欢把业务逻辑放到Confirm阶段执行,因为这样比较方便,但实际上Confirm阶段只能技术性的确认资源,不能做业务逻辑处理。如果选用TCC,又因很多操作难以抽象成TCC模型,只能使用SAGA,这意味着选择TCC模型也必须有SAGA模型,这导致系统变成一个混合事务模型,事务管理极其复杂。再加上TCC的二阶段需要大量的一阶段信息,这种信息的传递和存储对系统的开销很高。
不少架构师潜意识中喜欢功能齐全、复杂的产品,只有实战经验充足的架构师才会有意识的避免复杂的设计,在功能上去做取舍。从使用案例上来看,大型银行都使用SAGA,因为它相对简单,简单意味着明确,也意味着可靠。事务组件需要在非常复杂的场景下使用,给使用方提供一个简单明确的事务规则至关重要。
不重复造轮子是个伪命题。
我为大型IT系统招聘人员的时候,如果是互联网IT架构背景的人,我一般都要给他讲“造轮子”的道理。目前大部分PaaS层组件基本上是国内互联网大厂用开源软件改造的。互联网技术界流传着一句话:“不重复造轮子”,这几乎成为了所有互联网软件架构师的“圣经”。前几年互联网2.0在蓬勃发展,互联网公司采用的是丛林法则,讲究的是快速做出能挣钱的产品,砍掉赔钱的产品,其大部分IT系统的生命周期很短。然而大型IT系统的生命周期都是10年左右。当我们做一个生命周期较长的大型IT系统时,我们还是拿“开源的轮子”拼凑吗?是利用开源深度改造成本高,还是根据技术原理和自身需求进行开发成本高?在大型IT系统生命周期内“开源的轮子”如何更新升级和修复BUG,它闭源了怎么办?这些问题都是值得仔细评估的,而不是一句“不重复造轮子”就能定论的。
每个大型企业都有自己的IT历史、有自己的IT沉淀、有自己的IT规范、有自己的管理规范、有自己的团队分工。这些是企业的历史渊源,部分是企业的包袱,部分是企业的资产和骄傲。“开源的轮子”要想完美的架在每一个大型企业下,是不可能的。所以很多大型企业在建大型IT系统的时候尽量都不直接使用“开源的轮子”,他们会根据自身需要新造轮子或深度改造“开源的轮子”,通常会请大量外包人员帮自己造轮子。 帮大型企业造轮子是个“苦力活”,互联网巨头们并不愿意做这种生意,他们愿意做的是那种没有边际成本、可以无限复制的标品售卖,至于需要定制的部分交给合作伙伴吧。无论是开源组织、还是有标准产品的大厂,他们都会告诉我们不要重复造轮子,直接使用他们的“轮子”。作为“轮子”使用方自然不能人云亦云,需要根据企业现状和未来规划判定轮子是否合适。对于生命周期较长的大型IT系统,需要根据未来的运维和运营需要来决定是否要“量体裁衣造轮子”。
其实国内银行核心系统在建设过程中,各软件服务商已经沉淀了一套能提升业务逻辑开发和运行效率的aPaaS层和工具链体系,这些基本上是他们自己造的“轮子”。这些软件若开源出来,国内也许能形成独立完整的软件开发、运行及运维体系。但这些都是商业化产品,而非开源的demo级软件,这些产品的开源有诸多困难。最大的问题是商业资产外流,如果是国企央企还会涉及国有资产流失问题。其次是国内没有形成完善的版权机制和共识,开源软件的盈利模式没有形成。再次,是产品级的技术组件比demo级的开源组件重很多,绑定了很多特定的应用场景,这不利于其开源推广使用。只有把这些问题解决了,国内才能形成一套面向当前问题和未来发展的技术组件体系。
06
aPaaS层
当下主要的PaaS组件其实是10年前的技术产物,在单元化、云原生的架构体系下,直接用PaaS层的技术组件开发应用服务,会产生一系列问题:
业务参数如何同步到各单元、各节点中?
日益突出的热点问题该如何处理?
按单元拆分的数据如何保证时效的聚合?看似可以使用大数据技术,实则不然。
全局唯一且趋势递增的序号如何获取?
如何让交易按数据分布进行路由?
按微服务拆分业务逻辑后,如何快速编排实现完整的联机交易和批量交易?
如何便捷的实现文件批转联机交易?
如何做联机交易、消息交易、文件交易的协议和格式转换?
上述问题是近10年来国内外互联网技术中间件并没有解决的问题,我们在实际项目建设中需要补充一系列技术组件来解决这些问题。
参数缓存同步
集中式系统逐渐的进行了分布式、单元化改造,以前的一个大系统拆分成了很多小系统,每个小系统都采用集群化部署,这使得运行的节点数量增加了十几倍甚至几十倍。以往的参数获取方式在分布式系统中会导致数据库连接不够,并且获取速度较慢,于是“参数缓存同步平台”应运而生。与10多年前国外创造Redis的原因一样,我们也在解决遇到的问题过程中沉淀出我们的技术组件。
大型系统的交易控制较为复杂,产品、费用、利率等参数很多,交易中使用这些参数的频率也非常高。如果把这些参数存放在数据库中,到数据库中查询这些参数的总耗时会非常大,即使把这些参数放置在Redis缓存中,访问参数需要经过网络,效率依然不高。唯有将参数直接推送到每个应用节点的内存中,才是效率最高的参数获取方式。
在大型系统中,业务参数通常是按版本发布的,所有开源的参数同步产品都无法按版本把参数同步到本地内存中。部分系统为了提高性能把参数已经加载到内存中,但参数的版本管理、内存参数查看、内存参数核对等配套功能没有实现,导致内存中的参数是看不见的黑盒,发生问题时“两眼一抹黑”。
很多人喜欢把系统的各种缓存混为一谈,总是在全局缓存中加入交易级缓存,在交易级缓存中考虑如何实现全局缓存。分布式系统中分为全局缓存、交易级缓存,交易级缓存又分为组合交易缓存和基础交易缓存。组合交易缓存是跨远程调用的,其缓存需要在远程节点间用返回报文和请求报文传递,即联机引擎自动把缓存内容封装在上一个节点的返回报文中,在下一个节点通过请求报文传入,自动解析到内存中,从而实现上一个远程节点的缓内容传递到下一个节点的缓存中。基础交易的缓存相对简单,只需在程序中借助ThreadLocal实现。
参数缓存同只针对全局缓存,主要实现需要按版本管理的业务参数的全局缓存。如果多个技术参数也需要按版本发布,开源的配置中心是难以实现的,这时也可以用参数缓存同步。参数缓存同步的功能有缓存查询、缓存加载、缓存更新、缓存同步、缓存核对、缓存版本管理、缓存版本回滚等。支持版本管理,包括按版本发布、按版本回退、按版本核对缓存信息。还支持参数缓存的灰度发布,即指定IP端口的发布。为了实现贯彻监和控一体化的理念,参数缓存同步提供缓存查询、核对、手工刷新接口,以便运维管控平台集成。
应用系统集成参数缓存同步的SDK之后可以在内存中便捷的查询参数表。其通过拦截DAO层,根据配置自动判断是否从内存中查询,使业务程序能无任何改动的方式从查询数据库表变成查询内存表,实现无侵入接入缓存。在查询缓存的SDK中其建立了一套完善的索引机制,能实现参数查询只需0.02ms的极致性能。
分布式序列
2015年阿里提出去“IOE”,其中的O是指Oracle数据库。喊去掉Oracle数据库的口号简单,实则需要付出巨大代价,必须创造一个分布式序列生成组件是代价之一。
在单元化架构中获取全局唯一且递增的序号并不容易,在Oracle数据库中获取序列比较简单,调用一个数据库函数即可,然而在单元化架构下需要用一个序列生成组件进行产生序列号。其主要原因是去Oracle数据库后国产数据库没有那么高性能的序列生成能力。个别国产数据库的Proxy有序列生成能力,但高并发下效率低,而且偶尔会重复;其次,单元化系统的吞吐量一般大于集中式系统,需要的序号生成能力也是大于原来集中式的,这加大了序号生成的难度。所以分布式序列应运而生,也可以说是在新架构下为了解决新问题,我们不得不创造这个技术组件。
分布式序列组件一般分为序号生产端和序号消费端,消费端一般以SDK方式提供给相应微服务依赖,服务端根据序列配置的起始值和终止值、步长、前缀、后缀、中缀等信息成批生成序号放在缓存中。消费端每次来服务端获取一小批,保存在消费端的缓存中,应用程序使用的时候实际上是从内存中获取序号。
分布式序列的功能一般有序列号规则定义,序列号生成,生产端序列号缓存、消费端序号缓存,序列号回收,序列号监控,序列号管理,还有按日生成序号。有的序列产品甚至支持自选号、吉祥号。在序号生成场景中,有的序号只要求全局唯一,并不要求递增,这时候可以直接采用sdk生成雪花算法或UUID。其中雪花算法的使用节点数大于1000时,其workid则需要进行统一分配,才能为随机数保留足够的位数,降低序号重复的概率。
在个别对高可用要求较高的序列产品中,还提供按单元生成序号的能力,从而实现了序列的分布式生成能力。不过,这种能力需要修改老系统的序号规则,在序号中加入单元号。在要求‘对外无感’的项目建设中不能采用这种序列生成能力。
为了提升效率,在我们的产品中服务端采用双队列缓存,消费端采用多队列缓存,这样的设计能让序列获取耗时降到零点几毫秒,比Oracle数据库获取序列快十多倍,吞吐量也远远大于Oracle数据库的序列。
热点资源引擎
互联网大商户的对公账号记账已经成为了金融IT界的难题。例如拼多多等互联网商户的开展的抢购活动,以及各种理财的线上抢购活动,这类活动使账户余额和限额变成热点资源。以前银行内部账户可以透支,通常采用抓大放小的方式控制余额,然而互联网商户账号既有爆炸式流量又需要防透支。形成业内难以解决的热点账户难题和热点限额难题,热点资源计算引擎主要用于解决这类问题。
某国内互联网巨头曾经打造过一款“高速记账引擎”,热点记账性能号称到达2万笔/秒,但其做了绑定硬件优化,对硬件有要求,通用性不好。技术也极其底层,据说到达汇编层,可维护性也极差。最主要的是由于产品售卖不好,绩效不好,研发团队已经解散了,内部的售前人员都不敢售卖该产品。其实这是一个不错的产品,能彻底解决热点资源这个行业难题,但只注重短期盈利的互联网公司没有给这个产品太多时间,实在可惜。
目前热点资源的解决方案有三类,异步处理、散列处理,以及采用高速引擎。
异步处理和散列处理都是利用主流数据库实现,具有较高的可靠性,通用性和可维护性也比较高。异步处理模式的热点记账性能可以达到2000多笔每秒,散列处理的热点记账性能可以达到1万多笔每秒,它已经完全可以满足大型银行的热点记账效率要求。
异步处理方案是采用异步记录热点数据的策略,将热点资源竞态条件的判断和热点资源数值的更新两个步骤进行分离,先记录热点交易值,并做透支或超限判定,然后异步做汇总更新热点资源值。这样做可以实现热点交易全程无锁,从而提高并发能力。
异步处理的热点资源方案可以与TCC或SAGA两种记账方式进行整合。按照TCC的流程对热点资源的操作进行拆分,把对热点资源竞争态的判断操作与TCC的Try进行整合,把对热点资源交易数据确认的动作放在CONFIRM(确认阶段),把对交易数据状态回滚状态的动作放在CANCLE(取消阶段),最后由异步任务对交易确认后的记录进行汇总更新到热点资源值中去;热点资源与SAGA记账的整合也是类似步骤,但执行SAGA的DO接接口的时候可以省去资源确认步骤,执行UNDO节点的时候反向登记一笔交易记录。
散列的处理方式就是把一个热点资源拆分成多个热点,通过横向拆分来扩展并发度。具体来说,如果把一个热点值为1000的资源拆分成10个,每个平均分到100,进行热点值扣减计算时,随机取一个子热点来进行扣减,如果不够则再取一个进行计算,直到足够为止,取完所有子热点值还是不够则交易返回失败。
散列的热点处理方式在绝大部分情况下都能在一个子热点值中扣减结束返回,所以具有较高的热点记账性能。只有在大额扣减或热点值快扣完时出现多个子热点值同时扣减的情况,这种情况实际上是要整体加锁串行的。为了让各子热点值相对平均,除了进行随机扣减,还要有定时机制把热点值重新分配到各子热点值中。
热点资源引擎通过分析传统的热点处理模式,通过剥离传统的热点记账的业务逻辑,抽象出一个通用的热点资源技术组件,用于解决热点资源计算这个行业级难题。热点资源引擎分为分同步处理、异步处理、热点资源监控、并行处理框架四个模块。同步处理包含增减的热点值、热点资源值查询、维护热点值状态、清除热点记录等接口;异步处理包含异步汇总余额、异步更新交易后余额、异步汇总限额等功能;热点资源监控包括热点事件识别、热点资源设置、热点资源取消、热点事件扫描等;并行处理框架是针对热点资源需要极高的异步汇总效率,而打造的一个基于令牌桶机制的并行处理框架,该框架除了能高效的调度异步处理任务,在高可用方面也做了很多考量。
热点资源引擎跟具体的记账或记限额的应用是以SDK方式集成的,耦合度比较高,在实施过程中有些人可能直接把它作为应用的一部分,然后逐渐的再把这个业务问题纳入进来考虑,这样会又回到传统处理热点问题的方案。最后既难以效率问题,也失去了通用性,这需要我们在实施过程中注意。
数据聚合
我在南方某股份制银行做核心系统技术平台时,最初行方计划采购的数据库没有数据聚合能力。由于大数据部门也很难在秒级时效上做数据聚合,我们不得不创造一个数据聚合产品。项目实施做过程中,行方更换了数据库,这个数据库有一个多源同步的配套产品,但该产品已经不演进了。在互联网大厂中,不演进的产品一般不妙,不是产品团队解散了就是已经转向其他方向,有责任心售前和销售人员都会避开这种产品售卖。
数据聚合在大数据技术难以保障数据时效性,数据库又没有可靠的数据库聚合工具的背景下应运而生。
数据聚合有数据捕获、数据同步、同步模板配置、数据分库分表、同步任务管理等功能。数据捕获是通过数据捕获SDK拦截应用系统的DAO层,对数据的增删改操作进行进行拦截,触发异步的方式查询操作结果数据同步到数据聚合服务端。数据同步是在数据同步服务端根据数据同步模板对数据进行解析,并且落库聚合库。在数据存入聚合库的时候可以按照配置策略对数据进行分库分表,以支持海量数据的聚合,并且能高效的更新不同维度进行查询。
在性能方面,由于数据聚合是采用拦截DAO的方式异步触发同步,其几乎不影响原交易性能。而且它可以按交易、按表、按操作动作去进行同步,比解析Binlog方式同步灵活性强很多,时效性也较为可控。在实际测试中,几千TPS的交易数据同步,可以轻松实现秒级时效性。
单元化路由
我是在2018年参与民生科技分布式核心研发的时候接触到的单元化路由组件,后来民生科技平台研发的原班人马把这个产品‘带入’了邮储银行新核心系统。最初单元化路由的巧妙构思和设计给我恍然大悟、眼前一亮的感觉,我心中对设计者的敬佩油然而生。直到我到阿里后,才发现单元化路由的雏形是在支付宝单元化改造过程中,为了解决单元定位问题自然而然创造出来的。这又一次证明了技术的形成是问题解决过程中自然产生的。
支付宝的单元化路由只是雏形,真正的单元化路由是在几个大型银行核心项目中才真正变成一个技术组件的。对于技术的标准化、产品化、工程化,银行IT部门在这方面的能力应是首屈一指,特别是银行核心系统的技术团队,他们对技术方案、代码质量、测试质量的要求是最高的。
目前主流的拆分单元是按客户拆分的,当上送客户号时直接采用客户号取hash,后取绝对值,再对单元总数取模获取一个数字,这个数字则可以对应着单元号。在最初的支付宝中方案中,交易都是上送客户号的,所以它的单元路由相对简单。在银行的交易中,有些交易并没有上送客户号。单元路由是在交易没有上送客户号的情况下,根据账号、证件类型和证件号码、手机号等信息找到客户号,再根据客户算出分片号,以确定该笔交易路由到哪个单元。这需要建立客户号与账户、证件号、手机号之间的关系,在国产数据库下保存这个对应关系的表本身又需要进行分库分表。这样就逐渐增加的单元路由的复杂度,复杂度增加后自然就需要一个独立的技术组件来进行封装,这也是单元化路由在银行核心项目中被完整创造出来的原因之一。
单元化路由的功能有映射管理、路由管理、切换过度支持、访问权限控制、参数管理、统一数据访问功能、客户锁、账户锁、流水日志功能、运维支持功能等。其分为SDK和服务端两大部分,SDK给到使用单元路由能力的应用集成,一般是网关、服务编排等组件在外调的时候会使用到单元路由。服务端的主要功能是同步和管理客户号与其他要素对应关系,并且提供客户/账户锁功能。
如果交易上送客户号,单元化路由只需要在SDK集成一个路由算法即可解决路由定位问题,没有客户号则需要去服务端查询。但是,目前所有的单元化路由都做成了无论是否上送客户号都需要访问单元化路由,原因是把锁的功能和迁移过度的功能也加入到单元化路由中。在银行核心项目中,一次单元路由耗时可以控制在5ms一下,可以一次性把交易中涉及到的多方客户号的单元路由信息查询回来也能提高单元路由效率。
联机引擎
“联机引擎”这个词是IBM在邮储银行分布式核心项目中创造的,顾名思义它就是驱动联机交易的运行的引擎。最初的核心功能是交易流程控制、分布式事务控制、防重幂等、流水处理等。这两年联机引擎逐渐跟服务编排结合了起来,变成了可视化服务编排的交易执行引擎。再加之“业技一体化”理念的落地实施,联机引擎逐渐变成一个集成交易运行所需各种技术组件的平台,运行业务建模流程的平台。
但是,目前并没有公司把它当做一个平台来规划和设计,甚至有的公司把它当做流程引擎的扩展,把分布式事务、分布式锁等复杂组件简单的往上集成,使整个联机引擎复杂极高,且没有清晰的设计和架构。在南方某股份制银行核心项目中,80%以上的问题产生于联机引擎。联机引擎设计之初并不是“复杂的组件”,而是封装交易处理流程中的公共处理的组件,主要目的是提供标准的公共逻辑处理层,让具体的业务开发人员不用重复写每只交易的公共逻辑,降低业务开发难度,提升项目质量。
目前完整的联机引擎功能一般有:报文解析与映射,流水管理,公共检查,防重幂等,服务控制,服务前后处理嵌入,交易上下文管理、交易级缓存、优雅停机、SPI扩展机制、日志切面、本地事务管理、异常处理和封装、超时配置和处理、错误码管理、通用工具封装。以及集成分布式事务、乐观锁、服务治理、运维监控等组件。
联机引擎对性能要求是极为苛刻的,在对其性能调优的时候,甚至要把能获得零点几毫秒的耗时减少的优化点都进行了优化。在通信方面,大部分银行在联机引擎中基本上都采用效率较高的RPC通信。联机引擎中分布式事务的管理开销特别高,主要是其需要开启大量的独立事务,分布式数据库每次提交事务需要2-6ms,导致联机引擎耗时的三分之二都在事务提交上。
未来在联机引擎事务控制设计中可能需要更加注重其架构,只有搭好足够大的“架子”,才能在其上优雅的集成各种组件。另外,需要重新评估独立事务带来的收益和消耗,在交易设计中也应该尽量减少独立事务提交。分布式式事务提交效率低的问题将是分布式数据库最大的特点,只有客观评估当下问题,打破固化思维,才能找到有效的解决方案,从而创造出新的方案或产品。
批量调度引擎
2018年我们在民生科技做分布式核心研发,那时没人知道在分布式核心中日终批量如何运行。于是我把银行核心日终批量的70多个作业全部梳理和分析了一遍,最终我们论证通过了一种分布式核心系统跑批的方式:先收集待处理数据集,然后把待处理数据集逐条封装成请求报文,通过联机请求触发联机交易去处理日终批量逻辑,也就是现在大家说的”批转联”。批转联中的收集待处理数据集对应着集中式系统日终作业中的大循环的循环数据集,其循环内的逻辑则需要封装为联机交易逻辑。
批量引擎与集中式的批量平台相比较,除了批转联的整体思路改变,其中的流程控制还是跟集中式的控制逻辑一样。在任务分发和管理方面也需要做相应的改变,任务分发需要支持按单元分发,任务状态管理需要根据批转联任务执行情况来处理任务状态。批量引擎在分布式单元化架构中对其高可用方面也提出了新的要求。任务拆分均匀程度和吞吐量也有了更高的要求。一个新问题的解决,人们总是倾向于原有方案中做修改,以期解决新问题。在银行核心系统做分布式改造的初期就是如此往下推进批处理问题解决的。
目前市面上的批量引擎主要基于spring batch或xxl-job二开而成。其功能主要有作业定义、作业向执行机分发、单元化的作业分发、企业级系统间的作业分发;还有持作业状态管理,由下层批量任务控制器反馈作业执行状态并进行持久化存储供状态查询,以及按单元查询和统计。在流程控制方面,联机引擎有作业流程控制,包括基于作业依赖和时间依赖以及事件触发等多种作业调度编排方式;在流程控制中有分支流程、串行流程、并发流程、循环流程等,批量作业的操作有中断、恢复、跳过等。批量引擎对批量任务的数据段进行分片,分片策略通常有分段、一致性哈希、取模、按单元等方式。
批量调度引擎的任务执行实际上是的任务是在执行器中处理。要实现高可用和故障自动恢复,对执行器的管理和任务分发有很多细节性的要求。例如任务分发时记录和维护任务执行状态和执行器节点信息;还有执行器与批量调度服务端有注册发现机制;以及需要为运维管控平台提供相应的管控接口,比如调控批量并发数、发出监控告警信息等,避免系统高压力运行时出现批量争取联机资源,导致联机交易运行失败。
基于spring batch开发的批量调度引擎,一般采用开源软件比较简单和轻量级的特点,不会记录业务处理详细记录,只记录任务处理的chunk数据,而且它进行多次拆分,任务能较均为的分散到执行器中。这类调度引擎效率通常比较高,缺点就是任务记录较为简单,任务拆分逻辑比较抽象没有业务含义,很难适应大型业务系统建设中进行大规模开发。在大型系统的开发中,除了要求效率,而且还要求有详细的操作过程记录和批处理情况记录,相应的记录势必会造成性能下降,这是批量调度引擎设计时需要权衡。
文件引擎
某国内大厂采用spring batch进行稍微改造后号称为批量平台,再加上一个文件解析job后有又成了文件引擎。当时我在该厂工作,给他们产品部门详细讲解过文件引擎功能,今年我在某股份制银行看到该大厂给他们做的文件引擎还只是一个文件解析的job。
其实,文件引擎是一个具有很深历史积淀的技术组件,绝对不是拿着开源组件稍微改造就可以的。在银行中,从最传统的文件批处理流程到最新的流程,只是接入渠道增加了,其传统的处理流程几乎没有改变。文件引擎有很多技术处理细节是老银行IT人员的习惯或者经验,就如一位银行IT前辈所说:“按照以往的方式处理不一定是最好的,但我能确定是没问题的”。
在银行中,文件批量类交易通常都是代发代扣,最传统的代发通常是企业会计人员使用银行给的加密软件,对工资发放的excle做加密,然后用光盘或U盘存储后给到柜员,柜员用柜面系统进行上传到中间业务业务系统做校验和登记,然后转换为核心的文件格式发送到核心系统记账。现在也有大量的文件批量来自网银代发、银企直连等渠道。
文件引擎的处理步骤通常是:文件上传、文件通知、文件解析落库、文件内容校验(文件头处理)、文件内容执行(文件体处理)、文件处理结果核验(文件处理)、回执文件等。在文件引擎中必须有文件批类型管理和文件批次管理,文件批类型管理用于创建、修改文件批对应的文件模板、上送/返回文件路径、挂载文件头体尾处理逻辑、设置文件批的优先级、控制文件批量访问渠道等等;文件批次管理则是管理具体的次运行的文件批任务,包括批次的状态、批次的流程控制、批次信息的查询等。
在性能方面,文件拆分、落库,以及任务的拆分和分发,都需要并发进行,并发度的动态控制是最大的难点。在批转联情况下,并发度还需要考虑对联机交易资源的抢占。
统一网关
在企业级架构中,各系统集成一直都是企架的难点和重点。以往主要采用ESB串联大型企业中的各系统。但随着服务注册发现、声明式API等技术的普及,企业的微服务数量爆炸式增长,ESB的集成能力显得力不从心。
联机网关是最常见的一种网关,与联机交易一样,还有消息交易和文件交易,消息网关和文件网关也越来越被大家重视起来。另外,系统外调其实也需要进行协议转换和报文转换。因为这些网关有很多共通之处,例如协议转换、报文转换、鉴权、验签等都是它们的共同能力,我们在此把联机网关、消息网关、文件网关、外呼网关并称为统一网关。
联机网关一般有转换层,包括接口协议转换、接口报文映射、业务相应码转换、简单逻辑转换;接口管理,包括接口定义、接口维护、接口删除、接口查询,以及企业级接口同步;服务治理,包括限流、熔断、降级,开源的网关是通常是服务级的,通常需要做到一定改造才能实现接口级服务治理。造成这个问题的原因是互联网架构师认为的服务通常是一个接口,而大型金融系统的架构认为的服务通常是一个微服务;服务控制,包括访问鉴权、黑白名单;以及参数映射、服务分组管理、路由转发、灰度。
网关虽然有很多功能,其中重点还是协议转换和报文转换,支持的协议类型是判定网关能力的重要考量点。协议转换和报文转换的效率也是网关最重要的性能指标,一个高性能的网关,做一个50参数的协议和报文转换耗时不应超过5ms,为了提高性能,有些网关还采用了只解析报文头的方式。甚至有些网关在RPC协议中,通过查找字节码方式截取报文头进行解析,以极高的效率做报文转换、协议转换,以及流量控制。有TCP协议的握手机制非常消耗性能,有的网关直接采用长连接的方式。总之,网关是一个系统的门户,对稳定性和高效性要求极高,采用多少性能优化措施都不为过。
消息网关与联机网关很类似,除了报文来源是消息体,其他的都可以复用联机网关能力。不过,需要处理好消息消费失败的场景,消费失败分为业务系统消费失败和网关组件消费失败,两种情况需要采用不同方式进行处理。外呼网关其实就是联机网关的反方向处理流程,但其需要一个SDK把系统内的请求转发到外呼网关中,外呼网关也应该跟联机网关和消息网关分开部署,以便灵活控制系统流入流量和流出流量。文件网关与联机网关有一定区别,首先是其不适合跟联机网关和消息网关部署在一起,通常会跟文件引擎或文件批量部署在一起。
微服务和系统的数量越来越多,微服务和系统间的集成一定越来越复杂,集成技术从ESB逐渐转为网关,未来一定还需要更适合未来企业架构的“网关”,Mesh也许是一个方向,但开源的demo级Mesh肯定是不能满足金融级场景的,金融级的Mesh可能还是需要国内软件服务商在项目中根据实际需求进行创造。
莫把开头当结尾
过去10年互联网的蓬勃发展,为分布式、单元化、云原生技术发展“开了个头”。随着银行等金融机构和国内头部IT服务企业在这些技术上逐渐增加投入,特别是银行核心系统应用了这些技术,这些技术的运用将更加标准化、工程化、产品化。在运用单元化、云原生技术过程中,金融机构和头部IT服务企业也沉淀了大量aPaaS中间件,例如:单元化路由、参数缓存同步、热点资源引擎、数据聚合等。
国内大型金额机构和头部IT服务商在信创和云原生转型过程中,沉淀的这些aPaaS中间件如果开源出来,国内将形成新一代中间件,这代中间件将支持着我国大型IT系统在未来10年高效平稳运行。至于国外开源的注册中心、配置中心、MQ消息、Redis缓存等产品,没必要照抄一遍。因为这些产品在单元化、云原生架构下,以及大型系统的应用场景中需要进行深度的改造才能使用,不如根据新架构、新技术及信创要求研发新的产品,去解决我们遇到的新问题,只有这样我们才能摆脱“技术跟屁虫”的窘境。
不能提高应用开发和运行效率的技术平台就不是好的技术平台。aPaaS提供一些使应用开发更加便捷、应用运行更加标准高效的能力,其必然会成为云原生技术平台最有生命力的一层。
07
SaaS层
大型系统在国内SaaS化情况
几年前我在阿里银行核心的云先锋团队中工作,当时我们调研过国内银行核心SaaS化的情况。从理论上分析,软件SaaS化后只需增加运行的硬件资源就能支撑更多客户运行,也就是其扩大售卖规模的边际成本很低。这是互联网大厂最喜欢的商业模式,SaaS化几乎成为所有商业软件都想走的一条路。一个产品是否优秀,能否无边际成本的大规模售卖是最重要的衡量指标。
然而,在国内的监管下银行核心系统SaaS化几乎不可能。不过也有采用“多租户”来实现一个系统多个客户使用的,本质上多租户也是SaaS化的一种形式。国内主要有某数金和某城商联盟在提供银行核心的“多租户”服务,其中某数金并没有特别好的盈利,某城商联盟的系统维护和升级也异常艰难。金融系统的SaaS化似乎是一条艰难的路,然而餐饮管理、直播、电商、协同办公等行业却蓬勃发展。
金额系统SaaS化难度高的原因,除了监管严格和数据安全问题,还有定制化需求多、系统复杂性高、安全性要求高、稳定性要求高等。我们先抛开政策性问题,仅从技术上分析,近几年服务编排逐渐应用在大型系统建设中,复杂模块也逐渐进行了引擎化或工厂化,软件的分层封装也做得越来越好,这些技术发展趋势可以使复杂的大型系统SaaS化成为可能。
下面我们就从服务编排、引擎化、工厂化、分层管理等方面来分析如何做SaaS化的应用。
服务编排,让SaaS具备轻松定制业务流程的能力。
服务编排,简单来讲就是把内部和外部的各种服务接口编排起来,提供一个完整的服务,或者提供一个一站式服务。它让系统根据可视化流程的运行起来,业务人员能根据业务流程需要调整流程节点,也可以改变节点执行条件。专业的服务编排是要图菱完备的,还要与分布式事务融合,在对远程服务调用过程中自动管理分布式事务。这样业务人员可以自行修改系统运行流程,真正实现IT系统的敏捷响应业务需求。
引擎化,让SaaS具备强大的参数配置和调节能力。
大型IT系统有很多复杂的模块,其逻辑复杂性高,而且特别集中,这类模块通常可以抽象成一个引擎。例如限额引擎、规则引擎、热点资源引擎等。限额引擎专门用于控制各种额度以及数值的最大值、最小值。规则引擎则用于控制系统中各种状态变化和流转的,热点资源引擎则是上文在aPaaS中阐述的一个技术组件。在银行核心这种标准的系统中,这类引擎很常见。抽象成引擎后其参数可以由专门的引擎管控端进行配置,限额引擎和规则引擎基本上可以把系统中各种额度限制和状态流转都配置出来,通过改变配置就能改变各种数值的限制和状态的变更,这样的系统运行起来就非常灵活,实现真正的敏捷。
工厂化,通过产品工厂快速创建产品,满足市场需求。
2013年的时候我们本土化改造Oracle的一款银行核心系统Flexcuble。这是国内引入的首款Java银行核心,这款产品异常复杂,本土化改造量很大,实施成本非常高,但还是拿下了好几个客户,其中有一个股份制银行和两个农信。Flexcuble的最大亮点就是产品工厂做得特别好,当时国内核心普片还在做参数中心的时候,它已经把银行核心系统的参数进行整理归类,形成了产品工厂。产品工厂能让产品研发人员快速的配置出市场所需的产品,这才是真正的敏捷,这种敏捷是敏捷开发无法企及的,对于对稳定性、安全性要求较高的系统应该追求这种敏捷,而不是敏捷开发。
Flexcuble等国外产品的引进,给国内银行核心系统厂商做了些参考,使后来国内新研发的java核心系统从面向参数设计演变成了面向产品设计。以往面向参数设计的系统也能做到很高的灵活度,但没有对参数按业务属性进行整理,甚至有些核心系统的参数直接是键值对形式的,取名也比较偏技术。产品人员根本看不懂,也配置不明白。所以真正的产品工厂是要采用业务语言描述,产品人员能看懂、能配置。这一波银行核心建设主要是信创推动,业务人员很少参与,个别项目业务人员甚至明确不参与。这种情况下新建的核心系统,是否有产品工厂似乎也没人关心。
加入适配层(防腐层),在多版本演进时增强核心逻辑的稳定性。
适配层包括对外接口的适配层,以及数据模型持久化的适配层。也就是在对外接口层到业务逻辑层之间加入一层适配层,让定制化版本在适配中进行改动。另外,核心业务逻辑要与数据模型解耦,避免不同版本对存储的信息有不同的要求,导致数据模型改变,从而改动核心业务逻辑。这要求业务逻辑不能直接操作数据模型,而是操作业务逻辑所需的实体模型,在业务逻辑层和持久化层中间加适配层,做定制化版本的持久化层适配,以保护核心业务逻辑稳定。
封装环境层,降低应用开发人员对运行环境的认知要求,使其专注于应用开发。
aws的云平台中有一款很优秀的产品叫Beanstalk,它对环境的封装就非常好,可谓是真正的大师级产品。真正的技术大师不会把技术菜单和按钮摆满屏幕,而是把用户直接意图所需的操作放在最显著的位置,用户在没有阅读操作手册的情况下,凭借直接意图就知道点哪个按钮。顺着用户意图逐渐要求客户去补充相关配置和信息,并且给出很多的默认配置,尽量降低用户的知识要求。反观国内大厂的同类产品,把所有菜单都展示出来,菜单栏上几十个菜单,必须认真研读其操作手册,理解其中复杂的关系后才能勉强会用,要想熟练掌握必须考一个证书才行。有的产品有导航式引导,但它是引导客户进行基础参数配置的,而不是用户的直接意图,用户一开始就很疑惑为什么要配置那些繁琐的配置,而且用户必须要看操作手册才知道如何配置。
封装环境层则是将环境作为一个整体,应用是运行在其上,应用开发人员不用关心环境内部的机制。环境中有全套中间件、数据库、负载均衡,以及配套的网络配置和运行的资源,乃至配套的运维监控。目前的云环境太复杂的,应用开发人员完全理解云环境中的各种概念很困难,所以对环境整体的封装是必然的选择,Beanstalk给我们做了很好的示范。
数据安全问题是SaaS化的拦路虎。
最近这些年我经常接到各种莫名其妙的促销电话,有时甚至接到国外的诈骗电话。让人恐惧的是骗子能准确知道我的身份证、住址、职业、喜好,以及刚才网上购物情况,我相信很多人都深受其苦,但无能为力。这说明我们对个人信息数据的保护并没有明显的成效,唯有让大家感觉到数据安全的确有保障,SaaS化才有可能快速发展。
数据的权利大致可分为所有权、管理权、使用权。数据的所有权理应属于相应的个人或机构,管理权则属于管理相关数据的机构或个人,使用权属于被数据所有人授权使用的机构或个人。这三种权利需要严格区分和保障,数据所有者有权对自身数据的使用授权进行管理及享受数据使用的收益,数据不应被数据管理者擅自使用,数据更不能被数据管理者默认占有,数据管理者只要数据除存储加工处理权利不应有使用权利。只要有对这些权利进行严格规范和管理,人们才能在这个数字化的世界中安全生存。
上述的数据权限分离和保障,当下是有技术手段可以实现。采用数据加密手段,限制数据管理者的权限是关键。数据管理者是最容易侵权的一方,其利用管理职能,很轻松就能利用海量数据获取巨额利用,只有对数据进行严格加密,密码掌握在数据所有者手中,才能避免数据被数据管理者滥用。
在公共云环境中数据加密更为重要,公共云其实就是把客户的数据放到互联网络环境中,数据安全问题尤其突出。一方面是云环境的管理者可以轻易获取数据,另一方面是互联网环境本身容易受到渗透和攻击。把企业的IT系统运行在公共云上,相当于把企业的生命托付在云上,只有让数据所有者采用自己可信的加密方式对数据进行了加密,数据所有者才会放心的把数据放到公共云上。这样SaaS化才有可能高速发展。
大型IT系统SaaS化,耐心是关键。
国内某互联网巨头在2018年信誓旦旦进军银行核心系统,直到2022年5月落地实施了一家银行互联网核心。银行账务核心的关键微服务也正在一家农信和一家城商行落地过程中。然而,该互联网巨头却无视客户诉求、不顾项目影响,毅然停止了其银行账务核心关键微服务的版本演进,拆解相关团队。
一家国内做银行核心的民营企业,全年营收没超过3亿。有一个40-60人的银行核心研发团队,花了3年时间研发了Java版银行核心,又花了3年时间在一家客户关系非常好的城商行进行了落地实施。前后花了6年时间,才算获得了一个银行核心系统1.0版。由此可见要把类似于银行核心这样的大型系统进行SaaS化,其时间周期将是非常长的,公司或投资者的耐心是成败的关键。
在新兴领域需要的是快速试错、及时止损;在大型核心系统领域则需要高瞻远瞩的技术人才和耐心的资本。国内互联网大厂用新兴领域的模式进军核心领域,必定是水土不服的。
SaaS服务一定要部署在公共云上吗?
SaaS化大家通常理解是把系统部署到公共云中。其实不然,大型企业可以把应用部署到私有云中,再通过前置系统向外部合作伙伴或客户提供服务,这是大型IT系统SaaS化更加合理的部署方式。因为数据安全、网络安全、公共云可信度等问题尚未解决,大型核心系统很难在公共云上进行SaaS化部署。而且很多大型企业已经自建云平台,也没必要把关键系统放到公共云上。
生态云或行业云也不一定要把所有系统都上公共云,关键系统部署在私有云中通过前置系统把几个私有云中的系统串连接起来,同样也能形成更加安全可靠的生态云或行业云。所以,SaaS服务并不是特指公共云上的服务,未来更多必将是私有云中的SaaS服务。
08
采用什么理论能确保你的系统10年后依然好用?
一个基础的理论
目前很多大型系统建设都是“闻风而动”,一阵技术风潮吹过就重构一遍系统,使用周期长达10年以上的IT系统肯定是跟不上技术风潮的,这种情况亟需更基础的理论指导,从更加长远角度指导大型IT系统建设。本文姑且抛转引玉,提出一个可能适用的基础理论概述。
近20年IT技术的发展是伴随互联网崛起而发展的,其从来没有什么理论指导,也不需要理论指导,能挣钱的互联网公司就活下来了,反正则已经消失在技术迭代的浪潮中。“物竞天择,适者生存”正是《进化论》的基本原理。
假设存在更广义的进化论:“事物总是以自身存在为目的,进行对外作用和对内调整”。这似乎是一条必然正确的假设,因为如果某个事物不以自身存在为目的而对外作用和对内调整,该事物就已经不存在,所以现存的事物应该都遵循这个假设。动物的进化是如此、公司发展亦是如此,那么IT系统的演进是否也是如此呢?
假敏捷与真敏捷
自从互联网的敏捷开发之风吹起后,很多大型企业也掀起了敏捷之风,熟不知对于大型复杂系统来说那是假敏捷。对于大型IT系统,快速的迭代需要大量的人力,而且难以保障系统的稳定性。只有在全新的领域,业务模式还在探索阶段的领域,才适合快速迭代、测试、发版。对于业务规则几十年都没怎么变化的金融系统,为何需要频繁迭代更新?原因只是系统设计之初并没有考虑如何敏捷的支持业务变更。
那么大型IT系统如何做到真敏捷?如何具有更强的适应性?以确保在未来的竞争中适合并且生存下来。我想其设计理念应该是离不开上面谈到的基础理论的。根据上述理论:“事物总是以自身存在为目的,进行对外作用和对内调整”,IT系统满足这个理论则可经久不衰,满足这个理论这需要三个模块或部分:内部调整部分、输出部分、接入部分。理论上,一个IT系统只要这三个模块足够强大,那么它就有对未来环境的强大适应能力,并且能真正敏捷的支持业务发展。
在当前技术条件下,做好内部调整部分可以是做好系统的参数化、引擎化、可视化流程编排、产品工厂等方面;输出部分则可以有对外供数、数据聚合、数据清洗和分析等,也可以有系统监控、自检、外呼等,还可以有系统运行效能、运行成本等;输入部分目前大家比较注重联机网关、消息网关、Mesh等,其实还应有IT系统对业务变迁的感知,比如“业技一体化”之类的技术和理念,它弥合了业务与IT实现间的鸿沟,让IT随业务而动,此乃真敏捷。
完美的系统
人其实本身就是一个非常完美的系统,其大脑类似于一个强大的控制引擎。人的身体构造本身几万年来都没太多变化,变化比较大的是其大脑里的思想。通过快速改变大脑的思想来适应环境,使人这个“超级系统”存在了几万年。对应这人的一些特征,系统设计时应该为其设计各种参数引擎、流程编排器、产品工厂等,以提升系统对内的调整能力;其次还需要有对外的感知部分,比如同业的同类系统业务开展情况,通过一些公开的数据进行分析,以调整快速调整自身产品参数,确保产品比同业产品更受市场欢迎;再则需要对外输出模块,以便和外部系统协同,例如向监控系统输出系统运行状态,以及向数据下游系统提供丰富的数据。只有对内可调整维度足够多、调整幅度足够大,对外作用精准有效的系统才能在长时间内更好的适应环境。未来,采用深度神经网络作为控制引擎的系统也许更能适应环境。
老子说:“道可道,非常道,名可名,非常名”,人的认知与总结能力是有限的,人不能创造完美的系统,只不断推进系统的演进。每次无法通过修改参数或流程来满足业务需求,都应该作为系统设计者的一次反思,采用面向对象的方法进行分析、总结经验,让下个升级版本更加适应需求。当大部分需求都无法通过修改参数或流程来满足时,系统则应被淘汰在业务演进的浪潮中。
佛说:“诸法空相”,现实业务本身才是完美的,当我们在IT系统的逻辑中迷茫时,回到现实业务本身,乃可重拾方向。(作者微信:wcsmomo)
说明:本文仅代表作者个人观点




