皇上,还记得我吗?我就是1999年那个Linux伊甸园啊-----24小时滚动更新开源资讯,全年无休!

恒丰银行微服务架构优化实践

作者 薛梁

“Weniger aber besser(少而优)”是德国工业设计大师Dieter Rams崇尚的设计理念,也是乔布斯“至繁归于至简”的精髓所在。

关于架构,是不是越复杂越好呢?从各大金融案例来看,恰恰相反,简单才是硬道理。这也正是微服务能够流行的原因,市场上出现的服务架构如EJB、SCA、Dubbo等,相比微服务来说他们的功能更完善,但因为它们过于复杂,所以都没有微服务这么深入民心。

目前,微服务架构已经在金融企业范围内实践应用,伴随着系统不断的优化,企业会选择在原有基础进行改进,或者开发更多适合企业业务的新架构平台,这也许就是简单框架流行的本质。

本文就围绕微服务架构在恒丰银行的使用案例,采访恒丰银行科技开发部资深软件架构师 曾光尧老师,请他谈谈微服务架构给恒丰银行带来了哪些收益,以及恒丰在微服务架构上做了哪些研发。PS:曾老师也会到8月10-11日在北京举办的APMCon大会上演讲,感兴趣的可以进一步关注。

InfoQ:曾老师,您提到说,恒丰银行开发团队自己研发了很多自适配的服务,是因为传统技术架构存在性能瓶颈,这里可否详细的介绍一些性能瓶颈有哪些?

曾光尧:银行传统的应用服务架构大多数是基于J2EE体系的,在大家熟悉的Tomcat、JBoss、WebLogic等应用服务容器上开发部署,应用软件通过较流行的Spring/Struts/Hibernate等技术框架实现对象容器化管理、MVC分层、数据对象映射等基础能力。大部分的应用服务容器都是传统的多线程系统架构模式,通过服务线程池调度实现对外部请求的响应。由于操作系统线程切换代价较大等原因,在传统多线程架构下单个节点能够同时服务的客户端有限,并发服务能力始终没办法获得大的提升,在我们实际生产环境中,单节点应用服务的Qps一般在1000以内。

通过学习国外先进网站的应用技术架构特点,和现有的架构做比较,我们可以发现传统多线程服务架构不能有效发挥当前CPU多核的硬件优势,存在如下缺点:

  1. 在网络多路复用IO技术选择上,大部分应用服务容器采用select/poll机制,对操作系统内核的负担较重,容易遭遇C10K问题(即单个服务器节点客户端连接不能超过1万)。而在目前移动互联应用场景下,手机设备往往需要和后端应用服务器建立WebSocket这种全双工的长连接,以提升客户交互体验,这就对单台服务器能连接的设备数量提出了更高要求。
  2. 一个客户端请求在执行过程中独占一个服务线程,应用服务容器同时处理的请求任务数取决于线程池大小,我们往往需要配置较大线程池(一个CPU逻辑核对应10个以上线程)才能实现更大的并发处理能力。但在高并发场景下,线程数越大意味着操作系统的线程切换管理负担加大,从而减少硬件资源的有效利用率,增加服务响应时间,降低服务器负载容量。
  3. 线程之间共享资源操作需要借助锁机制,而在高并发场景下,锁冲突会加剧,从而影响业务逻辑的执行效率和线程资源的使用效率。
  4. 在客户端请求执行过程中只能采用同步(阻塞式)IO机制,在商业应用中,服务器线程大部分时间是花在IO等待上面,比如本地文件读写或网络服务等待上。
  5. 传统应用服务容器本质上还是单体应用,高度容错的分布式并行处理编程困难,业务逻辑难以拆分成多个并行处理子过程,无法有效利用多节点和多核的X86服务器集群硬件优势,业务逻辑越复杂对客户端的响应时间也越慢。

综上所述,我们认为传统服务架构因为网络多路复用IO机制、线程调度、锁资源竞争、同步IO等因素,难以有效利用CPU计算资源和实现业务逻辑的并行化处理, 整体服务承载能力有效,不能满足移动互联应用场景高并发低延迟的技术能力要求。

InfoQ:简单介绍一下恒丰银行的业务特点是什么?对整个公司的IT架构有什么特殊的规格?

曾光尧:恒丰银行是12家全国性股份制商业银行之一,经营的金融业务种类齐全,近年来业务发展稳健快速。恒丰银行致力于做“知识和科技的传播者、渠道和平台的建设者、金融综合解决方案的提供者”。提出了“四轮驱动、两翼齐飞”的经营策略(“四轮”是指企业金融、金融市场、零售金融、移动金融业务,“两翼”则是投资银行和资产管理业务),依托金融云平台和大数据平台,实现龙头金融、平台金融、家庭金融、O2O金融等四大金融创新业务模式,打造数字银行、交易银行、银行的银行,力求为客户和社会提供效率最高、体验最佳的综合金融服务。

恒丰银行的发展战略意图是如何更好发挥金融媒介作用,整合金融服务资源和能力并与社会经济活动、大众生活场景相结合,实现社会多方参与协作的业务模式创新。恒丰银行突破物理网点的限制,面向细分客户群体的不同需求,有针对性地设计产品和业务流程,并以数字化运营为基础,充分发挥移动互联网络的优势,为客户提供便捷个性化、智能场景化的创新金融服务。唯有如此,才能在激烈竞争的金融市场存活并获得发展,才能扬长避短实现弯道超车。

行内业务发展对IT系统建设提出的总体要求是“打造数字化驱动的智慧银行”,从IT架构规划和实施的角度,体现为如下几点:

  1. 充分利用云计算技术的优势,打造灵活高效并支持弹性部署的软件服务基础设施,支持高并发低延迟的移动互联场景应用需求,支持银行业务重心从线下到线上的转移,满足客户通过各种移动设备和自助机具获得良好服务体验的需求。
  2. 打造基于大数据技术的数字化运营体系,实现海量数据的自动化获取、加工处理、深度挖掘,并运用数据智能技术构建恒丰银行的“智慧业务大脑”,实现智慧网点服务、智能风控体系、智能获客与产品个性化推荐、实时的业务分析与决策支持。这也意味着一笔简单的线上客户交易,后台发生的事会越来越复杂,除了传统的交易帐务处理之外,还可能涉及到客户线上操作行为的采集、交易反欺诈引擎的规则判断和模式计算、交易完成后个性化的产品推荐和业务提醒、基于地理位置的生活场景服务推送;与此同时,客户实时业务视图在后台自动更新处理,不同的业务部门按照各自管理视角定制的实时业务分析看板也要重新计算和刷新。
  3. 坚守银行系统运行安全可靠的底线,在积极实现业务创新的同时,提供稳定可靠的服务质量。如在应对“双十一”购物狂欢节等特定的交易峰值是能保持稳定的服务能力输出;局部的程序缺陷造成的影响能有效隔离和自动修复,不好出现全局性的服务可用性问题。

InfoQ:恒丰银行在设计微服务架构初期,有什么样的考量,需要规避哪些可能存在的坑?

曾光尧:企业应用软件架构经历以TCP/IP网络通信编程为特征的Client/Server模式、以IDL接口描述语言为特征的分布式组件对象架构(DCOM和CORBA为代表)、以WSDL/WebService/ESB为特征的SOA面向服务架构,一直进化到Reactive/容器化/DevOps为特征的微服务架构。每一次应用软件架构的变化,都号称解决了以前的问题,简化了应用的开发,但对于大多数程序员来说,好像都是痛苦地被裹挟到这个软件进化的洪流,不得不适应主流技术架构的变化,在这个过程中的一知半解往往会引发无法预见的问题。

从我个人的角度看,这20多年应用软件架构变化主要有如下动因:

  1. 简化和屏蔽复杂的底层网络通讯细节,增强网络服务的可管理性和位置透明。
  2. 将越来越复杂的现实应用程序分拆为更小的软件部件,不断弱化部件之间的耦合度,降低部件的开发难度,优化它们组合成完整应用的实现形式。
  3. 将解耦后的软件部件部署为分布式轻型化的组件服务,增强组件服务的自治性、容错性,更好地实现分布式并行处理能力。

微服务架构在恒丰银行被采用的原因,主要因为当前应用的复杂度和应用服务的弹性部署要求。通过将大的单体应用系统分拆为多个松耦合、可独立运行的微服务组件,可按业务和技术职能划分给更小的团队独立开发,减少代码变更对整体应用的影响,对不同的应用部件按需弹性配置硬件资源。

容易陷入的认知误区是:

  1. 认为应用程序只是换了一种运行容器或基础设施,大家还是按照单体应用程序的构建形式开发和部署软件。
  2. 把握不好微服务的粒度划分原则。粒度划分过细导致微服务过多,会增加跨网络的接口调用成本和降低响应速度,加大运维部署成本和资源分配难度;粒度划分过粗,甚至退化为原有的三层结构,不容易隔离业务应用之间的影响,为出现性能瓶颈的软件部件分配更多的硬件资源。

考虑到我们需要采用Reactive微服务架构去解决传统架构存在的问题,我们还是从技术和业务两个维度去切割微服务:

  1. 用异步化编程模式包装各种网络服务为基础的微服务组件,如数据库服务、FTP服务、MQ服务等,这些服务局限在应用内部调用,一般不对外开放。这种做法可以简化网络服务调用的复杂交互控制细节,为后端网络服务的压力负荷管理提供可能性。
  2. 消耗CPU较多的复杂迭代算法或内存计算任务,微服务化后可以更好地支持分布式并行处理。如蒙特卡洛模拟等算法,可以切分搜索空间,发送给不同节点去做实际运算。
  3. 具备独立的业务能力的软件模块,接口比较稳定或者可以设计得比较宽泛(如通过可变参数列表形式),多个微服务化的业务组件可以组合成更加复杂的业务功能服务。

InfoQ:最终选择Akka作为微服务基础软件框架的原因是什么?更关注Akka的什么功能特性?

曾光尧:Akka作为高性能、高度容错、支持弹性部署的成熟方案,Actor模式的特性可以很好地用来实现微服务。其详细特点描述如下:

  1. Akka消息处理的高性能。单节点每秒可完成5000万消息处理。
  2. 资源需求低,每GB内存可容纳250万Actor实体对象。
  3. Akka的成熟度。是著名的Spark大数据平台的底层架构软件,也被BBC、Amazon、Cisco、eBay、Groupon等众多大企业采用,并在2015年获得JAX 创新开发技术大奖。
  4. 基于强大的Scala语言编写,编码实现效率高,可以和其他JVM语言类库相互调用。
  5. 角色(Actor)并发编程模型较好地屏蔽了底层通讯细节和线程任务调度细节,编程较容易;基于消息传递机制实现服务协同和数据共享,消除资源锁竞争。
  6. 来源于Amazon Dynamo系统的Gossip集群通讯协议,经过Amazon云服务平台的长期技术验证,可靠性高。可支持Cluster Sharding、Cluster Singleton、Distributed Publish Subscribe、Distributed Data等多种集群应用场景。
  7. 父子角色对象(Actor)的监管者(Supervisor)模式。父角色对象可以捕获子角色对象的异常并自动执行不同的重启策略,极大提高了系统的容错性和服务可用性,减少高可用性代码编写难度。
  8. 通过软件路由器(router)和执行分发器(dispatcher)组合实现多种Actor并发和负载均衡算法策略,构建软件弹性部署能力。其中路由器支持如轮询调度(round robin)、随机调度(random)、广播(broadcast)、一致性哈希(Consistent Hashing)等任务分配算法;执行分发器构建独立线程池,隔离不同类型Actor之间的CPU资源竞争影响。

InfoQ:据了解,恒丰自研基于Akka的微服务架构平台Skyline进行相关组件开发,那么最后实现了那些需求,效果如何?Skyline在恒丰内部还发挥了哪些作用?

曾光尧:Akka等微服务软件框架上的应用开发存在工程实现难度,主要表现为如下三点:

  1. 受限于语言本身对分布式并行处理的支持程度不高,大部分基于微服务或异步IO框架的软件开发需要关注异步通讯的交互细节,容易陷入嵌套异步回调的编程陷阱,不符合大部分程序员顺序编程思维的习惯,开发和调试都非常困难。
  2. 基础平台层面缺乏应对峰值压力下的自适应调整能力,容易将访问压力传导到数据库等更脆弱的基础软件设施,导致系统整体崩溃。
  3. 缺乏在运行时对不同服务质量的差异化管理机制,在云计算环境下的动态部署能力受限。

针对上述技术难点,我们在Akka的基础上自研了Skyline微服务架构平台,针对上述三类问题,我们的技术解决方案为:

  1. 独立自主设计实现了支持分布式并行计算的新编程语言Zebra,实现多种并行处理范式,支持微服务的异步并行调用。
  2. 微服务组件化,实现服务组件容器,实现服务组件实例的弹性创建和销毁,服务请求的排队、超时清理、过载阻断,保护后端较脆弱的服务设施,提供稳定的服务质量。
  3. 服务组件容器支持不同微服务的并发实例数、使用线程资源池、任务队列长度、超时时间、部署物理节点等动态配置项,可以在运行时动态调整,以支持差异化的服务质量。

Skyline平台最终实现的效果为:

  1. 实现高并发低延迟服务能力。Zebra分布式并行服务语言通过增强语法支持异步并行服务调用,通过数据并行、指令并行、Pipeline等三种方式提升程序的运行速度,降低响应延迟时间;Zeroutine协程调度框架减少线程切换成本,构建完全无阻塞的程序运行机制,有效提高服务吞吐量。
  2. 提供稳定可靠服务输出。服务组件容器技术实现微服务实例的按需自适应调整和峰值压力下的排队缓存、超时清理和过载阻断机制;组件容器隔离程序缺陷影响,实现异常崩溃后的快速重启;并通过Zebra语言的契约式编程范式提升代码质量,隔离不同模块和应用系统的错误影响。
  3. 更好的弹性部署能力。可动态配置的服务组件部署机制,支持多种集群部署模式;从并发处理能力、单位时间最大吞吐量、线程资源等多个维度实现弹性的服务部署策略;与Docker容器云技术结合实现硬件资源的弹性扩容。

Skyline平台解决了系统容错、集群弹性部署、快速开发测试、应用服务间集成、数据并行化处理、系统过载的服务可用性等关键问题,对移动互联场景下高性能数据应用服务开发提供了完整有效的平台工具支持;基于Zebra语言编写的商业逻辑代码能有效屏蔽底层服务技术细节,加快分布式并行数据处理应用服务的开发效率。恒丰银行在客户营销、风险管理等多个业务领域基于Skyline平台开发了近30多个应用和公共服务,单节点的QPS值达到7万多,应用服务的总体硬件成本降为原来的1/5-1/10,高质量分布式软件服务的开发成本降为原来的1/2,并且可以节约较多的商用中间件软件的采购成本。

InfoQ:请介绍在微服务架构下,是如何与大数据软件生态集成,如何快速开发实时创新应用的?

曾光尧:Skyline平台主要通过如下几个方面实现和大数据软件生态的集成和整合:

  1. 开发相关网络服务适配器。将我们能用到的大数据软件(如Kafka、Hbase、Spark等)的客户端代码包装成可动态配置参数的适配器组件,屏蔽复杂的接口交互细节、异常处理等事项,该组件能被容器部署并动态管理,在Zebra脚本语言中异步调用,并支持多种并行处理模式对应用加速。
  2. 实现了分布式实时消息总线。通过服务代理机制集成了MQ、Kafka等多种消息设施。与其他技术方案相比,提供了统一的发布订阅编程原语,容易扩展集成多种消息设施,可在客户端与客户端、客户端与服务器以及多个服务器之间实现一致性的即时消息通讯开发;支持可插入式的消息编码解码算法,支持Pub-Sub、RPC、OneWay三种接口调用方式,可在Web端通过WebSocket直接调用Zebra函数实现分布式并行数据处理。
  3. Skyline分布式实时消息总线结合Flume、Kafka,打造完整的实时流处理平台。开发操作系统、数据库和各种网络服务的数据探针,对接多种系统数据源;开发管理工具,支持数据采集、格式化处理、数据过滤、聚合计算、数据补全、数据存储、数据流控等过程的动态配置和自动化部署;可动态嵌入Zebra语言编写的业务逻辑处理代码,提升后端服务的并行处理效率。与其他流处理方案相比,业务编程更简单,可实现高并发无阻塞的业务处理过程,支持多系统动态集成,可充分利用分布式硬件资源优势。
  4. 开发面向业务团队的实时智能决策引擎。业务团队可通过可视化工具配置客户营销、风险管理等领域的业务知识库、业务规则路由,支持复杂规则驱动的业务逻辑处理,实现营销机会的实时推送和潜在风险的实时预警。

以信用卡交易监测应用为例,基于Skyline平台的实现步骤如下:

  1. 在流处理管理平台定义APM网络报文日志实时采集和动态解析加工规则,自动部署agent到相关应用服务节点;flume collect 将agent发过来报文数据按预定义的规则解析成结构化数据,转入Kafka的交易信息主题。
  2. 执行Zebra业务处理代码的流处理组件订阅了交易信息主题,能及时收到相关交易数据,异步存储到实时流缓存数据库;交易数据接着触发实时智能决策引擎的规则推理过程,输出判断交易风险的分类数据,并转发到信用卡交易风险数据主题。
  3. 信用卡交易风险数据主题被风险处置的流业务组件所订阅,可以根据风险分类等级,确定执行卡冻结、还是增加新的验证环节等处置手段。
  4. 整个过程大部分可通过实时流处理平台的数据采集和加工解析配置、智能决策引擎的知识库与规则路由配置,加上较少的Zebra业务处理代码来实现,大数据平台上的实时创新应用开发会比较快。

InfoQ:恒丰银行针对微服务架构做了哪些性能优化、性能调优方面的举措?如何提升它的高可用性能?

曾光尧:恒丰银行在构建Skyline微服务架构平台时设计了如下性能优化的机制:

  1. Skyline的协程架构和异步服务调用机制,Zebra编写的业务逻辑处理组件在容器中可以用接近于逻辑核的线程数实现无阻塞运行,完全避免了线程切换成本。
  2. 网络服务通过适配器组件包装并单独Docker化部署,可实现不同访问成本任务的差异化并发控制,最大化提升后端传统服务架构的吞吐量,与业务逻辑任务有效隔离,避免不同类型代码模块的执行速度失配,影响系统整体的高并发服务能力。
  3. Skyline的分布式实时消息总线,可实现各种设备与后端服务的长连接,减少网络延迟时间。
  4. Zebra语言提供的多种任务并行化机制,可提升单个任务的并行度,充分利用分布式硬件资源,极大降低任务的响应时间。
  5. Skyline平台基于Actor的组件编程模式,消除了资源锁竞争,提高了并发任务的执行效率。
  6. 大部分应用调优可通过Skyline平台组件容器的运行策略动态调整解决,具备运维的便利性。

高可用性主要体现在如下方面:

  1. Docker容器化部署实现了硬件故障的失效转移和快速重启。
  2. 组件容器实现任务的缓存排队、超时清理和过载阻断,可有效缓冲峰值压力,实现稳定平衡的服务输出;基于异常处理的策略化管理,可有效隔离程序缺陷,实现异常服务组件微秒级的快速恢复。
  3. 涉及网络服务的关键组件和分布式实时消息总线都实现了心跳活跃检测和自动化重建连接的机制,提升了网络化服务的高可用性。
  4. Zebra语言支持契约式编程机制,可在开发测试阶段提前发现业务逻辑缺陷,并在运行时有效阻断程序异常缺陷在不同软件部件中传播。
  5. 增强的Raft协议服务组件,可构建跨中心的组件服务,实现多中心的运行时灾备容错,构建永不停顿的服务质量。

InfoQ:最后,问一个经验类的问题,您拥有22年的银行IT系统开发经验,可不可以谈谈,银行系统开发经历了哪些变革阶段?当前的银行系统需要具备什么样的特性?如何与最热的AI技术、FinTech技术相结合呢?

曾光尧:商业银行IT系统的开发演进基本跟随了软件技术的各个发展阶段:

  1. 1990年代早期,主机-终端时代,编程语言为C/COBOL。银行的主要IT系统是核心帐务处理系统,架设在集中式的主机之上(大行采用小型机或中型机,小行采用PC服务器),网点通过终端与主机连接,一般只能构建同城的终端网络系统,实现了同城业务集中和通存通兑。那个年代推广一套系统,包里揣个硬盘就出去了。
  2. 1990年代中后期,客户机/服务器架构时代。银行IT系统建设开始提以客户为中心的综合业务系统概念,开始实施区域集中的核心银行系统,地市前置机系统外挂网点终端设备,通过DDN专线与省行帐务处理主机相连,采用交易通讯中间件或通过TCP/IP协议实现前置机与帐务主机的报文通讯和交易一致性机制。这个时候的银行核心系统大部分基于Unix系统和C语言开发,商业银行网银系统开始出现,尝试使用JAVA语言、HTML、Javascript开发应用。
  3. 2000年代初期至中期,客户机/应用服务器/数据库服务器分离的三层架构时代。股份制银行率先实现全行大集中核心项目,实现全行业务通存通兑;商业银行的应用系统建设出现细分,业务报表、信贷管理、票据系统等纷纷从核心帐务系统职能剥离,形成专业化应用;BI、数据仓库技术开始引入,CRM系统、客户呼叫中心系统、经营决策系统、财务管理系统等新系统开始建设,新建系统开始采用J2EE架构,JAVA语言逐渐替代C语言成为应用开发的主流语言,也有部分应用采用微软的.NET技术。
  4. 2000年代后期至2010年代初期,SOA架构时代。银行应对激烈的市场竞争,开始注重业务模式变革、管理模式变革。较领先的股份制银行提出了流程再造、产品工厂等新概念和新需求,SOA架构某种程度上顺应了银行流程再造的需求,也有利于商业银行进行渠道和产品系统整合以及创新业务产品的快速推出。与此同时,移动互联网逐渐兴起,客户交易主渠道逐渐转向新推出的手机银行系统;银行开始重视客户的服务体验,重视风险管理体系建设,开始尝试数据挖掘和机器学习技术提炼数据价值,提升客户营销与风险管理水平。

进入2010年代中期,商业银行面临利率市场化和国内金融市场对外开放的压力,互联网金融的兴起也加剧了银行客户和资金的流失。面对新的挑战,商业银行在科技领域也在加大创新投入,虚心向互联网企业学习,不断拥抱新技术,体现如下:

  1. 引入云计算技术构建企业私有云,包括OpenStack和Docker容器技术,实现硬件资源的弹性管理。
  2. 尝试运用微服务架构开发创新应用,包括在分布式核心系统、实时风险预警、实时营销应用等新建系统,希望降低单体应用的运营风险,在云环境更合理地给不同业务服务弹性分配硬件资源。
  3. 搭建大数据平台,开发创新的数据应用与服务。大数据技术逐渐流行,有效提升了企业的海量数据处理能力和业务建模能力,实时流处理技术提升了银行的客户感知能力和风险预警能力,加快了业务的反应速度。
  4. 人工智能技术开始在银行受到重视。基于大数据平台的机器学习技术逐渐流行,加速了客户营销与风险管理领域的业务建模速度;文本分析、认知计算、知识图谱等技术提升了银行对文本数据、社交网络数据的价值提炼和业务应用水平;规则推理引擎技术的应用,使得复杂业务场景的智能决策成为可能。
  5. 区块链、VR等新技术在商业银行处于预研和孵化阶段,在等待技术体系不断成熟和实施成本下降的过程中,正在寻找合适的业务场景结合点。

嘉宾介绍:

恒丰银行微服务架构优化实践曾光尧,恒丰银行科技开发部资深软件架构师,22年银行IT系统开发经历。个人现阶段关注的是高性能微服务架构设计、分布式并行处理技术、领域语言设计、大数据与人工智能技术等。

转自 http://www.infoq.com/cn/news/2017/07/hengfeng-bank-micro-service-arch