消息隊列使用場景
“喫不喫蝴蝶酥呀......”
在分佈式系統中,消息隊列扮演着重要的角色,是很重要的組件,主要解決應用解耦,異步消息,流量削峯等問題。可以實現高可用,高性能,最終一致性的架構。目前市面上使用較多的消息中間件:RocketMq,Kafka,RabbitMq,ActiveMq 等......
那麼在日常業務中,有什麼樣的使用場景呢?
場景一
一、當天交易滿三筆就送紅包?
1. 可以去直接掃描數據庫,當天滿三筆的用戶,直接贈送紅包
2. 查庫是否存在庫存,存在就鎖定,並提交訂單,然後查詢過往訂單,是否滿足第三筆,符合要求,就贈送紅包。
3. 運營活動是有時效性的,或者在贈送中的內容會經常變。造成這裏會被頻繁更改,但是核心邏輯基本沒有動,會對業務的穩定性造成影響。
所以這裏可以增加一個運營模塊。邏輯層中的所有 用戶下單,就可以發送一個 mq 消息,其他的運營邏輯都交給運營模塊來處理。那麼運營有自己的運營的 db,並且通過 rpc 去調用邏輯層的 db 服務。
二、拓展問題:
2.1 如果連續登錄 5 天贈送紅包怎麼實現?以及新用戶註冊贈送紅包
方案一:
1. 如果用戶登錄之後,以當前的時間戳和 uuid 進行往下結果集的判斷,可以查出用戶是否連續五天登錄。
2. 假設用戶用戶一天內會登錄很多次,那麼存在很多垃圾數據。
2.2 優化方案:
優化 1:判斷當天是否登陸過,如果登陸過,就不存儲了。或者說,存儲當天最早登錄時間和最後登錄時間,其他的時間點就不管了。
優化 2:
a. 用【當前時間戳 ts】%【246060】 ,可以得到當天過了多少秒,那麼使用 ts-ts%86400, 可以得到當天零點的時間戳。
b. 寫入的時候按照這個算法寫入,並且建立唯一索引,就會發現時間戳衝突,是唯一索引。
c. 按照這種存儲方式,我們就可以根據 now()> ts > 5 天前的時間戳,就可以根據返回值數量,是不是五天連續登陸。
優化 3: 如果超過 5 天的數據,就是垃圾數據。據此可以進一步優化
重新設計表 uuid timestamp loginbit(用一個位表示用戶登錄狀態)
0:表示這天沒來,
1:表示今天來過。
那麼一條記錄就可以存儲用戶三十天的登錄記錄。
首先用戶第一天來了,可以將 timestamp 存儲以及當前最後一位 bit 位改成 1,如果一天內多次登錄,可以將當天時間和數據庫的時間進行比較 ,num = (ts`-ts)%86400;
如果 num=1,那麼第二天連續登陸了
loginbit << num +1 可以將 bit 位左移 num 位,然後加一,就知道是否是連續登陸了;
如果是 5 天連續登錄,就可以和 0x1F 按位與 :0x1F & loginbit == 0x1F 就是五天連續登錄;
如果是 10 天連續登錄,就可以和 0x3FF 按位與 :0x3FF & loginbit == 0x3FF 就是十天連續登。
場景二
電商 IM
1.User1 和服務端 1 建立長連接,user2 和服務端 2 建立長連接;如果 user1 想給 user2 發送消息,那麼緩存如 redis 中會保存用戶的登錄信息,user :ip 等信息。
2. 根據這個信息,可以將消息發送給 user2;
3. 但是如果用戶沒有登錄,不在線
那麼我們需要將消息存儲起來。用戶關注了我們, 並且給用戶發送微信推送。
所以,如果用戶不在線,發送 mq 消息,一些擴展的邏輯直接在訂閱 mq 後,進行處理。比如用戶離線狀態和微信的推送等。
如果不停的往 IM 中進行增加,但是在 im 中是邊緣業務,但是在業務線中是核心業務。
所以我們可以將消息丟到 mq 裏面,然後進行廣播,每個業務線。與業務解耦。
場景三
用戶註冊後行爲
1. 同步類型
用戶調用註冊接口,註冊完成後,同步進行發註冊郵件、短信,發放優惠卷等。問題點在於這些非核心業務邏輯,拖慢註冊接口,如果後續接口服務有問題,可能會影響註冊。
2. 並行類型
用戶調用註冊接口後,異步並行調用發送註冊郵件、短信,發放優惠卷等。提升了系統性能,但是如果郵件接口 10ms,發放優惠卷接口 500ms,那麼整體接口也得 500ms 才完成,拉低了整個系統的性能;
3. 引入消息隊列
用戶註冊後,發送 mq 消息。各自的邏輯都訂閱這個 topic 來進行邏輯處理,這樣異步處理,可以提高系統的吞吐量。
筆者思考
我私以爲在日常業務中,沒有最好工具,只有最適合的工具。不同的業務場景中,不一樣的要求。在異步場景中,引入消息中間件確實能夠削峯填谷,異步解耦,但是確實也會提高系統的複雜性。在便利的同時,伴隨而來的複雜性增高也是不能避開的話題。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Sd5XpARhFmR_ecixZfAZDA