信用算力基于 RocketMQ 实现金融级数据服务的实践
微服務架構已成為了互聯網的熱門話題之一,而這也是互聯網技術發展的必然階段。然而,微服務概念的提出者 Martin Fowler 卻強調:分布式調用的第一原則就是不要分布式。
縱觀微服務實施過程中的弊端,可以推斷出作者的意圖,就是希望系統架構者能夠謹慎地對待分布式調用,這是分布式系統自身存在的缺陷所致。但無論是 RPC 框架,還是 REST 框架,都因為駐留在不同進程空間的分布式組件,而引入了額外的復雜度。因而可能對系統的效率、可靠性、可預測性等諸多方面帶來負面影響。
信用算力自2016年開始實施微服務改造,通過消息隊列(Message Queue),后文簡稱MQ,來規避微服務存在的缺陷,實現金融級數據服務。以下是一些使用場景和心得。
為什么需要 MQ
一、案例介紹
先來看一個當前的真實業務場景。
對于通過信息流獲客的企業而言,當用戶注冊時,因業務需求會調用用戶服務,然后執行一系列操作,注冊 -> 初始化賬戶信息 -> 邀友獎勵發放 -> 發放優惠券 -> ... -> 信息流數據上報。
用戶服務的開發人員壓力非常大,因為需要調用非常多的服務,業務耦合嚴重。如果當時賬戶服務正在執行發版操作,那么初始化賬戶動作會失敗。然而平臺經過不斷的迭代更新,后續又新增了一個簽到業務,新注冊用戶默認簽到一次。這就需要修改用戶服務,增加調用簽到服務的接口。每當遇到此種情況,開發用戶服務的同學就非常不爽了,為什么總是我?新增簽到業務和用戶服務又有什么關系?
為解決此類重度依賴的問題,我們在架構層面引入了 MQ,用來規避微服務之間重度耦合調用的弊端。新架構如下圖:
用戶完成注冊動作后,只需要往 MQ 發送一個用戶注冊的通知消息,下游業務如需要依賴注冊相關的數據,訂閱注冊消息的 topic 即可,從而實現了業務的解耦。
看完上述真實的案例后,大家可能產生疑惑,到底什么是 MQ,使用 MQ 又有什么好處?適合使用 MQ 的場景和不適合使用 MQ 的場景有哪些不同?
二、什么是 MQ?
簡單來說,MQ(MessageQueue)是一種跨進程的通信機制,用于上下游傳遞消息。
適合使用 MQ 的場景有:
1、上游不關心下游執行結果,例如上述案例中用戶注冊后,我們并不關心賬戶是否初始化,是否上報了信息流等;
2、異步返回執行時間長:例如上述案例中,當邀友獎勵發放,需要經歷很多風控規則,執行時間比較長,但是用戶并不關注獎勵何時發放。
不適合使用MQ場景
調用方實時關注執行結果,例如用戶發起注冊動作后,需要立刻知道,注冊結果是成功還是失敗,這種需要實時知道最終執行結果的場景,就不適合使用MQ。
三、使用MQ的好處:
1、解耦
2、可靠投遞
3、廣播
4、最終一致性
5、流量削峰
6、消息投遞保證
7、異步通信(支持同步)
8、提高系統吞吐、健壯性
MQ 的技術選型
目前業內比較主流的 MQ 包括 RocketMQ、ActiveMQ、RabbitMQ、Kafka等,關于性能、存儲、社區活躍度等各方面的技術對比已經很多,本文不再重復。
但我們發現通過簡單的選型對比,很難抉擇到底選擇哪款MQ產品。因為金融行業對于數據一致性以及服務可用性的要求非常高,所以任何關于技術的選項都顯得尤為重要。
經調研,如微眾銀行、民生銀行、平安銀行等國內知名的互聯網銀行和直銷銀行代表,都在使用 RocketMQ,且 RocketMQ 出生在阿里系,經受過各種生產壓力的考驗,非常穩定。并且,目前此項技術已經捐增給 Apache 社區,社區活躍度非常高。另外 RocketMQ 開發語言是Java,開發同學遇到解決不了的問題點,或者不清楚的概念,可以直接 Debug 源碼。經過多方面的比較,我們選擇 RocketMQ 作為規避微服務弊端的利器。
MQ 在微服務下的使用場景
MQ 是一種跨進程的通信機制,用于上下游傳遞消息,目前信用算力將 RocketMQ 應用于解耦、流量削峰、分布式事務的處理等幾個場景。
一、解耦
通常解耦的做法是生產者發送消息到 MQ,下游訂閱 MQ 的特定 topic,當下游接收到消息后開始處理業務邏輯。
那么,消息發送方到底應該是由誰來承擔?是服務提供者在處理完RPC請求后,根據業務需求開始發送消息嗎?但此刻開發人員就會抱怨為什么總是我?為什么處理完業務后需要發送 MQ?
為此,在解耦的過程中通過訂閱數據庫的 BinLog 日志,開發了一套 BinLog 日志解析模塊,專門解析日志,然后生成 JSON 字符串后發送消息到 MQ,下游訂閱 MQ 即可。流程如下:
目前所有需要依賴下游服務的業務線,其數據變動都采用此方案。
方案優缺點:
優點:
1、服務之間依賴完全解耦,任何基于注冊行為的業務變更,都無需依賴上游,只需訂閱MQ即可;
2、系統的穩定性和吞吐量增加了,用戶注冊的響應時間縮短了;
缺點:
1、引入MQ后系統復雜性增加,維護成本增加;
2、從注冊開始到全部數據初始化結束的整體時間增加了;
二、流量削峰
每逢遇到會員日的時候,平臺會發送大量的會員福利活動通知,以短信、站內信、PUSH 消息的方式通知注冊用戶。所有的消息會在很短的時間全部推送到消息中心,同時正常的業務通知任然有大量業務消息推送到消息中心。為保障平臺的穩定性和可靠性,在消息中心前置了多種 topic,如短信、推送、站內提醒。消息中心接收到消息后會全部寫入不同 topic 的 MQ,多個消費者來消費并把信息推送給終端用戶。
三、分布式事務
用戶在平臺上支付他訂購某種業務的時候,需要涉及到支付服務、賬戶服務、優惠券服務、積分服務,在單體模式下這種業務非常容易實現,通過事務即可完成,偽代碼如下:
然而,在微服務的情況下,原本通過簡單事務處理的卻變得非常復雜,若引入兩階段提交(2PC)或者補償事務(TCC)方案,則系統的復雜程度會增加。
信用算力的做法是通過本地事務 + MQ 消息的方式來解決, 雖然 RocketMQ 也支持事務消息,但是其他主流 MQ 并沒有此項功能,所以綜合考慮采用如下方案:
- 消息上游:需要額外建一個tc_message表,并記錄消息發送狀態。消息表和業務數據在同一個數據庫里面,而且要在一個事務里提交。然后消息會經過MQ發送到消息的消費方。如果消息發送失敗,會進行重試發送;
- 消息上游:開啟定時任務掃描tc_message表,如果超過設置的時間內狀態沒有變更,會再次發送消息到MQ,如重試次數達到上限則發起告警操作;
- 消息下游:需要處理這個消息,并完成自己的業務邏輯。此時如果本地事務處理成功,表明已經處理完成了,需要發起業務回調通知業務方;
方案優缺點:
優點:
1、用最小的代價實現分布式事物,以達到數據最終一致性;
2、方案非常靈活,任何環節都可以人為控制;
缺點:
1、復雜性增加了,業務操作的時候需要寫入 tc_message 表以及發送 MQ,同時還需要考慮狀態超時未變更的補發機制以及告警處理機制;
2、用戶看到的數據,存在有短暫不一致的情況;
心得體會
使用 RocketMQ 3年多了,總體來說運行的非常穩定,基本上沒有發生過生產事故,下面說說這幾年使用下來的心得體會:
1、一個應用盡可能用一個 Topic,消息子類型用 tags 來標識。Topic 名稱和 Tags 名稱可以自行設置。Producer,Consumer都需要規范,要做到見名知意。發送消息時候必須攜帶 Tags,消費方在訂閱消息時,才可以利用 Tags 在 Broker 做消息過濾。
2、每條消息在業務層面有唯一標識碼,方便在系統出現異常的情況,可以通過業務維度查詢。舉個栗子,當用戶在平臺注冊成功后,會以 Topic 和 UserID 作為唯一標識碼(topic_user_10011),服務器會為每個消息創建索引,該消息會持久化入庫,以防將來定位消息丟失等問題。下游收到消息后會以 Topic+Key 方式來記錄消費行為,包括消息日期、當前機器IP地址、處理結果等;也可以通過 Topic+Key 的方式來查詢這條消息內容,包括消息被誰消費,以及這條 MQ 在每個環節的處理狀態。
3、消息發送成功或者失敗,都需要記錄 log 日志,且必須打印 sendresult、MsgID、唯一標識碼。
4、由于上游會做消息重試機制,所以下游消息必須要做冪等處理。
5、需要封裝 MQ 的 API 在封裝后,API 需屏蔽底層 MQ 的特性,開發人員無需關注到底是用的哪個 MQ 來支持本地分布式事物、MQ 消息自動入庫、自動打印日志,減少開發人員操作成本。
總的來說,MQ 是一個互聯網架構中常見的解耦利器,在這3年中,信用算力在微服務中一直使用 MQ 來為金融客戶提供高質量的數據服務。雖然 MQ 不是唯一方案,但是從目前階段來看,的確是一種非常不錯的解決方案。
?
原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的信用算力基于 RocketMQ 实现金融级数据服务的实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云Kubernetes服务上使用Te
- 下一篇: 主流微服务注册中心浅析和对比