訊息中介軟體選型

奮鬥的小媛。發表於2020-12-16

目前開源的訊息中介軟體可謂是琳琅滿目,能讓大家耳熟能詳的就有很多,比如 ActiveMQ、RabbitMQ、Kafka、RocketMQ、ZeroMQ 等。不管選擇其中的哪一款,都會有用的不趁手的地方。有些大廠在長期的使用過程中積累了一定的經驗,其訊息佇列的使用場景也相對穩定固化,或者目前市面上的訊息中介軟體無法滿足自身需求,並且也具備足夠的精力和人力而選擇自研來為自己量身打造一款訊息中介軟體。但是絕大多數公司還是不會選擇重複造輪子,那麼選擇一款合適自己的訊息中介軟體顯得尤為重要。就算是前者,那麼在自研出穩定且可靠的相關產品之前還是會經歷這樣一個選型過程。

在整體架構中引入訊息中介軟體,勢必要考慮很多因素,比如成本及收益問題,怎麼樣才能達到最優的價效比?雖然訊息中介軟體種類繁多,但是各自都有各自的側重點,選擇合適自己、揚長避短無疑是最好的方式。

各類訊息佇列簡述

ActiveMQ 是 Apache 出品的、採用 Java 語言編寫的完全基於 JMS1.1 規範的面向訊息的中介軟體,為應用程式提供高效的、可擴充套件的、穩定的和安全的企業級訊息通訊。不過由於歷史原因包袱太重,目前市場份額沒有後面三種訊息中介軟體多。

RabbitMQ 是採用 Erlang 語言實現的 AMQP 協議的訊息中介軟體,最初起源於金融系統,用於在分散式系統中儲存轉發訊息。RabbitMQ 發展到今天,被越來越多的人認可,這和它在可靠性、可用性、擴充套件性、功能豐富等方面的卓越表現是分不開的。

Kafka 起初是由 LinkedIn 公司採用 Scala 語言開發的一個分散式、多分割槽、多副本且基於 zookeeper 協調的分散式訊息系統,現已捐獻給 Apache 基金會。它是一種高吞吐量的分散式釋出訂閱訊息系統,以可水平擴充套件和高吞吐率而被廣泛使用。目前越來越多的開源分散式處理系統如 Cloudera、Apache Storm、Spark、Flink 等都支援與 Kafka 整合。

RocketMQ 是阿里開源的訊息中介軟體,目前已經捐獻個 Apache 基金會,它是由 Java 語言開發的,具備高吞吐量、高可用性、適合大規模分散式系統應用等特點,經歷過雙 11 的洗禮,實力不容小覷。

ZeroMQ 號稱史上最快的訊息佇列,基於 C 語言開發。ZeroMQ 是一個訊息處理佇列庫,可在多執行緒、多核心和主機之間彈性伸縮,雖然大多數時候我們習慣將其歸入訊息佇列家族之中,但是其和前面的幾款有著本質的區別,ZeroMQ 本身就不是一個訊息佇列伺服器,更像是一組底層網路通訊庫,對原有的 Socket API 上加上一層封裝而已。

選型要點概述

功能維度

衡量一款訊息中介軟體是否符合需求需要從多個維度進行考察,首要的就是功能維度,這個直接決定了你能否最大程度上的實現開箱即用,進而縮短專案週期、降低成本等。如果一款訊息中介軟體的功能達不到想要的功能,那麼就需要進行二次開發,這樣會增加專案的技術難度、複雜度以及增大專案週期等。

優先順序佇列:
優先順序佇列不同於先進先出佇列,優先順序高的訊息具備優先被消費的特權,這樣可以為下游提供不同訊息級別的保證。不過這個優先順序也是需要有一個前提的:如果消費者的消費速度大於生產者的速度,並且訊息中介軟體伺服器(一般簡單的稱之為 Broker)中沒有訊息堆積,那麼對於傳送的訊息設定優先順序也就沒有什麼實質性的意義了,因為生產者剛傳送完一條訊息就被消費者消費了,那麼就相當於 Broker 中至多隻有一條訊息,對於單條訊息來說優先順序是沒有什麼意義的。

延遲佇列:
當你在網上購物的時候是否會遇到這樣的提示:“三十分鐘之內未付款,訂單自動取消”?這個是延遲佇列的一種典型應用場景。延遲佇列儲存的是對應的延遲訊息,所謂“延遲訊息”是指當訊息被髮送以後,並不想讓消費者立刻拿到訊息,而是等待特定時間後,消費者才能拿到這個訊息進行消費。延遲佇列一般分為兩種:基於訊息的延遲和基於佇列的延遲。基於訊息的延遲是指為每條訊息設定不同的延遲時間,那麼每當佇列中有新訊息進入的時候就會重新根據延遲時間排序,當然這也會對效能造成極大的影響。實際應用中大多采用基於佇列的延遲,設定不同延遲級別的佇列,比如 5s、10s、30s、1min、5mins、10mins 等,每個佇列中訊息的延遲時間都是相同的,這樣免去了延遲排序所要承受的效能之苦,通過一定的掃描策略(比如定時)即可投遞超時的訊息。

死信佇列:
由於某些原因訊息無法被正確的投遞,為了確保訊息不會被無故的丟棄,一般將其置於一個特殊角色的佇列,這個佇列一般稱之為死信佇列。與此對應的還有一個“回退佇列”的概念,試想如果消費者在消費時發生了異常,那麼就不會對這一次消費進行確認(Ack), 進而發生回滾訊息的操作之後訊息始終會放在佇列的頂部,然後不斷被處理和回滾,導致佇列陷入死迴圈。為了解決這個問題,可以為每個佇列設定一個回退佇列,它和死信佇列都是為異常的處理提供的一種機制保障。實際情況下,回退佇列的角色可以由死信佇列和重試佇列來扮演。

重試佇列:
重試佇列其實可以看成是一種回退佇列,具體指消費端消費訊息失敗時,為防止訊息無故丟失而重新將訊息回滾到 Broker 中。與回退佇列不同的是重試佇列一般分成多個重試等級,每個重試等級一般也會設定重新投遞延時,重試次數越多投遞延時就越大。舉個例子:訊息第一次消費失敗入重試佇列 Q1,Q1 的重新投遞延遲為 5s,在 5s 過後重新投遞該訊息;如果訊息再次消費失敗則入重試佇列 Q2,Q2 的重新投遞延遲為 10s,在 10s 過後再次投遞該訊息。以此類推,重試越多次重新投遞的時間就越久,為此需要設定一個上限,超過投遞次數就入死信佇列。重試佇列與延遲佇列有相同的地方,都是需要設定延遲級別,它們彼此的區別是:延遲佇列動作由內部觸發,重試佇列動作由外部消費端觸發;延遲佇列作用一次,而重試佇列的作用範圍會向後傳遞。

消費模式:
消費模式分為推(push)模式和拉(pull)模式。推模式是指由 Broker 主動推送訊息至消費端,實時性較好,不過需要一定的流制機制來確保服務端推送過來的訊息不會壓垮消費端。而拉模式是指消費端主動向 Broker 端請求拉取(一般是定時或者定量)訊息,實時性較推模式差,但是可以根據自身的處理能力而控制拉取的訊息量。

訊息回溯:
一般訊息在消費完成之後就被處理了,之後再也不能消費到該條訊息。訊息回溯正好相反,是指訊息在消費完成之後,還能消費到之前被消費掉的訊息。對於訊息而言,經常面臨的問題是“訊息丟失”,至於是真正由於訊息中介軟體的缺陷丟失還是由於使用方的誤用而丟失一般很難追查,如果訊息中介軟體本身具備訊息回溯功能的話,可以通過回溯消費復現“丟失的”訊息進而查出問題的源頭之所在。訊息回溯的作用遠不止與此,比如還有索引恢復、本地快取重建,有些業務補償方案也可以採用回溯的方式來實現。

訊息堆積 + 持久化:
流量削峰是訊息中介軟體的一個非常重要的功能,而這個功能其實得益於其訊息堆積能力。從某種意義上來講,如果一個訊息中介軟體不具備訊息堆積的能力,那麼就不能把它看做是一個合格的訊息中介軟體。訊息堆積分記憶體式堆積和磁碟式堆積。一般來說,磁碟的容量會比記憶體的容量要大得多,對於磁碟式的堆積其堆積能力就是整個磁碟的大小。從另外一個角度講,訊息堆積也為訊息中介軟體提供了冗餘儲存的功能。

效能

功能維度是訊息中介軟體選型中的一個重要的參考維度,但這並不是唯一的維度。有時候效能比功能還要重要,況且效能和功能很多時候是相悖的,魚和熊掌不可兼得。訊息中介軟體的效能一般是指其吞吐量和時延。

訊息中介軟體的吞吐量始終會受到硬體層面的限制。就以網路卡頻寬為例,如果單機單網路卡的頻寬為 1Gbps,如果要達到百萬級的吞吐,那麼訊息體大小不得超過 (1Gb/8)/100W,即約等於 134B,換句話說如果訊息體大小超過 134B,那麼就不可能達到百萬級別的吞吐。這種計算方式同樣可以適用於記憶體和磁碟。

時延作為效能維度的一個重要指標,卻往往在訊息中介軟體領域所被忽視,因為一般使用訊息中介軟體的場景對時效性的要求並不是很高,如果要求時效性完全可以採用 RPC 的方式實現。雖然不建議在時效性很高的場景下使用訊息中介軟體,但是如果所使用的訊息中介軟體的時延方面比較優秀,那麼對於整體系統的效能將會是一個不小的提升。

可靠性 + 可用性

訊息丟失是使用訊息中介軟體時所不得不面對的一個同點,其背後訊息可靠性也是衡量訊息中介軟體好壞的一個關鍵因素。尤其是在金融支付領域,訊息可靠性尤為重要。然而說到可靠性必然要說到可用性,注意這兩者之間的區別,訊息中介軟體的可靠性是指對訊息不丟失的保障程度;而訊息中介軟體的可用性是指無故障執行的時間百分比。

運維管理

在訊息中介軟體的使用過程中難免會出現各式各樣的異常情況,有客戶端的,也有服務端的,那麼怎樣及時有效的進行監測及修復。業務線流量有峰值又低谷,尤其是電商領域,那麼怎樣前進行有效的容量評估,尤其是大促期間?腳踢電源、網線被挖等事件層出不窮,如何有效的做好異地多活?這些都離不開訊息中介軟體的衍生產品——運維管理。

運維管理也可以進行進一步的細分,比如:申請、稽核、監控、告警、管理、容災、部署等。

申請、稽核很好理解,在源頭對資源進行管控,既可以進行有效校正應用方的使用規範,配和監控也可以做好流量統計與流量評估工作,一般申請、稽核與公司內部系統交融性較大,不適合使用開源類的產品。

監控、告警也比較好理解,對訊息中介軟體的使用進行全方位的監控,即可以為系統提供基準資料,也可以在檢測到異常的情況配合告警,以便運維、開發人員的迅速介入。除了一般的監控項(比如硬體、GC 等)之外,對於訊息中介軟體還需要關注端到端時延、訊息審計、訊息堆積等方面。

3972450-91d3c39ade57439d.png

相關文章