我們一開始選了 Kafka,結果殺雞用了牛刀——訊息佇列選型的真實復盤
System Design·2026年6月17日·6 分鐘閱讀

我們一開始選了 Kafka,結果殺雞用了牛刀——訊息佇列選型的真實復盤

L
Leo Wu

後端工程師,做過高併發與金流系統,曾經為一個小需求扛了整套 Kafka,從此學會選最合身的而不是最強的。

一個我們選錯的開場

我們一開始選了 Kafka,結果殺雞用了牛刀——訊息佇列選型的真實復盤:本文架構

先講一個我自己選錯的故事。

有個內部系統,需求很單純:幾個服務之間要做非同步解耦,把一些任務丟出去讓別的服務慢慢處理,量不大,一天頂多幾十萬則。當時團隊裡「Kafka = 高大上的訊息系統」的印象很深,選型會議十分鐘就拍板用 Kafka。

結果呢?我們為了這個不大的需求,扛上了 Kafka 一整套的運維重量——ZooKeeper(那個年代還要)、分區規劃、消費者位移管理。真正用到它高吞吐能力的場景一個也沒有,卻天天在為它的維運複雜度買單。後來我才想通,我們要的其實是一個能靈活路由、好維護的任務佇列,那根本是 RabbitMQ 的主場。這篇就是我被這件事教訓之後,對這兩者選型的整理。

先講本質:它們根本是兩種東西

我們一開始選了 Kafka,結果殺雞用了牛刀——訊息佇列選型的真實復盤:概念圖

很多人把 Kafka 跟 RabbitMQ 放在一起比,好像是同類產品的 PK。但我覺得先要認清:它們的設計哲學根本不同。

RabbitMQ 是傳統的訊息佇列(message broker),核心是「把訊息從生產者,透過靈活的路由規則,送到對的消費者」,訊息被消費完通常就沒了。Kafka 本質上是一個「分散式的、可重播的提交日誌(log)」,訊息是持久化在日誌裡的,消費者靠記錄自己讀到哪個位移來消費,讀完訊息還在,可以重播。

搞懂這個本質差異,後面所有的取捨才講得通。我當初就是沒搞懂這個,只看到「Kafka 吞吐高」就選了。

吞吐量:Kafka 的看家本領,但別被數字騙了

Kafka 的高吞吐是真的,它靠順序寫磁碟、批次、零拷貝這些設計,能扛非常大的量。如果你的場景是每秒幾十萬、上百萬則的日誌收集、行為追蹤、串流資料,那 Kafka 幾乎是預設答案。

但「別被數字騙了」——你要先問自己,你真的有那個量嗎?我那次的教訓就是,我們拿著一個一天幾十萬則(平均每秒個位數)的需求,去用一個為每秒百萬則設計的東西。吞吐量的上限對我們毫無意義,我們付的卻是它的複雜度成本。選型不是選最強的,是選最合身的。

路由彈性:RabbitMQ 真正的殺手鐧

RabbitMQ 在「怎麼把訊息送到對的地方」這件事上,靈活度遠勝 Kafka。它有各種 exchange 型別,可以做到按規則精細地把不同訊息路由到不同佇列。你要「這種訊息給 A 跟 B、那種只給 C」這種複雜派送,RabbitMQ 幾行設定就搞定。

Kafka 的模型就樸素很多,主要靠 topic 跟分區,複雜路由要嘛在應用層自己做、要嘛靠額外的串流處理。我那個「靈活派任務」的需求,恰恰是 RabbitMQ 的甜蜜點,我卻拿 Kafka 硬幹。

訊息順序:這題比你想的微妙

大家都說 Kafka 保證順序。精確地講,Kafka 只保證單一分區內的順序。一旦你為了擴展把一個 topic 分成多個分區,跨分區之間就沒有全域順序了。如果你需要「同一個使用者的事件嚴格照順序」,你得靠分區鍵把同一個使用者的訊息都路由到同一個分區。這是設計時就要想清楚的,不是它自動幫你搞定。RabbitMQ 這邊,單一佇列單一消費者是有序的,但一旦你為了吞吐開多個消費者並行,順序一樣會亂。兩邊都沒有免費的「又要並行又要嚴格全域有序」。

重複消費與冪等:這是你逃不掉的功課

不管你選哪個,都要面對「同一則訊息可能被消費不只一次」。網路超時、消費者處理到一半掛掉重啟,都會導致重投。所以消費端的冪等性是必修課,不是選了哪個 MQ 就能免掉的。我的做法通常是給每則訊息一個唯一 ID,消費端記錄「這個 ID 我處理過了」,重複的直接跳過。這件事跟你選 Kafka 還是 RabbitMQ 完全無關,你都得自己做。

運維成本:那個沒人在選型會議上講的真相

這是我那次最痛的一課。選型會議上大家都在比功能、比吞吐,沒人算維運成本

Kafka 這套東西要跑得穩,你得懂分區、副本、位移管理,出事的時候要能診斷。它不是你架起來就一勞永逸的。RabbitMQ 相對輕,中小規模好上手很多。如果你團隊沒有人真的熟 Kafka,卻為了一個用不到它威力的需求把它扛回家,那個複雜度會在往後每一天慢慢跟你收利息。

什麼時候其實用不到 Kafka

坦白講,很多團隊的量,根本用不到 Kafka。如果你的需求是服務間解耦、非同步處理任務、量在中小規模,RabbitMQ(甚至更輕的方案)就夠了,還更好維護。不要因為 Kafka 名氣大就預設用它——那正是我犯的錯。

一個現實裡常見的答案:兩個都要

規模大了之後,很常見的情況是兩個都用:Kafka 扛高吞吐的資料流、事件溯源、串流處理;RabbitMQ 處理需要複雜路由的業務訊息。它們不是互斥的選擇題,是工具箱裡兩把用途不同的工具。

我的選型原則,濃縮成幾句話

  • 高吞吐、要重播、串流資料 → Kafka。
  • 複雜路由、傳統任務佇列、中小規模、要好維護 → RabbitMQ。
  • 先問「我真的有那個量嗎」,再問「我團隊養得起它的維運嗎」,最後才看功能。
  • 不管選哪個,消費端冪等自己做,別想逃。

小結

那次選錯 Kafka 的經驗,把我從「選最強的」掰成了「選最合身的」。

老實講,我到現在遇到選型還是會猶豫。有時候明明評估下來 RabbitMQ 就夠,但想到團隊未來一兩年可能會長到需要 Kafka,又會動搖——到底要為現在最合身而選,還是為想像中的未來預留?這題我沒有標準答案,每次都是重新賭一次。我唯一比較有把握的是:別再單純因為「Kafka 比較高大上」就選它。下次有人在選型會議上這樣說,我一定會先問一句:我們,真的用得到它嗎?

#Kafka#RabbitMQ#Message Queue#System Design#Event-Driven#Idempotency

留言討論

有想法、有不同經驗、或想糾正我?歡迎在下面留言,免註冊,填個暱稱就能留。

相關文章