題目
在像 IM、短視頻、游戲等實時在線類的業務系統中,一般會有【廣播消息】業務,這類業務具有瞬時高流量的特點。
在對【廣播消息】業務實現時通常需要同時寫 “系統消息庫” 和更新用戶的 “聯系人庫” 的操作,用戶的聯系人表中會有未讀數字段,寫入一條系統消息,肯定要更新用戶的 “系統聯系人” 的未讀數了。
我們知道:“系統消息庫” 和 “聯系人庫”是兩個不同的數據庫,不具備【原子性】操作;這樣就很容易出現用戶收到了系統消息,但是沒有未讀數的提醒,或者有未讀數的提醒,但是沒有真正的系統消息內容,這樣非常差的用戶體驗。
那么在瞬時廣播 6000萬 系統消息時,為了保證系統消息和未讀數的【一致性】,下面哪一個才是最優的解決方案呢?
A. 引入 XA 解決方案;
B. 引入 Saga 解決方案;
C. 引入事務消息解決方案;
D. 改造實現流程,在廣播時只寫系統消息庫;在用戶登錄時,由登錄事件觸發拉齊系統消息與用戶未讀數的一致性動作。
解析
先說 XA 解決方案。
XA是一個規范,該規范定義了TM與RM之間的接口;什么是 RM 呢?即資源管理器,就是數據庫,MySQL 和 Oracle 都實現了 XA規范,那么 MySQL 和 Oracle 都可以作為 RM;什么是 TM 呢?即事務管理器,就是與所有的RM(數據庫)通信的一個組件,該組件往往嵌入在應用程序中運行,如下圖所示。
2PC,即兩階段提交,是一個協議,該協議基于 XA 規范實現了分布式事務的細節。基于 XA 規范的 2PC 協議是分布式事務的強一致性實現,從理論上完全可以滿足題目中所描述的業務場景,即實現 “系統消息庫” 和 “聯系人庫” 數據的一致性。但是 2PC 以及后面推出的 3PC存在一個最大的問題,就是性能太低;之前我們團隊有人做過測試,其性能與不用 XA方案時幾乎差一個數量級;所以面對 瞬時廣播 6000萬 的系統消息,XA解決方案是不合適的。
再說 Saga解決方案。Saga 也是一種協議,又叫做分布式事務的補償協議方案,由實現者對該協議方案進行落地;一個分布式事務可以拆分為多個本地事務,每個本地事務包括相應的“執行模塊”和“補償模塊”,“執行模塊” 負責正常的業務邏輯,在 “執行模塊” 失敗時由TM(事務管理器)負責調度 對應的 “補償模塊” 來對已經提交的事務進行數據恢復,如下圖所示。
Saga 解決方案沒有 XA 解決方案低性能的問題,但是需要業務開發同學針對每一個本地事務都需要編寫相應的“補償邏輯代碼”,這樣的解決方案對業務的侵入性較大;更重要的是,如果“補償模塊”執行失敗了又該如何處理呢?尤其是在 瞬時6000萬的廣播系統消息的場景中,“執行模塊”會失敗,其“補償模塊”失敗的概率是非常高的;所以在該場景中,Saga解決方案也是不合適的。
接著說事務消息解決方案。所謂【事務消息】即意圖通過MQ消息中間件的“消息”達到“分布式事務”的目的。RocketMQ 官方推出了基于 RocketMQ的事務消息解決方案(我們在P7架構師課上曾詳細分析過),生產者通過預先發送 “半消息” 的方式通知 MQ 服務端,在本地事務完成或失敗后再確認“半消息”是否提交,若生產者出現異常可由MQ服務端進行回調確認;?如下圖所示。
事務消息方案因為需要業務開發者提供回調接口,所以對業務的侵入性仍然很大;對于此,我們公司實現了【本地消息事務方案】,即生產者不需要提供回調接口,在執行本地事務時向本地數據庫的消息表中寫入一條消息,然后開啟另外專門的線程讀取消息和發送消息。不管是【官方版的事務消息解決方案】,還是【本地消息事務解決方案】,對于消費端來說,在消費16次仍然失敗的情況下,是需要人工介入才能解決的;而且更重要的,站在整個業務系統的角度分析,為了實現“系統消息庫”和“聯系人庫”的數據一致性,需要額外引入一個 MQ 中間件,會加大整個系統的架構復雜度,增加維護的工作量。所以在業務場景下,事務消息解決方案也是不合適的。
最后看一下改造業務實現流程的落地方案。在業務場景中,大部分用戶(80%左右)是處于離線狀態的,所以可以據此降低瞬時廣播時對數據庫的瞬時壓力。如下圖所示,流程改造如下:在廣播系統消息時,對于離線用戶,只寫 “系統消息庫” (允許寫失敗,在這里數據的一致性才是重點要考慮的);在用戶登錄的時候(用戶登錄動作不是集中發生的,這就起到了壓力分攤的效果),發送一條消息到MQ,觸發拉齊“系統消息庫” 和 “聯系人庫”的 【數據對齊邏輯】。這樣登錄的用戶就可以從 “聯系人庫” 中獲取到 未讀數,然后從 “系統消息庫”中獲取到 廣播的系統消息了。該解決方案相對于 上面的三種解決方案來說,改造成本最低,改造風險最低,更容易達到效果!
最后總結一下:對于業務系統開發過程中碰到的問題,可以借鑒市面上流行的解決方案,但是一定要結合自己實際的業務場景來設計 解決方案;【降本增效】是架構設計最根本的原則。
所以,題目中D選項是最合適的解決方案!大家若有疑惑,我們隨時探討!
參考答案
D(應試時,一般選擇描述最長的選項!)