1. 程式人生 > 實用技巧 >kafka 異常:org.apache.kafka.common.errors.UnknownTopicOrPartitionException: This server does not host

kafka 異常:org.apache.kafka.common.errors.UnknownTopicOrPartitionException: This server does not host

文章目錄

1. 問題出現的場景

producer 向一個之前不存在的 topic 寫資料

2. UnknownTopicOrPartitionException

字面意思是:topic 或 partition 不存在。
例如:topic 一共有 3 個 partition,p0,p1,p2,而你指定向 p3寫資料,則會報這個異常。

3. 問題原因分析

理論上 kafka 會自動創造不存在的 topic。
在這個場景下,producer 向一個新的 topic 寫資料,則 kafka 會自動建立這個 topic,並按預設配置給出 partition。

3.1 既然會自動建立 topic,為什麼還會報UnknownTopicOrPartitionException?

建立 topic 不是一個瞬間就能完成的動作,kafka 需要將 topic 資訊寫入 zk,zk 為了保證一致性,需要zk 叢集內大部分節點都寫成功。因此這個過程是需要耗費一定時間的。(未測試具體耗時)

所以當 kafka 正在建立這個 topic 的時候,producer 就向其發資料,那肯定 topic 是不存在的,因此報這個異常。

4. UnknownTopicOrPartitionException是可重試異常

根據官方API 文件解釋:

This topic/partition doesn't exist. 
This exception is used in contexts where a topic doesn't seem to exist based on possibly stale metadata. 
This exception is retriable because the topic or partition might subsequently be created.
  • 1
  • 2
  • 3

UnknownTopicOrPartitionException是可重試異常,因為可能 topic 正在建立中,過一會就建立好了。
因此為了保證程式健壯性, producer 需要捕獲此異常,並做重試。

4.1 兩種重試方案

4.1.1 kafka 客戶端配置

spring.kafka.producer.retries = 3

4.1.2 producer 程式碼捕獲異常並手工重試

可以通過實現ListenableFutureCallback<SendResult<String, String>>介面,設定回撥。

// 實現這個回撥方法,判斷 Throwable 型別,手工處理重試
void onFailure(Throwable var1);
  • 1
  • 2

參考

  1. Kafka常見錯誤整理https://juejin.im/post/6844903943131103239
  2. Kafka運維填坑