文章目錄
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
參考
- Kafka常見錯誤整理 https://juejin.im/post/6844903943131103239
- Kafka運維填坑