消息隊列使用場景

“喫不喫蝴蝶酥呀......”

        在分佈式系統中,消息隊列扮演着重要的角色,是很重要的組件,主要解決應用解耦,異步消息,流量削峯等問題。可以實現高可用,高性能,最終一致性的架構。目前市面上使用較多的消息中間件: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