微服務及消息隊列簡史
自從 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?在消息隊列中的缺點。
如果您本身就在使用公有云,具備一定的用戶或業務體量,對消息隊列有穩定性及自動擴容的要求,并且能接受其費用,那么,選擇云服務提供的消息隊列。
參考總結
以上就是本文希望分享的內容,如果大家有什么問題,歡迎在公眾號 - 跬步之巔留言交流。