需求
需要前端展示實時的訂單資料資訊。如下圖所示,實時下單實時頁面統計更新展示
思路方案
前端使用websocket 建立通訊
後端監聽資料庫的binglog變更,實時得到最新資料,推播到前端
現狀及問題
使用者端想實現實時獲取資料的變更,使用了websocket+kafkaMq,當資料庫變更的時候,通過mq傳送變更資訊到佇列,伺服器端消費。
由於使用者端與伺服器端websocket連線,是單臺伺服器建立通道,資料庫變更到伺服器消費,只會是其中一臺伺服器消費,其他伺服器消費不到,導致其他伺服器連線的使用者端,接收不到實時的資料。
解決方案
根據以上問題,目前發現四個解決方案
方案名 |
描述 |
優缺點 |
改動點 |
redis+定時 |
當伺服器A消費時,在redis裡存下所需推播的全部資訊 所有伺服器都啟動一個定時器,定時遍歷redis中需要推播的,根據當前伺服器socket的連線,推播對應使用者端 |
優點:在消費成功以及存redis成功後,可以保證實時資料不丟失,都能推到 缺點: 有定時,偽實時,處理邏輯相對複雜 每臺伺服器都遍歷一次所有的資料,資源浪費 |
增加定時器,在定時器里根據redis裡存的實時資料,一一推播到與本伺服器連線的使用者端 |
kafka多個消費組 |
目前所有伺服器都設定了同一消費組,kafka推播的時候,若是在同一分組則只推其中一個,可以考慮把每個伺服器的分組按照ip+分組名來分組,形成,一個伺服器是一個分組,則可以都推播到 |
優點:廣播形式,推播到所有伺服器,實時性有保證,訊息不易丟失 缺點: 每臺伺服器都消費所有資料,資源浪費 |
修改基礎元件,或者新寫消費者程式碼中分組部分 |
rocketMq佇列 |
資料庫變動時,通過rocketMq佇列傳送訊息,rocketMq支援廣播形式 |
優點:廣播形式,推播到所有伺服器,實時性有保證,訊息不易丟失 缺點: 每臺伺服器都消費所有資料,資源浪費
|
1、接收到資料庫變更資訊後,傳送mq 2、增加rocketMq消費業務程式碼實現 |
redis釋出訂閱 |
每個伺服器通過redis都訂閱固定頻道的訊息 當某個伺服器得到資料庫變更時,在redis裡存好實時資料,然後再在redis頻道傳送變更的key 所有伺服器裡訂閱到訊息後,根據key查詢redis中實時資料,推播到使用者端 |
優點:redis廣播,實時性有保證,輕量,易實現 缺點: 每臺伺服器都消費所有資料,資源浪費 若redis因為網路不穩定,會導致沒有訂閱到,訊息易丟失,不保證訊息必達 |
1、增加redis訂閱頻道 2、消費處增加傳送頻道資訊功能 |
方案流程圖
redis+定時
kafka多個消費組
rocketMq佇列
redis釋出訂閱
優化
根據以上方案,發現一個統一的優化點,即每臺伺服器都會遍歷實時資料,不夠精準,後期可以通過,redis和分組裡加ip來,相對精準推播。。
後記
主要是提供一個思路,漏洞或許也很多,歡迎大家不吝賜教。
參考:
websocket 詳解:https://blog.csdn.net/weixin_50339217/article/details/125160323
websocket 叢集處理方案:https://www.cnblogs.com/yangjl01/p/12740836.html
監聽資料庫變化參考:
https://blog.csdn.net/Zxb654614425/article/details/129057114
https://blog.csdn.net/qq_45821251/article/details/127490460
redis 釋出訂閱 : https://blog.csdn.net/w15558056319/article/details/121490953
前端實時更新資料的幾種方式:https://www.jianshu.com/p/b7b363e5352a
其他參考:https://blog.csdn.net/qi923701/article/details/79253779