天天看點

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

阿裡妹導讀:近年來,随着微服務架構的流行,分布式消息引擎在物聯網、分布式事務、實時計算和大規模緩存同步等場景中的應用日益增多。

本文将分享微衆銀行基于RocketMQ建構消息服務平台的實踐,通過添加諸多進階特性來解決消息收發過程中遇到的各種問題。你将了解到:金融行業服務架構的演進曆程、微衆銀行的消息服務架構以及基于RocketMQ定制的消息進階特性。

銀行應用架構的演進曆史

不管是銀行的系統還是其他一些傳統企業的系統,他們在最早的時候都使用到了服務總線,即ESB或者某種形式存在于SOA架構中,目的是把所有的服務都串起來,讓服務之間能夠形成一個調用。但這類服務架構其實是比較重的,所有的服務架構都要經過總線,總線成為了架構上的瓶頸。很多商業化的ESB總線大家可能都用過。從服務調用的次元來看,銀行的應用架構的演進經曆了以下3個階段。

第一階段:90年代中後期分布式架構

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

這個階段的架構具有以下3個特點:

1.将總行的集中式系統在各個省分行分别都部署一套,每天晚上再以批量處理的方式将各省資料進行集中。

2.這種架構的方式能夠最快的解決聯機性能問題, 但存在跨省轉賬交易無法實時到賬的問題。

3.系統釋出的實時性是硬傷。

第二階段:2000-2010年集中式總線架構

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

到了2012年以後,随着各個海外開放平台獲得的巨大成功,一線網際網路公司都逐漸将自己的接口開放出來,并實施了開放平台生态圈戰略,進而推動了SOA服務化的快速發展。

左邊是之前的傳統銀行集中式總線架構,右邊是網際網路服務化架構,包含了開放平台、服務注冊和發現,以及服務化産品系統。

通過開放平台對外提供接口暴露,可以發現這種架構在保障傳統銀行系統穩定性的同時也可以滿足網際網路金融需求的快速疊代實施,并且也使用了新興的網際網路分布式技術,來降低開發和運維的成本。

####微衆銀行的消息服務架構

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

微衆銀行基于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收到。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

廣播pub-sub模式

多個線上的Consumer會同時收到廣播消息。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

Active/Standby消費模式

生産者隻有一個,消費者有多個,但是作為HA,隻有一個Active,其他都是StandBy。當Active挂掉一個,Standby會迅速接管。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

request-reply模式

發送請求-等待響應結果。在發送方做了一個線程的等待,要等待結果的notify。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

在分布式消息系統的建構過程中,基于業務的需求,我們在RocketMQ的消息系統中添加了多項進階特性,包括多中心多活、灰階釋出、熔斷機制、消息存活期、流量的權重、消息去重、驚群效應問題的解決、背壓模式、消息服務治理、MQTT消息服務等。

基于RocketMQ添加的一些消息進階特性

同城多活

DC級别的多活希望解決的問題是,不僅消息不能丢,還要保證服務不能中斷。這裡有兩個層面的故障,一個是應用全部當機,那麼希望被其他IDC的應用能夠迅速來接管消息,另外一個是消息中間件當機,那麼希望生産者能夠切換到其他IDC的中間件進行發送,并且這個中間件的消息在其他IDC有備份,能夠進行消費。微衆已經通過IDC斷網演練檢驗同城多活能力。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

灰階釋出

灰階釋出希望解決的問題是,同一個消費組内不同的執行個體有監聽不一樣的topic時,能保證不同topic的消息被正确的執行個體消費。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

熔斷機制

當希望消息的堆積到一定程度時,可能是消費者出現了故障,我們希望能夠提醒生産者。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

流量權重(自動伸縮Q)

說到流量的權重,有一個問題是,Topic的Q值是在使用過程中手動設定的,當執行個體的數量超過Q的數量,那麼超過部分的執行個體是收不到消息的。但是,如果你的執行個體數量小于Q的話,它們之間會由于負載均衡分Q。根據負載均衡算法,分到的Q可能是不一緻的。比如有的分到2個,有的分到3個。在這種叢集消費的情況下,就會出現處理的不對等。比如當大流量到來的時候,分到3個Q的那個執行個體可能會出現一些問題,比如挂掉了。

是以我們希望,不同的執行個體拿到的消息量應該是對等的。是以,流量權重希望解決的問題是,随着執行個體數的動态增加和減少,能夠動态調整consumeQueue的數量,不至于出現流量不均勻的情況。是以,我們做了一個自動伸縮Q的功能。預設Topic建成時,Q的數量是1,當啟動一個新的執行個體的時候,會自動擴充一個,停掉一個執行個體的時候會自動縮一個。進而達到Q個數量和執行個體的數量是一一對等的。這解決了執行個體和消息量不對等的問題。

消息去重

在負載均衡的一個很短時間内,當新上一個執行個體的時候,由于大家分到的Q都是相同的,目前一個分到Q的還在繼續拉消息,下一個執行個體由于負載均衡很快做完,也分到Q,就會去拿這個Q的消息,這個時候就會出現消息的重複。此時,通常會通過Redis等緩存方式進行去重,也可以在Broker上做一個簡單的處理,例如用互斥鎖,在競争消費的短時間内,對其進行加鎖,搶到鎖的才能進行消費,同時占有鎖的時間有限制,進而解決消息去重的問題。

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

消息服務去重原理圖

消息的背壓消費模式

如何用 RocketMQ 打造金融級消息服務平台?微衆銀行這麼做

背壓模式示意圖

在一些特殊場景下,需要對消息引擎做一些加強,例如背壓模式。當消息拉到本地的消費線程池時,會出現一個問題。當要做一些例如DB的寫的操作導緻出現線程卡死,處理能力會下降,服務出現降級,但是消息還在不停地往本地拉。

這個時候,我們希望達到一種效果,能夠根據後續服務的治理能力決定拉的消息數量。當然RocketMQ的ProcessQ也能達到這個效果,但是還不夠精細化。因為在金融場景下,交易一旦出現不一緻或者逾時,會很麻煩。是以我們希望在實時的交易鍊路上去解決這個問題。于是我們做了一個類似Reactor架構的背壓處理,能夠根據處理能力實時拉取消息。

消息存活期

當對消息的有效期有要求時,可以在消費消息時對存活時間進行判斷,逾時則丢棄。

記憶體模式

對于存活期非常短和對延時要求比較低的消息,我們通過記憶體模式(不落盤)進行加速,降低延時。

驚群效應問題

因為負載均衡算法在用戶端,用戶端的連接配接和斷開都會觸發消費組内的所有執行個體會收到notification做負載均衡。比較理想的情況是,一個執行個體的掉線不能影響到其他執行個體,當監聽的topic比較多時,會出現負載均衡慢的問題,是以我們希望負載均衡收斂到服務端來做,用戶端隻需要關注topic,不需要關注consumeQueue。

目前,我們團隊已經參與到Apache RocketMQ的社群建設中,并對自用的消息服務以社群分支的形式在維護,希望各行業更多的開發者可以一起參與進來,以打造适用範圍更廣、更好用的分布式消息引擎。

原文釋出時間為:2018-01-09

本文作者:陳廣勝

本文來自雲栖社群合作夥伴“

阿裡技術

”,了解相關資訊可以關注“

”。