背景
- 項目使用docker swarm部署
- 服務之間使用消息中間件 kafka 通信
- Kafka 使用 star 3.7k 的
wurstmeister/kafka:2.12-2.2.1鏡像 - Zookeeper 使用
zookeeper:3.5.5鏡像
問題描述
每當Kafka和Zookeeper服務重啟后,項目就會報以下錯誤:
org.apache.kafka.common.errors.UnknownTopicOrPartitionException:
This server does not host this topic-partition
由於是開發環境,之前每次遇到這種問題,都是粗魯的直接清掉Kafka和Zookeeper的存儲文件,隨后重啟就工作正常。
在切CICD環境之前,我們一直使用物理機部署程序在跑,在物理機上安裝的Kafka和Zookeeper, 項目運行了一年多從來沒出現過這種問題。
排查問題
首先仔細閱讀了kafka鏡像的readme文件,問題出現在下面這塊:
By default each broker will get a new port number and broker id on restart. Depending on your use case this might not be desirable. If you need to use specific ports and broker ids, modify the docker-compose configuration accordingly.
默認情況下,在重啟Kafka鏡像時每個broker會獲取一個新的broker id。在你的項目中,這種機制或許是不合適的。如果你需要用指定的broker ids,請相應地修改你的docker-compose配置。
看了這一段說明,我追蹤了以下zookeeper中 /borkers/ids 下面的節點信息,發現每次重啟Kafka之后,都會生成新的id出來,這就是問題的根本。
於是我接着查看了一下物理機上Kafka的配置文件,發現 broker id 在配置項中是固定值 0。

解決方案
- 修改 docker-compose 文件中 kafka 的配置,明確配置 Kafka 的
broker id,例如:環境變量添加KAFKA_BROKER_ID: 0 - 通過 BROKER_ID_COMMAND 命令配置,例如:BROKER_ID_COMMAND: "hostname | awk -F'-' '{print $$2}'"
- 如果你的環境支持自動伸縮,那么推薦使用
--no-recreate選項來確保container不會重新創建,這樣就會保留之前生成的broker id
關注公眾號:JAVA九點半課堂,這里有一批優秀的程序猿,加入我們,一起探討技術,共同進步!回復“資料”獲取 2T 行業最新資料!
