提到消息隊列,大家一定不陌生,無論是在校、面試還是工作,我們涉及得都很多。
有需求就有供應,市面上消息隊列當然非常多,算得上主流的也有5、6個,而大家可能由于對某一種隊列比較熟悉,就一直用它,大概就是亞瑟打野、亞瑟上路、亞瑟中路、亞瑟輔助。
但你有思考過嗎引入的隊列是否是最合适的嗎?
它與其它隊列相比有什麼優勢嗎?
可以說,選型是開發工作中最重要,也是最體現能力的一環。今天牛牛就來給大家介紹下消息隊列如何抉擇。
消息隊列是什麼?
消息隊列,顧名思義就是傳遞消息的隊列,有着先入先出的特性,既然是隊列,自然遵循先入先出的原則,同時,消息隊列具備可靠性、高性能等特點。
消息隊列是大型分布式系統不可缺少的中間件,一般用于異步流程、消息分發、流量削鋒等問題,可以通過消息隊列實現高性能、高可用、高擴展的架構。
業界比較出名的消息隊列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ。
那大家就會問了,這麼多消息隊列,我選誰好呢?
别急,我們先來深入理一理消息隊列的應用場景,以及每個隊列的特色,知道這些信息,才好做出決策。
消息隊列的應用場景
- 異步
如果一個接口,處理時間很長,而且不能通過水平擴容來解決,就需要異步,那麼,什麼情況下不能通過水平擴容解決呢?
有很多,比如視頻處理,涉及到視頻下載,那受限于網絡帶寬等因素,擴容無用;比如區塊鍊這種共識場景,隻有單機才能出塊,擴容也沒有用;還有更常見的,比如一個業務流程,過了10多個微服務,單個也許不長,加起來就很難接受。
以上的情況下,用戶很難通過同步接口長時間等待結果,那就應該做成異步,先扔進消息隊列,後續再進行消費,響應時間可以從10s,降低到10ms。
2.消息分發
假設一個核心服務A,是用來發布某種信号的,發布之後,需要通知到下遊服務B、C,這種模式在隻有B、C兩兄弟的時候,沒啥問題。
但随着業務需要,可能會有D、E、F等更多的打工人出現,這時候A服務就需要更改代碼,将消息也傳遞給這些新加入的兄弟,每次增加打工人,就需要更改一次代碼。
而引入消息隊列,則可以解決這個問題,實現能力複用,業務解耦。
3.削峰
業務有個概念叫峰值流量,也就說流量在一段時間遠大于平時,從視圖上看就像一個山峰。比如天貓雙十一秒殺日,特别是0點的時候,流量起碼是平常的千倍以上,如果不做好處理,一波就能徹底将服務打死。
如果常備1000倍流量的設備,那是極大的成本浪費,如果臨時調配,進行服務擴容,很多時候又不如想象得簡單。
之前有和Shopee的同學聊過,一到活動日他們就得緊鑼密鼓去做擴容,擴容之後還得熬更守夜地做壓測,不光勞命傷财、還容易出事故。
消息隊列可以優雅地解決這個問題,将雙十一的請求扔入消息隊列,等待後續服務慢慢處理,如下圖所示。
其實在架構上,削峰和上面的異步場景是相同的架構,都是将請求扔入隊列中,再慢慢消費。
但要注意異步場景是單個請求,本身處理時間很長。削峰針對是單個請求ok,但是流量突發的場景。
消息隊列能力對比
上面有提到幾個知名的消息隊列,其中ZeroMQ太過輕量,主要用于學習,實際是不會應用到生産,我們就Kafka、ActiveMQ、RabbitMQ、RocketMQ來進行不同維度對比。
特性 |
ActiveMQ |
RabbitMQ |
RocketMQ |
Kafka |
單機吞吐量 |
萬級 |
萬級 |
10 萬級 |
10 萬級 |
時效性 |
毫秒級 |
微秒級 |
毫秒級 |
毫秒級 |
可用性 |
高(主從) |
高(主從) |
非常高(分布式) |
非常高(分布式) |
消息重複 |
至少一次 |
至少一次 |
至少一次 最多一次 |
至少一次 最多一次 |
消息順序性 |
有序 |
有序 |
有序 |
分區有序 |
支持主題數 |
千級 |
百萬級 |
千級 |
百級,多了性能嚴重下滑 |
消息回溯 |
不支持 |
不支持 |
支持(按時間回溯) |
支持(按offset回溯) |
管理界面 |
普通 |
普通 |
完善 |
普通 |
消息隊列選型
選型的時候,我們需要根據業務場景,結合上述特性來進行選型。
比如你要支持天貓雙十一類超大型的秒殺活動,這種一錘子買賣,那管理界面、消息回溯啥的不重要。
我們需要看什麼?看吞吐量!
所以優先選Kafka和RocketMQ這種更高吞吐的。
比如做一個公司的中台,對外提供能力,那可能會有很多主題接入,這時候主題個數又是很重要的考量,像Kafka這樣百級的,就不太符合要求,可以根據情況考慮千級的RocketMQ,甚至百萬級的RabbitMQ。
又比如是一個金融類業務,那麼重點考慮的就是穩定性、安全性,分布式部署的Kafka和Rocket就更有優勢。
特别說一下時效性,RabbitMQ以微秒的時效作為招牌,但實際上毫秒和微秒,在絕大多數情況下,都沒有感知的區别,加上網絡帶來的波動,這一點在生産過程中,反而不會作為重要的考量。
其它的特性,如消息确認、消息回溯,也經常作為考量的場景,管理界面的話試公司而定了,反正牛牛呆過的地方,都不看重這個,畢竟都有自己的運維體系。
最後
本次,牛牛給大家分享了消息隊列是什麼、解決什麼問題、每種隊列的特性,以及怎麼結合場景和特性做分析。
面試時可以針對每個場景的不同因地制宜選取隊列,這樣不僅可以展現知識的全面性還可以體現出自己分析問題的能力。
而在實際的工作中,我們需要考慮的則更多,比如團隊的技術棧、經濟成本等情況進行綜合分析。隻有熟悉每個消息隊列的優劣,才能好中取優,選出适合的方案。
,