Message Queue(以下簡稱MQ), 其實在UNIX的執行緒之間通訊就已經用到了MQ技術,
一個執行緒寫資料到特定的MQ中, 其他執行緒可以從隊列中讀取資料, 進而實現非同步通訊能力.
MQ相對於RPC通訊來說有以下優勢
模組之間的耦合降低
, 彼此不用在認識對方, 只要認識MQ使用它就好
消息、事件、請求的順序性
, 因為Queue的特性, 就是能保證先進先出
異步通訊能力, RPC畢竟是個同步請求, MQ則只需要同步調用到, 資料丟給MQ, 服務有收到就好; 算是完成了非同步
處理.
緩衝能力, 消峰
; 由於MQ的容量可以很大, 通常看記憶體給它的上限. 如果是用硬碟空間來存放Log的, 就幾乎無限容量了(加硬碟就好XD). 這樣子高峰期突來的請求流量, 就能被積壓起來在MQ內. 在後面的時間平滑地處理完成, 主要是保護DB, 讓DB不至於crash. 取用方根據自己的能力去MQ拉
資料回來處理就好.
舉例1: 電商秒殺活動(這例子很常出現XD)
大型電商都有引入MQ作為訊息中間件, 在架構之中.
舉例2:
通訊軟體中也很常用MQ, 做群組訊息推送, 因為像是JPush, APNS這些其實回覆速度很慢,
會需要把新訊息先緩存,讓推播服務依照自己消耗速率來消費, 但順序性很重要, 剛好MQ很適合.
當MQ收到新資料後, 主動調用Consumer的類似onMessage接口來通知處理. 這種消費方法, Consumer只能被動等待通知了.
Consumer輪詢調用MQ的接口來拿新資料. 相對的Client是主動權多很多.
Pull模式下, Consumber需要自己建立一個獨立的routine去拉取並且處理資料, 並不會浪費MQ執行緒資源來管理誰還沒拿. 缺點就是沒那麼實時.
Push模式下, 訊息的處理過程就會佔用到MQ的執行緒資源了, 需要掌控這段資料給consumer1, 哪一段給consumer2, consumer需要回ack回給MQ, 讓它知道處理資料的狀況. 優點就是很實時.
Push模式下, 當consumer offline或是消費速率不快時, MQ就需要持久化新進來的資料, 等consumer resume,或等它回了ack, 就得把大量積累的資料透過MQ的執行緒去處理.
沒辦法對方不在沒法問要不要扔了, 當然也可以做些設定保護MQ.
Pull就是, 反正也不管consumer狀況, MQ server不會做過多保證, 會定期清理.
Kafka、Nats就是用Pull模式.
Nats是Push還是Pull的討論
常見的MQ有RabbitMQ、Kafka、AciveMQ、NSQ, 小弟後面會介紹Nats.
小弟自己選型上, 會看預計吞吐量,有沒有破十萬以上; 再來是看我有沒有要做資料回溯.
因為RabbitMQ是沒有寫log的, 沒了就沒了. 吞吐量大概在1秒幾萬.
Kafka則是能透過log讀取出來回溯, 吞吐量可達百萬.
但大部分幾乎RabbitMQ就很夠用了, 因為Kafka頗複雜的.
小弟以前RabbitMQ簡介