2019第1週日-MQ選型要點

用消息中間件猶如小馬過河,選擇合適的才最重要,這須要貼合自身的業務需求,技術服務於業務。具體在選擇上可從下面功能、性能、可靠性和可用性、運維管理、社區和生態、團隊技術棧等維度來進行篩選。html

具體技術選型指標1:功能ios

首要的就是功能維度,這個直接決定了你可否最大程度上的實現開箱即用,進而縮短項目週期、下降成本等。若是一款消息中間件的功能達不到想要的功能,那麼就須要進行二次開發,這樣會增長項目的技術難度、複雜度以及增大項目週期等。程序員

功能維度又能夠劃分個多個子維度,大體能夠分爲如下這些。編程

  1. 優先級隊列:優先級高的消息先被消費,若消費速度大於生產速度,MQ中沒消息堆積,那沒多大意義;
  2. 延遲隊列:延遲隊列存儲的是對應的延遲消息,所謂「延遲消息」是指當消息被髮送之後,並不想讓消費者馬上拿到消息,而是等待特定時間後,消費者才能拿到這個消息進行消費。
  3. 死信隊列:存沒法被正確投遞消費的消息,避免不能消費的回退消息放在隊列頂部,不斷被處理和回滾陷入死循環。
  4. 重試隊列:指消費端消費消息失敗時,爲防止消息無端丟失而從新將消息回滾到 Broker 中。通常分紅多個重試等級,每一個重試等級通常也會設置從新投遞延時,重試次數越多投遞延時就越大。爲此須要設置一個上限,超過投遞次數就入死信隊列。
  5. 消費模式:消費模式分爲推(push)模式和拉(pull)模式。推模式是指由 Broker 主動推送消息至消費端,實時性較好,不過須要必定的流制機制來確保服務端推送過來的消息不會壓垮消費端。而拉模式是指消費端主動向 Broker 端請求拉取(通常是定時或者定量)消息,實時性較推模式差,可是能夠根據自身的處理能力而控制拉取的消息量。
  6. 廣播消費:消息通常有兩種傳遞模式:點對點(P2P,Point-to-Point)模式和發佈 / 訂閱(Pub/Sub)模式。
  7. 消息回溯:指消息在消費完成以後,還能消費到以前被消費掉的消息。對於消息而言,常常面臨的問題是「消息丟失」,至因而真正因爲消息中間件的缺陷丟失仍是因爲使用方的誤用而丟失通常很難追查,若是消息中間件自己具有消息回溯功能的話,能夠經過回溯消費復現「丟失的」消息進而查出問題的源頭之所在。消息回溯的做用遠不止與此,好比還有索引恢復、本地緩存重建,有些業務補償方案也能夠採用回溯的方式來實現。
  8. 消息堆積 + 持久化:流量削峯是消息中間件的一個很是重要的功能,而這個功能其實得益於其消息堆積能力。消息堆積份內存式堆積和磁盤式堆積。RabbitMQ 是典型的內存式堆積,但這並不是絕對,在某些條件觸發後會有換頁動做來將內存中的消息換頁到磁盤(換頁動做會影響吞吐),或者直接使用惰性隊列來將消息直接持久化至磁盤中。Kafka 是一種典型的磁盤式堆積,全部的消息都存儲在磁盤中。
  9. 消息追蹤:對於分佈式架構系統中的鏈路追蹤(trace)而言,你們必定不會陌生。對於消息中間件而言,消息的鏈路追蹤(如下簡稱消息追蹤)一樣重要。對於消息追蹤最通俗的理解就是要知道消息從哪來,存在哪裏以及發往哪裏去。基於此功能下,咱們能夠對發送或者消費完的消息進行鏈路追蹤服務,進而能夠進行問題的快速定位與排查。
  10. 消息過濾:消息過濾是指按照既定的過濾規則爲下游用戶提供指定類別的消息。就以 kafka 而言,徹底能夠將不一樣類別的消息發送至不一樣的 topic 中,由此能夠實現某種意義的消息過濾,或者 Kafka 還能夠根據分區對同一個 topic 中的消息進行分類。不過更加嚴格意義上的消息過濾應該是對既定的消息採起必定的方式按照必定的過濾規則進行過濾。
  11. 多租戶:重租賃技術,是一種軟件架構技術,主要用來實現多用戶的環境下公用相同的系統或程序組件,而且仍能夠確保各用戶間數據的隔離性。RabbitMQ 就可以支持多租戶技術,每個租戶表示爲一個 vhost,其本質上是一個獨立的小型 RabbitMQ 服務器,又有本身獨立的隊列、交換器及綁定關係等,而且它擁有本身獨立的權限。vhost 就像是物理機中的虛擬機同樣,它們在各個實例間提供邏輯上的分離,爲不一樣程序安全保密地容許數據,它既能將同一個 RabbitMQ 中的衆多客戶區分開,又能夠避免隊列和交換器等命名衝突。
  12. 多協議支持:爲了讓生產者和消費者都能理解所承載的信息(生產者須要知道如何構造消息,消費者須要知道如何解析消息),它們就須要按照一種統一的格式描述消息,這種統一的格式稱之爲消息協議。有效的消息必定具備某種格式,而沒有格式的消息是沒有意義的。通常消息層面的協議有 AMQP、MQTT、STOMP、XMPP 等(消息領域中的 JMS 更多的是一個規範而不是一個協議),支持的協議越多其應用範圍就會越廣,通用性越強,好比 RabbitMQ 可以支持 MQTT 協議就讓其在物聯網應用中得到一席之地。還有的消息中間件是基於其自己的私有協議運轉的,典型的如 Kafka。
  13. 跨語言支持:消息中間件自己具有應用解耦的特性,若是可以進一步的支持多客戶端語言,那麼就能夠將此特性的效能擴大。跨語言的支持力度也能夠從側面反映出一個消息中間件的流行程度。
  14. 流量控制:流量控制(flow control)針對的是發送方和接收方速度不匹配的問題,提供一種速度匹配服務抑制發送速率使接收方應用程序的讀取速率與之相適應。一般的流控方法有 Stop-and-wait、滑動窗口以及令牌桶等。
  15. 消息順序性:指保證消息有序。這個功能有個很常見的應用場景就是 CDC(Change Data Chapture)。
  16. 安全機制:身份認證是指客戶端與服務端鏈接進行身份認證,權限控制是指對客戶端的讀寫操做進行權限控制。
  17. 消息冪等性:消息在生產者和消費者之間進行傳輸而言通常有三種傳輸保障(delivery guarantee):At most once,至多一次,消息可能丟失,但毫不會重複傳輸;At least once,至少一次,消息毫不會丟,可是可能會重複;Exactly once,精確一次,每條消息確定會被傳輸一次且僅一次。對於確保對於大多數消息中間件而言,通常只提供 At most once 和 At least once 兩種傳輸保障,對於第三種通常很難作到,由此消息冪等性也很難保證。不過若是要考慮全局的冪等,還須要與從上下游方面綜合考慮,即關聯業務層面,冪等處理自己也是業務層面所須要考慮的重要議題。如下游消費者層面爲例,有可能消費者消費完一條消息以後沒有來得及確認消息就發生異常,等到恢復以後又得從新消費原來消費過的那條消息,那麼這種類型的消息冪等是沒法有消息中間件層面來保證的。若是要保證全局的冪等,須要引入更多的外部資源來保證,好比以訂單號做爲惟一性標識,而且在下游設置一個去重表。
  18. 事務性消息:支持事務的消息中間件並不在少數,Kafka 和 RabbitMQ 都支持,不過此二者的事務是指生產者發生消息的事務,要麼發送成功,要麼發送失敗。消息中間件能夠做爲用來實現分佈式事務的一種手段,但其自己並不提供全局分佈式事務的功能。

具體技術選型指標2:性能緩存

功能維度是消息中間件選型中的一個重要的參考維度,但這並非惟一的維度。有時候性能比功能還要重要,何況性能和功能不少時候是相悖的,魚和熊掌不可兼得,Kafka 在開啓冪等、事務功能的時候會使其性能下降,RabbitMQ 在開啓 rabbitmq_tracing 插件的時候也會極大的影響其性能。消息中間件的性能通常是指其吞吐量,雖然從功能維度上來講,RabbitMQ 的優點要大於 Kafka,可是 Kafka 的吞吐量要比 RabbitMQ 高出 1 至 2 個數量級,通常 RabbitMQ 的單機 QPS 在萬級別以內,而 Kafka 的單機 QPS 能夠維持在十萬級別,甚至能夠達到百萬級。安全

消息中間件的吞吐量始終會受到硬件層面的限制。就以網卡帶寬爲例,若是單機單網卡的帶寬爲 1Gbps,若是要達到百萬級的吞吐,那麼消息體大小不得超過 (1Gb/8)/100W,即約等於 134B,換句話說若是消息體大小超過 134B,那麼就不可能達到百萬級別的吞吐。這種計算方式一樣能夠適用於內存和磁盤。性能優化

時延做爲性能維度的一個重要指標,卻每每在消息中間件領域所被忽視,由於通常使用消息中間件的場景對時效性的要求並非很高,若是要求時效性徹底能夠採用 RPC 的方式實現。消息中間件具有消息堆積的能力,消息堆積越大也就意味着端到端的時延也就越長,與此同時延時隊列也是某些消息中間件的一大特點。那麼爲何還要關注消息中間件的時延問題呢?消息中間件可以解耦系統,對於一個時延較低的消息中間件而言,它可讓上游生產者發送消息以後能夠迅速的返回,也可讓消費者更加快速的獲取到消息,在沒有堆積的狀況下可讓總體上下游的應用之間的級聯動做更加高效,雖然不建議在時效性很高的場景下使用消息中間件,可是若是所使用的消息中間件的時延方面比較優秀,那麼對於總體系統的性能將會是一個不小的提高。服務器

具體技術選型指標3:可靠性 + 可用性網絡

消息丟失是使用消息中間件時所不得不面對的一個同點,其背後消息可靠性也是衡量消息中間件好壞的一個關鍵因素。尤爲是在金融支付領域,消息可靠性尤其重要。然而說到可靠性必然要說到可用性,注意這二者之間的區別,消息中間件的可靠性是指對消息不丟失的保障程度;而消息中間件的可用性是指無端障運行的時間百分比,一般用幾個 9 來衡量。架構

不少時候,對於可靠性方面也容易存在一個誤區: 想要找到一個產品來保證消息的絕對可靠,很不幸的是這世界上沒有絕對的東西,只能說盡可能趨於完美 想要儘量的保障消息的可靠性也並不是單單隻靠消息中間件自己,還要依賴於上下游,須要從生產端、服務端和消費端這 3 個維度去努力保證,《RabbitMQ 消息可靠性分析》這篇文章就從這 3 個維度去分析了 RabbitMQ 的可靠性。

從狹義的角度來講,分佈式系統架構是一致性協議理論的應用實現,對於消息可靠性和可用性而言也能夠追溯到消息中間件背後的一致性協議。對於 Kafka 而言,其採用的是相似 PacificA 的一致性協議,經過 ISR(In-Sync-Replica)來保證多副本之間的同步,而且支持強一致性語義(經過 acks 實現)。對應的 RabbitMQ 是經過鏡像環形隊列實現多副本及強一致性語義的。多副本能夠保證在 master 節點宕機異常以後能夠提高 slave 做爲新的 master 而繼續提供服務來保障可用性。Kafka 設計之初是爲日誌處理而生,給人們留下了數據可靠性要求不高的不良印象,可是隨着版本的升級優化,其可靠性獲得極大的加強,詳細能夠參考 KIP101。就目前而言,在金融支付領域使用 RabbitMQ 居多,而在日誌處理、大數據等方面 Kafka 使用居多,隨着 RabbitMQ 性能的不斷提高和 Kafka 可靠性的進一步加強,相信彼此都能在之前不擅長的領域分得一杯羹。

同步刷盤是加強一個組件可靠性的有效方式,消息中間件也不例外,Kafka 和 RabbitMQ 均可以支持同步刷盤,可是筆者對同步刷盤有必定的疑問:絕大多數情景下,一個組件的可靠性不該該由同步刷盤這種極其損耗性能的操做來保障,而是採用多副本的機制來保證。

這裏還要說起的一個方面是擴展能力,這裏我狹隘地將此概括到可用性這一維度,消息中間件的擴展能力可以加強其用可用能力及範圍,好比前面提到的 RabbitMQ 支持多種消息協議,這個就是基於其插件化的擴展實現。還有從集羣部署上來說,歸功於 Kafka 的水平擴展能力,其基本上能夠達到線性容量提高的水平,在 LinkedIn 實踐介紹中就說起了有部署超過千臺設備的 Kafka 集羣。

具體技術選型指標4:運維管理

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

運維管理也能夠進行進一步的細分,好比:申請、審覈、監控、告警、管理、容災、部署等。

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

監控、告警也比較好理解,對消息中間件的使用進行全方位的監控,便可覺得系統提供基準數據,也能夠在檢測到異常的狀況配合告警,以便運維、開發人員的迅速介入。除了通常的監控項(好比硬件、GC 等)以外,對於消息中間件還須要關注端到端時延、消息審計、消息堆積等方面。對於 RabbitMQ 而言,最正統的監控管理工具莫過於 rabbitmq_management 插件了,可是社區內還有 AppDynamics, Collectd, DataDog, Ganglia, Munin, Nagios, New Relic, Prometheus, Zenoss 等多種優秀的產品。Kafka 在此方面也絕不遜色,好比:Kafka Manager, Kafka Monitor, Kafka Offset Monitor, Burrow, Chaperone, Confluent Control Center 等產品,尤爲是 Cruise 還能夠提供自動化運維的功能。

無論是擴容、降級、版本升級、集羣節點部署、仍是故障處理都離不開管理工具的應用,一個配套完備的管理工具集能夠在遇到變動時作到事半功倍。故障可大可小,通常是一些應用異常,也能夠是機器掉電、網絡異常、磁盤損壞等單機故障,這些故障單機房內的多副本足以應付。若是是機房故障就要涉及異地容災了,關鍵點在於如何有效的進行數據複製,對於 Kafka 而言,能夠參考 MirrorMarker、uReplicator 等產品,而 RabbitMQ 能夠參考 Federation 和 Shovel。

具體技術選型指標5:社區力度及生態發展

對於目前流行的編程語言而言,如 Java、Python,若是你在使用過程當中遇到了一些異常,基本上能夠經過搜索引擎的幫助來獲得解決,由於一個產品用的人越多,踩過的坑也就越多,對應的解決方案也就越多。對於消息中間件也一樣適用,若是你選擇了一種「生僻」的消息中間件,可能在某些方面運用的駕輕就熟,可是版本更新緩慢、遇到棘手問題也難以獲得社區的支持而越陷越深;相反若是你選擇了一種「流行」的消息中間件,其更新力度大,不只能夠迅速的彌補以前的不足,並且也能順應技術的快速發展來變動一些新的功能,這樣可讓你以「站在巨人的肩膀上」。在運維管理維度咱們說起了 Kafka 和 RabbitMQ 都有一系列開源的監控管理產品,這些正是得益於其社區及生態的迅猛發展。

 

消息中間件選型還有一個考量標準就是儘可能貼合團隊自身的技術棧體系,雖說沒有蹩腳的消息中間件只有蹩腳的程序員,可是讓一個 C 棧的團隊去深挖 PhxQueue 總比去深挖 Scala 編寫的 Kafka 要容易的多。

 

消息中間件選型切忌一味的追求性能或者功能,性能能夠優化,功能能夠二次開發。若是要在功能和性能方面作一個抉擇的話,那麼首選性能,由於整體上來講性能優化的空間沒有功能擴展的空間大。然而對於長期發展而言,生態又比性能以及功能都要重要。

 

消息中間件大道至簡:一發一存一消費,沒有最好的消息中間件,只有最合適的消息中間件

 

 <http://www.52im.net/thread-1647-1-1.html

相關文章
相關標籤/搜索