歷史原因,公司存在多個 MQ 同時使用的問題,我們中介軟體團隊在去年下半年開始支援對 Kafka 和 Rabbit 能力的進行封裝,初步能夠完全支撐業務團隊使用。
鑑於在之前已經基本完全實施 Kafka 管控平臺、以及 Kafka 叢集遷移管控,我們基本可以認為團隊對於 Kafka 的把控能力初具規模。
因此,考慮到以下幾點原因,我們決定對 RabbitMQ 不再做維護和支援。
基於我們的資料統計和分析發現,基本上沒有服務使用我們自己封裝的 RabbitMQ 能力,用到的基本上是spring-amqp
或者原生的Rabbit 使用方式,存在使用混亂,方式不統一的問題,對於排查問題方面存在更多的問題。
另外考慮到對於 MQ 能力支援要做雙份,Kafka 和 Rabbit 都要支援相同的功能,對於人力資源方面存在浪費,當然也由於本身目前沒有對 RabbitMQ 非常精通的同學,所以對於維護能力這方面存在擔憂。
RabbitMQ 叢集對於網路分割區的容錯性不高,根據調查發現,系統中 RabbitMQ 高可用方案使用映象佇列,而當 RabbitMQ 出現網路分割區時,不同分割區裡的節點會認為不屬於自身所在分割區的節點都已經掛了,對於佇列、交換器、繫結的操作僅對當前分割區有效。
而且,如果原叢集中設定了映象佇列,而這個映象佇列又牽涉兩個或者更多個網路分割區中的節點時,每一個網路分割區中都會出現一個 master 節點,對於各個網路分割區,此佇列都是相互獨立的。
在預設的情況下,架構本身存在腦裂的風險,在 3.1 版本下是無法自動恢復的,之後的版本才會自動探測網路分割區,人工介入存在資料丟失的風險。
映象佇列解決了 Rabbit 高可用的問題,但是並不能增加負載和效能,線上曾經出現過 RabbitMQ 在高流量下的效能問題,就是因為佇列由單個節點承載流量,在高並行情況在叢集中單個節點存在效能瓶頸。
即便我們目前大部分場景下 MQ 流量不高,但是一旦出現問題,將成為整個系統的效能瓶頸。
另外我們對 Rabbit 做了一些效能方面的測試:
測試叢集一共有 4 臺磁碟節點,其中每臺 16 核,如果我們不做 Sharding,單佇列最高 TPS 在 5K 左右,如果是記憶體節點,官方可以給出的處理極限為 50K/s,如果做 Sharding,單佇列處理能力可以達到 10K/s。
上述結論都是以訊息能夠被正常快速消費為前提,實際上在高流量或者大量訊息積壓的情況會導致叢集效能急劇下降。
基於以上現有的問題和難點,我們決定對 Rabbit 進行全量遷移至 Kafka,以便能在業務高速發展過程中能夠保障對於穩定性、高可用、高效能方面的追求。
在方法論和理論體系層面,我們對業務生產有三板斧:可灰度、可監控、可回滾。
同樣,對於訊息中介軟體平臺運維我們希望有三板斧:可運維、可觀測、可管控,那麼目前基於 Kafka 的叢集管控和 Kafka Manager 的能力我們已經基本做到了上述幾點。
Exchange:生產者將訊息傳送到Exchange,由交換器將訊息通過匹配Exchange Type、Binding Key、Routing Key後路由到一個或者多個佇列中。
Queue:用於儲存訊息,消費者直接繫結Queue進行消費訊息
Routing Key:生產者傳送訊息給 Exchange 會指定一個Routing Key。
Binding Key:在繫結Exchange與Queue時會指定一個Binding Key。
Exchange Type:
Topic:傳送訊息的主題,對訊息的組織形式
Broker:Kafka 伺服器端
Consumer Group:消費者組
Partition:分割區,topic 會由多個分割區組成,通常每個分割區的訊息都是按照順序讀取的,不同的分割區無法保證順序性,分割區也就是我們常說的資料分片sharding機制,主要目的就是為了提高系統的伸縮能力,通過分割區,訊息的讀寫可以負載均衡到多個不同的節點上
綜上,我們將要對系統中所有使用RabbitMQ的服務進行遷移操作,整個遷移我們應該保證以下 3 點:
優點:可以做到無失真遷移
缺點:
這是基於雙訂閱模式的優化,通過使用我們的灰度/藍綠髮布的能力,做到可以不雙訂閱,不用同時監聽兩個訊息佇列的訊息。
優點:
缺點:同樣無法保證訊息有序性
上述只是針對現狀的遷移方案考慮,那麼還有一些跟實際和複雜的問題可能需要考慮。
比如訊息的場景有可能不是這種簡單的釋出/訂閱關係,可能存在網狀、環狀的釋出/訂閱關係,該如何處理?
其實是一樣的道理,只要我們能夠梳理清楚每個 Exchange 之間的釋出/訂閱的關係,針對每個 Exchange 進行操作,就能達到一樣的平滑遷移效果。
我們要做的就是針對每個 Exchange 進行遷移,而不是針對服務,否則遷移是無法進行下去的,但是這樣帶來的另外一個問題就是每個服務需要釋出多次,而且如果碰到多個複雜消費或者生產的情況要特別小心。
基於現狀,我們對所有 Rabbit Exchange 的情況進行了詳細的統計,將針對不同的 Exchange 和型別以及功能使用以下方式處理。
驗證
監控
監控通過 Kafka Manager 平臺或者現有監控
灰度
方案本身 Consumer 和 Producer 都可以直接灰度釋出,預發驗證
回滾
服務回滾,按照發布順序控制回退順序
巨人的肩膀: