天天看點

MQ在業務中的使用方式

最近一直在思考公司使用的rocketMQ的元件業務設計的問題, 
因為公司在使用上比較随意, 即使出了規範, 該規範也是比較零散缺乏統一的模型, 也沒有系統性的解決設計問題,            

背景

1. MQ搭建的系統, 目标之一是要做到事件驅動化系統, 他的優點有很多這裡不一一細說

2. RocketMQ, 有Topic, Tag, ConsumerGroup, ProducerGroup這幾個概念, 其中Topic, Tag功能相同, 隻是分組更細化, 是以這裡為了簡化問題, 将它們合二為一, ProducerGroup 在本次業務設計中用不到, 我們就當全局隻有一個提供者, 是以這裡的設計就隻針對, tag 和 ConsumerGroup 兩個, tag可以了解為對事件的定義或者命名, ConsumerGroup 可以了解為事件的消費者定義. 是以整個流程就是, 統一的發送者ProducerGroup, 發送不同的消息tag, 然後由不同的消費者ConsumerGroup處理, 一個消費者可以處理多個消息, 多個消費者也可以處理同一個消息

3. 簡化問題: 
    事件:消息 = 1:1, 可以把事件看作是消息
    Topic = Tag = 事件
    ProducerGroup = 1
    
4. 在能解決實際問題的前提下(包含業務問題和非業務問題), 事件和消費者 數量越少越好           

設計要解決的問題

1. 事件的定義次元是什麼? 
2. 事件有沒有固定的數量? 或者這個固定的數量來源依據是什麼?
3. 事件消費者定義的次元是什麼?
4. 事件消費者有沒有固定的數量? 或者這個固定的數量來源依據是什麼?

為什麼關心數量? 
    數量: 解決數量的問題, 1. 同等作用下, 數量越少越好, 2. 便于分類管理和便于了解

為什麼關心定義的次元?
    次元: 解決定義的次元問題, 1. 是為了統一模型, 統一思路, 2. 找出能解決上述問題的次元, 3. 便于了解, 便于定位           

方案

事件次元: 
    建議以訂單常用可變化狀态作為次元(比如訂單主狀态, 訂單支付狀态等)
    優點: 
        1. 極其便于了解和定位, 
        2. 能解決數量問題
事件數量: 
    數量 <= 主狀态數量 * 支付狀态數量
    優點: 
        1. 數量不大于狀态數量的乘積, 有上限, (如果沒有指定次元, 而是憑借業務, 則很有可能因為對業務的了解不一緻導緻事件數量沒有上限)
        
消費者次元:
    建議以業務為作為次元, 似乎隻能以業務作為次元, 消費者本身就是驅動不同業務的, 而業務是千變萬化的, 
    
消費者數量:
    數量 >= 事件數量
        ~= 可變化狀态數1 * 可變化狀态數2 * 不變狀态數1 * 不變狀态數2 * 業務系數n
        
名詞解釋:
    可變化狀态: 會随着訂單生命周期變化而變化的狀态, 比如: 訂單狀态, 支付狀态
    可變化狀态數: 指的是可變化狀态的取值範圍, 比如: 支付狀态取值有三種, 已支付, 未支付, 無需支付, 那可變化狀态數 = 3
    不可變化狀态: 不會随着訂單生命周期變化而變化的狀态, 但同時由标記訂單的某種業務類型的字段, 比如: 實時單, 預約單
    不可變化狀态數: 不可變化狀态的取值範圍
    業務系數n: 指的是同一個場景下, 需要處理的業務數量, 也正是因為此系數的存在, n取值 1-正無窮, 才使得消費者數量可以無窮多           

其他問題

1. 事件的定義以狀态變化作為次元, 那麼一些業務場景會同時觸發多個狀态同時發生變化, 那這個時候需要發幾個事件呢?
    方案:
        1. 還是以狀态為準, 如果有兩個狀态發生變化, 那就發送兩個事件, 消費者根據自己業務關注點的不同來自主選擇監聽哪個事件. 
        2. 多個狀态的變化很多時候有依賴關系, 應該把有依賴關系的事件分開獨立處理, 比如: 訂單已支付和訂單開始派車, 幾乎是同時發生的, 可以寫在同一個業務中, 但是開始派車是依賴于已支付的是以要分成兩個事件讓他們又先後依賴關系.
        
2. 有些事件是沒有狀态發生變化的
    方案:
        1. 有些事件比如創單成功, 對于資料來說就是從無到有, 是以可以把事件看作是從null變成初始值, 這樣也可以定義事件的
        2. 還有寫業務是根據有無關聯表來判斷業務狀态的, 而關聯的表并沒有狀态
            方案: 
                1. 業務定義的時候建議加上字段區分業務而不是通過有無資料進行區分
                2. 如果關聯表有相關狀态, 可以進一步将事件細化到關聯表的狀态上
        3. 宏觀上, 資料的有無可以看做一種狀态
        
3. 如果某個消費先定義, 如果想觸發這個消費業務就要發送已經定義好的tag, 要如何實作?
    方案: 
        1. 這種使用方式不在上述模型中, 同時在非必要的情況下, 不建議使用這種方式
        2. 如果使用這種方式, 則可以添加一層消費者中轉, 消費者監聽指定的事件, 同時消費者所處理的業務就是發送下一個事件, 這樣既能做到解耦, 又可以相容原有模型           

歡迎探讨

繼續閱讀