分布式系統中常用通訊模型主要是“請求-應答”模型和“發布-訂閱”模型。前者常見如RPC通訊,常用HTTP REST或Thrift等協議;后者多指消息隊列MQ通訊。
RPC大多屬於請求-應答模式,也包括越來越多響應式范式,對於需要點對點交互、強事務保證和延遲敏感的服務/應用之間的通信,RPC是優於消息隊列的。那么消息隊列(下文也簡稱MQ,即Message Queue)可以看做是一種異步RPC,把一次RPC變為兩次或多次,進行內容轉存,再在合適的時機投遞出去。消息隊列中間件往往是一個分布式系統,內部組件間的通信仍然會用到RPC。
常見消息隊列協議
底層協議(例如 TCP)是被設計用來將一個消息從一個發送者(sender)傳遞給一個接收者(receiver)。他們並不關系消息本身應該如何構建,也不關系消息的請求、獲取、存儲以及如何保證安全可靠。像 WebSockets 這樣在 TCP 之上的協議,添加了一些額外的功能,例如使用頭部(header)傳輸元數據,通過多個數據包分割較大的消息,簡單的身份驗證,以及路由/重定向相關信息。
消息隊列場景中producer、consumer和broker通信的協議,包括AMQP、STOMP、MQTT、HTTP、OpenWire(ActiveMQ)、XMPP、自定義等等。以下對比較常用的幾個說明:
1、STOMP: 面向流文本的消息傳輸協議(STOMP,Streaming Text Oriented Messaging Protocol),是 WebSocket 通信標准。在通常的發布-訂閱語義之上,它通過 begin/publish/commit 序列以及 acknowledgement 機制來提供消息可靠投遞。
特點:協議簡單且易於實現,幾乎所有的編程語言都有 STOMP 的客戶端實現。但是在消息大小和處理速度方面並無優勢。由於在許多發布-訂閱式的架構中,信息交換是基於文本的,所以許多協議選擇簡單地將整個信息轉化為文本,從而降低復雜性並提高了可讀性,當然帶來的代價就是需要再消息接受后執行額外的計算任務。
應用場景:信息交換基於文本,要求簡單的場景。
典型實現:ActiveMQ以及它的下一代實現Apache Apollo。
2、AMQP:比較全面和復雜的一個協議,包括協議本身以及模型(broker、exchange、routing key等概念)。
特點:AMQP 十分可靠且功能強大。當然它及它的實現並不是足夠輕量級。
應用場景:當簡單的發布-訂閱模型不能滿足使用要求。
典型實現:RabbitMQ是AMQP消息隊列最有名的開源實現。RabbitMQ同時還可以通過插件支持STOMP、MQTT等協議接入。Kafka、RocketMQ均使用自定義的協議。
3、MQTT:MQTT(Message Queue Telemerty Transport)是一種二進制協議,主要用於服務器和那些低功耗的物聯網設備(IoT)之間的通信。 它位於 TCP 協議的上層,除了提供發布-訂閱這一基本功能外,也提供一些其它特性:不同的消息投遞保障(delivery guarantee),“至少一次”和“最多一次”。通過存儲最后一個被確認接受的消息來實現重連后的消息恢復。
特點:它非常輕量級,並且從設計和實現層面都適合用於不穩定的網絡環境中。
應用場景:物聯網(IoT)場景中更適合,支持幾乎所有語言進行開發,並且瀏覽器也可通過 WebSocket 來發送和接收 MQTT 消息。
activeMQ5.11.1版本帶的例子提供了四種協議的簡單demo,這四種協議分別為:AMQP,MQTT,OpenWire,Stomp,通過運行這四種協議的的demo可以大致得出這四種協議實現在activeMQ中的性能對比:
amqp Received 10001 in 6.58 seconds mqtt Received 10000 in 2.69 seconds openwire Received 10001 in 8.87 seconds stomp Received 10001 in 14.17 seconds
可以看出,mqtt協議的實現最快,stomp的協議實現最慢。