微服務及訊息佇列簡史
自從 Peter Rodgers 博士 2005 年在 Web Services Edge 會議上首次提出 Micro-Web-Services 一詞後,IT 行業慢慢地從單體架構轉向了微服務。
2009 年,Netflix 決定把其單體架構拆分為微服務。
2010 年,Best Buy 開始把它們的單體架構轉變為微服務架構。
2011 年,eBay 開始推行微服務。
2001 年,當時 Amazon 的零售網站還是個巨大的單體架構。
Rob Brigham 在 Amazon 的 re:Invent 2015 會議上提出了微服務改造建議:
-
將服務端拆分成鬆耦合的微服務
-
隔離微服務時應該關注業務而非團隊技術棧
-
成立更小單位的研發團隊,專注於定義良好的服務,使他們可以更高效、更大規模的完成交付
今天,服務端基本都遵循微服務架構設計模式。然而,基於訊息佇列的程式間或執行緒間通訊可以追溯到 20 世紀 80 年代初,當時使用的是 UNIX 的 V API 或其它實時作業系統核心。直到 2000 年代,基於網路間通訊的訊息佇列才誕生。
-
RabbitMQ 在 2007.07.01 釋出了它的 v1.0.0 版本
-
Kafka 最初由 LinkedIn 開發,隨後於 2011 年初開源
-
Amazon SQS 於 2004 年底進入測試階段,並於 2006 年年中正式上市
使用同步通訊還是非同步通訊
選擇了微服務架構,就面臨著選擇服務間的通訊協議:
-
同步:HTTP,如 REST、SOAP、RPC、gRPC 等
-
非同步:訊息佇列,如 AMQP、Kafka、MQTT 等
同步通訊更容易出錯,更難除錯,也更難恢復。如果不是實時性要求特別強的功能,可以考慮非同步通訊。
非同步通訊提供了單一、可靠的訊息匯流排,使得除錯更容易,更不容易出錯,服務間資料傳遞更可靠也更安全。
也就是說,除非存在使用較舊程式語言的遺留服務,或者無法改造的舊基礎架構,雲原生時代更建議選擇非同步通訊。
選擇了使用非同步方法,就需要決定使用什麼訊息佇列中介軟體和訊息佇列協議。
訊息佇列中介軟體
以下是截至 2021 年比較著名的訊息佇列中介軟體以及雲服務列表:
-
RabbitMQ
-
Apache Qpid
-
Apache Kafka
-
Apache ActiveMQ
-
Redis
-
Eclipse OpenMQ
-
JoramMQ
-
Eclipse Mosquitto
-
HiveMQ
-
Solace PubSub+
-
Google Cloud Pub/Sub
-
Amazon SQS
-
Amazon MQ
-
IBM MQ
-
Azure Event Hubs
-
Azure Service Bus
訊息佇列協議矩陣
以下是訊息佇列協議比較矩陣:
注意:Headers 表示具有任意數量鍵的 dictionary 或 map,而 attrs 表示一組有限的鍵值對。
相似點:
-
所有協議都有佇列的 FIFO 概念
-
所有協議都基於 TCP
-
所有協議都有生產者、消費者的概念
-
所有協議都有負載(payload)與正文(body)
不同點:
-
AMQP 有不同的訊息傳遞模型
-
Cloud-based 的訊息佇列具有死信佇列
-
訊息檢索(routing key)方法不同
-
Headers 和 attrs 的支援有限
-
Redis、STOMP、MQTT 的功能最不豐富,而 AMQP 的功能最豐富
-
Cloud-based 的訊息佇列具有一些獨特的配置以及相關 API。
訊息佇列協議詳解
訊息佇列協議的選擇實際上比訊息佇列中介軟體的選擇更重要。因為如果選擇一個更通用的協議,就更容易找到其他中介軟體作為替代。
AMQP
AMQP - Advanced Message Queue Protocol 是一種基於 TCP 的二進位制協議,已成為 ISO 和 OASIS 的標準,AMQP 協議主要由 RabbitMQ 使用。
優點:
-
針對不同的使用者場景使用不同的訊息傳遞模型,在協議級別降低了架構的複雜性
-
AMQP 是 ISO 和 OASIS 標準,被廣泛採用
-
AMQP 快速、安全,可能是訊息佇列協議中最成熟的
-
可以在公有云上找到對應的雲產品,並且可以在雲產品和自有 RabbitMQ 間輕鬆切換
-
使用 classical 佇列或 quorum 佇列進行佇列映象,使其易於擴充套件
-
RabbitMQ 的訊息大小限制在版本 3.7.0 之前為 2GB,在版本 3.8.0 中減少到 128MB
缺點:
-
不向下相容,客戶端只實現協議的一個版本,版本之間升級遷移可能很耗時
-
依賴 RabbitMQ 許多外掛可能會面臨運維挑戰
-
除錯和監控可能存在問題
-
雖然 AMQP 感覺像是標準化的訊息佇列協議,但大多數訊息佇列中介軟體都不支援它
Apache Kafka
Apche Kafka 既是訊息佇列中介軟體的名稱,也是協議本身。截至 2021,該協議共有 12 個版本,客戶端可同時相容所有版本。
Apche Kafka 是一個由 Apache 軟體基金會開發和維護的專案,用 Scala 和 Java 編寫。
Apache Kafka 團隊選擇定義自己的協議,而不是採用 AMQP 或 STOMP。是因為他們認為協議決定了實現,因此,採用已有的協議會降低了他們建立分散式訊息中介軟體以及進行某些優化的自由度。
優點:
-
Apache Kafka 的 partition 和 replication 的功能使其易於擴充套件
-
Apache Kafka 提供了一種批量傳送小訊息的方法,使得該協議非常高效
-
Apache Kafka 提供的管理 API 使除錯變得很容易
缺點:
-
Apache Kafka 需要部署 ZooKeeper 和 Kafka 兩部分,對於初學者而言具有一定的挑戰性
-
Apache Kafka 協議規範不斷升級變化,客戶端可能很難跟上其變化,升級也可能具有挑戰性
-
訊息大小限制為 1MB
STOMP
STOMP - Streaming Text Oriented Messaging Protocol 是一種基於文字的協議,與 AMQP 非常相似。但它缺乏其他協議所具有的許多功能和優化。另一方面,STOMP 的簡單性使其更易於採用。因此,有許多客戶端支援該協議,RabbitMQ 也可以通過外掛支援 STOMP。對於一些簡單的用例或快速原型,可以考慮使用 STOMP。
優點:
-
簡單,易於整合
-
通過外掛方式支援 RabbitMQ
缺點:
-
與其他協議相比,功能和優化更少
MQTT
MQTT - Message Queuing Telemetry Transport 是物聯網(IoT)的訊息佇列協議,它是 ISO 和 OASIS 標準,當前支援 MQTT 的最著名的中介軟體是 Eclipse Mosquitto 和 HiveMQ。
優點:
-
輕量
-
雙向
缺點:
-
不適用於與物聯網無關的微服務
-
功能不夠豐富
Redis
RESP - Redis Serialization Protocol 是 Redis 的協議。Redis 是一個基於記憶體的 Key-Value 資料庫。從技術上講,Redis 不是一個訊息佇列中介軟體,但通過一些客戶端手段,Redis 可以用於非同步訊息通訊。這主要是那些喜歡使用 Redis 的開發者或者一些簡單場景採用的手段,因此,也把 Redis 納入訊息中介軟體。
優點:
-
Redis 基於記憶體,速度相當快
-
對於已經使用 Redis 的人來說,基本無學習曲線
缺點:
- 訊息沒有持久化,有丟訊息的風險
- 功能不夠豐富
- 不適用於其他協議能解決的所有應用場景
雲服務,如 AWS SQS
如果不想自己維護基礎設施,並需要自動擴容,或者本身就在公有云上,此時,可以考慮直接使用雲服務。
優點:
-
方便快捷
-
穩定,自動擴容
-
無需個人維護
缺點:
-
對於簡單或輕量的業務場景 ,費用可能過高
-
客戶端相容問題依賴雲廠商解決,對某些開發語言可能相容不好
-
非客戶端互動模式,如 API 方式可能存在效能問題
如何選擇訊息佇列
總之,一般情況下使用 AMQP - RabbitMQ 或 Kafka,對訊息可靠性要求較高時考慮 RabbitMQ,否則選擇 Kafka。
請勿採用 STOMP,因為它沒有被很好的相容,而且沒有很好的優化。
如果您在從事物聯網業務,那麼請使用 MQTT,它適合物聯網。
如果您喜歡 Redis,並且無法新增其它新技術,那麼可以繼續使用 Redis,但需要接受 Redis 在訊息佇列中的缺點。
如果您本身就在使用公有云,具備一定的使用者或業務體量,對訊息佇列有穩定性及自動擴容的要求,並且能接受其費用,那麼,選擇雲服務提供的訊息佇列。