kafka問題排查之 Java程式碼不進行消費
發現問題
使用 kafka 在linux系統,通過命令測試消費正常, 但在Java 程式碼無法正常接收佇列訊息
控制檯提示資訊:
15:21:33.804 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8886"] 15:21:33.836 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8886"] 15:21:33.841 [main] INFO org.apache.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read 15:21:33.859 [concurrentMessageListenerContainer-0-kafka-consumer-1] INFO org.apache.kafka.clients.consumer.internals.AbstractCoordinator - Discovered coordinator platform-010-030-050-167:16792 (id: 2147483647 rack: null) for group test-mengqa. 15:21:33.878 [main] INFO org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer - Tomcat started on port(s): 8886 (http) 15:21:33.884 [main] INFO com.navinfo.opentsp.qingqi.webpush.core.Application - Started Application in 49.808 seconds (JVM running for 53.243) 15:21:34.864 [concurrentMessageListenerContainer-0-kafka-consumer-1] INFO org.apache.kafka.clients.consumer.internals.AbstractCoordinator - Marking the coordinator platform-010-030-050-167:16792 (id: 2147483647 rack: null) dead for group test-mengqa
最後一行 Marking the coordinator platform-010-030-050-167:16792 (id: 2147483647 rack: null) dead for group test-mengqa
被標記為死亡, 不能接收訊息的原因可能就是消費者死亡導致的
分析過程
從 log 可以分析這句是 AbstractCoordinator 類列印的, 我們找到列印這行資訊的程式碼
protected void coordinatorDead() { if (this.coordinator != null) { log.info("Marking the coordinator {} dead.", this.coordinator.id()); this.coordinator = null; } }
顯然coordinator 為null了
打斷點追蹤
platform-010-030-050-167
是 Kafka 例項所在伺服器的主機名,
16792
是 kafka 的埠,這玩意好像是 Kafka 的連線地址
乍一看, 覺得沒什麼問題
從堆疊追蹤到上一呼叫方法處看看:
既然 coordinator 不為空, 那進入程式碼塊一定是因為 client.connectionFailed(coordinator)
這個方法的返回結果為true了。
從語義分析是因為客戶端連線 coordinator 失敗
進入該方法看看:
看到形參名是 node, 這個物件應該就是 kafka 的節點資訊,
點開檢視一下物件的具體屬性,知道問題原因在此。
問題定位
注意看上圖的 host 屬性, host 的意思一般是主機.
區域網內, 通過主機名是無法訪問的。
一般是通過 IP 、域名、或者修改 hosts 檔案把主機名和 IP 對應起來
定位後,我們嘗試用最簡單的方法解決問題.
解決
最簡單的就是修改本機 hosts 檔案
windows 系統 hosts 檔案位於 C:\Windows\System32\drivers\etc\hosts
使用管理員許可權開啟, 追加 IP 和 主機名對應關係
10.30.50.167 platform-010-030-050-167
重啟解決之。
方案總結
可能因為沒有給 Kafka 設定監聽地址導致的預設監聽主機名
在配置中果然搜尋到類似選項, 按照註釋的意思就是會廣播給消費者和生產者的地址.
我們按照要求改成 advertised.listeners=PLAINTEXT://10.30.50.167:16792
恢復本機 hosts 檔案經測試同樣解決了問題
最後
我們在 application.properties
中已經指定 spring.kafka.bootstrap-servers
為 IP, 為什麼還會使用主機名連結呢?
推測客戶端是先連線到 Kafka 例項後會從 zk 中獲取配置
然後客戶端 watch zk 節點得到配置地址後才開始監聽佇列。