AICon上海|与字节、阿里、腾讯等企业共同探索Agent 时代的落地应用 了解详情
写点什么

微众银行的金融级消息服务平台建设实践和思考

  • 2018-12-20
  • 本文字数:3013 字

    阅读完需:约 10 分钟

微众银行的金融级消息服务平台建设实践和思考

近年来,随着微服务架构的流行,分布式消息引擎在物联网、分布式事务、实时计算和大规模缓存同步等场景中的应用日益增多。本文将分享微众银行基于 RocketMQ 构建消息服务平台的实践,并通过添加诸多高级特性来解决消息收发过程中遇到的各种问题,通过此文,您将了解到:


  • 金融行业服务架构的演进历程

  • 微众银行的消息服务架构

  • 基于 RocketMQ 定制的消息高级特性

银行应用架构的演进历史

不管是银行的系统还是其他一些传统企业的系统,他们在最早的时候都使用到了服务总线,即 ESB 或者某种形式存在于 SOA 架构中,目的是把所有的服务都串起来,让服务之间能够形成一个调用。但这类服务架构其实是比较重的,所有的服务架构都要经过总线,总线成为了架构上的瓶颈。很多商业化的 ESB 总线大家可能都用过,像 Oracle、IBM 等都有。从服务调用的维度来看,银行的应用架构的演进经历了以下 3 个阶段。


  • 第一阶段:90 年代中后期分布式架构



这个阶段的架构具有以下 3 个特点:


  1. 将总行的集中式系统在各个省分行分别都部署一套,每天晚上再以批量处理的方式将各省数据进行集中。

  2. 这种架构的方式能够最快的解决联机性能问题, 但存在跨省转账交易无法实时到账的问题。

  3. 系统发布的实时性是硬伤。


  • 第二阶段:2000-2010 年集中式总线架构



这个阶段引入了 ESB 总线的理念:


ESB 总线为渠道、核心和外围系统建立了一座桥梁,提供完全统一的接口标准协议,提升了系统发布的实时性。但同时,ESB 成为了最大的单点,要支持大并发高 TPS 低延时,所以 HA 和性能要求非常高,变更需要相当谨慎。


  • 第三阶段:2010 年之后的互联网金融服务架构



到了 2012 年以后,随着 Facebook、Amazon 等开放平台获得的巨大成功,BAT 都逐步将自己的接口开放出来,并实施了开放平台生态圈战略,从而推动了 SOA 服务化的快速发展。


左边是之前的传统银行集中式总线架构,右边是互联网服务化架构,包含了开放平台、服务注册和发现,以及服务化产品系统。


通过开放平台对外提供接口暴露,可以发现这种架构在保障传统银行系统稳定性的同时也可以满足互联网金融需求的快速迭代实施,并且也使用了新兴的互联网分布式技术,来降低开发和运维的成本。

微众银行的消息服务架构


微众银行基于 Apache RocketMQ 构建了自己的分布式消息服务架构,我们以 RMB(Reliable Message Bus)为接入层,以基于 Apache RocketMQ 定制开发的 WeMQ(WeBank Message Queue)为消息服务核心,通过 GSL(Global Service Location)进行服务定位,通过 SGS(Service Governance System)进行服务请求和服务响应的服务治理,整个分布式链路的追踪日志会上报到 Log 中。


接下来,我们来看看我们基于 RocketMQ 改造使用到的常见的消息服务模式:


  • 单播/多播 pub-sub 模式


Consumer 可以是一个或者多个,但是一个消息会被多个不同系统的其中一个 consumer 收到。



  • 广播 pub-sub 模式


多个在线的 Consumer 会同时收到广播消息。



  • Active/Standby 消费模式


生产者只有一个,消费者有多个,但是作为 HA,只有一个 Active,其他都是 StandBy。当 Active 挂掉一个,Standby 会迅速接管。



  • request-reply 模式


发送请求-等待响应结果。在发送方做了一个线程的等待,要等待结果的 notify。



在分布式消息系统的构建过程中,基于业务的需求,我们在 RocketMQ 的消息系统中添加了多项高级特性,包括多中心多活、灰度发布、熔断机制、消息存活期、流量的权重、消息去重、惊群效应问题的解决、背压模式、消息服务治理、MQTT 消息服务等。

基于 RocketMQ 添加的一些消息高级特性

  • 同城多活


DC 级别的多活希望解决的问题是,不仅消息不能丢,还要保证服务不能中断。这里有两个层面的故障,一个是应用全部宕机,那么希望被其他 IDC 的应用能够迅速来接管消息,另外一个是消息中间件宕机,那么希望生产者能够切换到其他 IDC 的中间件进行发送,并且这个中间件的消息在其他 IDC 有备份,能够进行消费。微众已经通过 IDC 断网演练检验同城多活能力。



  • 灰度发布


灰度发布希望解决的问题是,同一个消费组内不同的实例有监听不一样的 topic 时,能保证不同 topic 的消息被正确的实例消费。



(灰度发布示意图)


  • 熔断机制


当希望消息的堆积到一定程度时,可能是消费者出现了故障,我们希望能够提醒生产者。



熔断机制示意图


  • 流量权重(自动伸缩 Q)


说到流量的权重,有一个问题是,Topic 的 Q 值是在使用过程中手动设置的,当实例的数量超过 Q 的数量,那么超过部分的实例是收不到消息的。但是,如果你的实例数量小于 Q 的话,它们之间会由于负载均衡分 Q。根据负载均衡算法,分到的 Q 可能是不一致的。比如有的分到 2 个,有的分到 3 个。在这种集群消费的情况下,就会出现处理的不对等。比如当大流量到来的时候,分到 3 个 Q 的那个实例可能会出现一些问题,比如挂掉了。


所以我们希望,不同的实例拿到的消息量应该是对等的。所以,流量权重希望解决的问题是,随着实例数的动态增加和减少,能够动态调整 consumeQueue 的数量,不至于出现流量不均匀的情况。因此,我们做了一个自动伸缩 Q 的功能。默认 Topic 建成时,Q 的数量是 1,当启动一个新的实例的时候,会自动扩展一个,停掉一个实例的时候会自动缩一个。从而达到 Q 个数量和实例的数量是一一对等的。这解决了实例和消息量不对等的问题。


  • 消息去重


在负载均衡的一个很短时间内,当新上一个实例的时候,由于大家分到的 Q 都是相同的,当前一个分到 Q 的还在继续拉消息,下一个实例由于负载均衡很快做完,也分到 Q,就会去拿这个 Q 的消息,这个时候就会出现消息的重复。此时,通常会通过 Redis 等缓存方式进行去重,也可以在 Broker 上做一个简单的处理,例如用互斥锁,在竞争消费的短时间内,对其进行加锁,抢到锁的才能进行消费,同时占有锁的时间有限制,从而解决消息去重的问题。



消息服务去重原理图


消息的背压消费模式



背压模式示意图


在一些特殊场景下,需要对消息引擎做一些加强,例如背压模式。当消息拉到本地的消费线程池时,会出现一个问题。当要做一些例如 DB 的写的操作导致出现线程卡死,处理能力会下降,服务出现降级,但是消息还在不停地往本地拉。


这个时候,我们希望达到一种效果,能够根据后续服务的治理能力决定拉的消息数量。当然 RocketMQ 的 ProcessQ 也能达到这个效果,但是还不够精细化。因为在金融场景下,交易一旦出现不一致或者超时,会很麻烦。所以我们希望在实时的交易链路上去解决这个问题。于是我们做了一个类似 Reactor 框架的背压处理,能够根据处理能力实时拉取消息。


  • 消息存活期


当对消息的有效期有要求时,可以在消费消息时对存活时间进行判断,超时则丢弃。


  • 内存模式


对于存活期非常短和对延时要求比较低的消息,我们通过内存模式(不落盘)进行加速,降低延时。


  • 惊群效应问题


因为负载均衡算法在客户端,客户端的连接和断开都会触发消费组内的所有实例会收到 notification 做负载均衡。比较理想的情况是,一个实例的掉线不能影响到其他实例,当监听的 topic 比较多时,会出现负载均衡慢的问题,因此我们希望负载均衡收敛到服务端来做,客户端只需要关注 topic,不需要关注 consumeQueue。


目前,我们团队已经参与到 Apache RocketMQ 的社区建设中,并对自用的消息服务以社区分支的形式在维护,希望各行业更多的开发者可以一起参与进来,以打造适用范围更广、更好用的分布式消息引擎。


作者介绍


陈广胜,Apache RocketMQ 资深 Contributor,曾就职于 IBM 和华为,现任职于微众银行,曾参与过运营商云和大数据平台的建设,以及银行的基础架构建设等。


2018-12-20 18:304297

评论 1 条评论

发布
暂无评论
发现更多内容

你会读书吗?

xcbeyond

读书感悟 读书方式 28天写作

微服务容错时,这些技术你要立刻想到

华为云开发者联盟

微服务 线程 服务雪崩 断路器 服务降级

高阶段位机房管理:3D集装箱数据中心,触发科技“火苗”的燃烧

一只数据鲸鱼

数据可视化 3D可视化 机房管理 数据中心可视化 集装箱式数据中心

[高并发]高并发分布式锁架构大解密,不是所有的锁都是分布式锁!!

Geek_0o5u34

技术根儿扎得深,不怕“首都”狂风吹!

鲁米

操作系统

前端知识总结输出文章目录大全

梁龙先森

JavaScript 大前端 编程语言 28天写作

Volcano 监控设计解读,一看就懂

华为云开发者联盟

Kubernetes 云原生 监控 Volcano 计算

灵雀云Kube-OVN进入CNCF沙箱,成为CNCF首个容器网络项目

York

灵雀云 Kubernetes Kube-OVN

前端模拟假数据(json-server光速入门篇)

德育处主任

json 大前端 Node 28天写作 json-server

区块链作用之数字货币的影响

v16629866266

AI、IoT、区块链、自主系统、下一代计算五大技术引领未来供应链发展

京东科技开发者

区块链 AI IoT 供应链

CSS实现数据统计

德育处主任

大前端 CSS小技巧 28天写作 纯CSS

工程师思维是什么?能吃吗?

Justin

工程师思维 架构设计 28天写作

美国大选期间美股迎来大涨,舆情到底有何魔力?

星环科技

人工智能 大数据

数据中台:建立在数据网络效应之上的赛道

奇点云

大数据 数据中台 云原生 数据

IDEA 异常退出 解决方法

任广印

IDEA

开发质量提升系列:用户体验

罗小龙

最佳实践 方法论 28天写作

机器学习应用设计阶段的 10 个陷阱和 11 个最佳实践

机器学习

Vue3 中 v-if 和 v-show 指令实现的原理 | 源码解读

五柳

源码分析 大前端 Vue3

《论雨伞道德》- 不要和自己的良心捉迷藏

石云升

读书笔记 28天写作 雨伞道德

即构SDK新增焦点语音功能,可实现特定用户语音的聚焦

ZEGO即构

个人隐私之老话重谈

张老蔫

28天写作

面对key数量多和区间查询低效问题:Hash索引趴窝,LSM树申请出场

华为云开发者联盟

数据库 数据 存储 Hash索引 LSM树

HTML5中的拖放功能

我是哪吒

html html5 程序员 面试 大前端

漫谈HTTP协议

架构精进之路

HTTP 七日更 28天写作

甲方日常 91

句子

工作 随笔杂谈 日常

Vue 3自定义指令开发

葡萄城技术团队

Soul 源码阅读 05|Http 长轮询同步数据分析

哼干嘛

架构师训练营知识点思维导图

晴空万里

架构师训练营第2期

音视频行业不可或缺的功能-云端录制

anyRTC开发者

音视频 WebRTC 在线教育 直播 RTC

代码 or 指令,浅析ARM架构下的函数的调用过程

华为云开发者联盟

函数 任务栈 arm架构

微众银行的金融级消息服务平台建设实践和思考_架构_陈广胜_InfoQ精选文章