今天試著用 golang 接 kafka(in docker),沒想到搞了一、二個小時才終於把 happy flow 走通,筆記一下。
由於我的作業系統是 windows,所以要先安裝 docker desktop。
安裝完之後,進到 docker 官網的 kafka image 頁面,第一步先把 image pull 下來。
docker pull apache/kafka:4.0.2 or docker pull apache/kafka:latest
接著照著官網的說明,把 kafka 跑起來。大致上只要底下四個動作就可以跑得起來。
指令在 docker desktop 裡面的 terminal 執行比較方便,我個人是自己切到 opt/kafka/bin 裡面去執行。
把 image 掛起來docker run -d --name broker apache/kafka:latest
新增一個 topic./kafka-topics.sh --bootstrap-server localhost:9092 --create --topic test-topic
建立 producer,這時候 terminal 會處於接受訊息的狀態,每輸入完一串文字按下 enter,就等於丟入一個訊息./kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test-topic
建立 consumer,這時候 terminal 會處於接受訊息的狀態,會把剛才 producer 丟入的訊息全部顯示出來./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test-topic --from-beginning
參考官網的 golang sample 還有 AI 開始把範例程式寫起來,原本以為也是 happly flow 直接一路通,但沒想到就在這裡卡了好一陣子。
程式寫完跑起來後,中了個底下的錯誤。
failed to dial leader:failed to dial: failed to open connection to localhost:9092: dial tcp 127.0.0.1:9092: connectex: No connection could be made because the target machine actively refused it.
一開始以為是防火牆的問題,所以還去調了一下 windows 的防火牆,但後來發現不是。
緊接著又再確認是不是 docker 的 kafka 沒跑起來,然後用了 docker ps 確認,也用了剛才的 kafka-console producer & consumer 再試著寫跟收訊息,也都一切正常。
後來沒招,就開始爬網路跟問 AI 看有沒有什麼靈感。
一開始 AI 很有信心的回覆,很有機會是相關的參數設定有錯。例:KAFKA_ADVERTISED_LISTENERS or KAFKA_LISTENERS……。
所以我就照著 AI 叫我要填的參數填好,然後 container 刪掉,再重啟一次 image。
結果卻還是是一樣。
就在卡了好一陣子後,終於被我試到,原來是少設定對應的 port 號……。
AI 有提示說也有可能是 port 號的問題,但我在 container 起來的時候,有去看過 log,他的確是跑在 locathost:9092 的 port 號上,所以我一直不覺得有問題。
後來才留意到,在起 container 的時候,要多設定作業系統外面跟 docker 裡面的 port 號對應……。
因為 container 裡面的 port 可以跟外面對到的不一樣,所以在設定上可以把它分開。只是如果都只是要用預設的 9092 port,那就還是要設定這個對應的 port 號。
但故事到這邊還沒結束,現在 kafka 也起來了,golang 程式也顯示寫入資料成功。但我在 docker terminal 裡的 kafka-console-consumer 就是一直收不到資料……。
反覆的確認 golang 程式有沒有寫錯,kafka 是不是有設定又調錯,同一時間 AI 也一直不斷的給一些靈感,例如:確認 topic 的 offset、有沒有寫錯 partition……等。
在鬼打牆了一陣子後,才在 docker log 裡面發現原來一直在噴錯,但我沒看到……
WARN Auto topic creation failed for __consumer_offsets with error 'INVALID_REPLICATION_FACTOR': Unable to replicate the partition 3 time(s): The target replication factor of 3 cannot be reached because only 1 broker(s) are registered. (kafka.server.DefaultAutoTopicCreationManager)
原來我起成 cluster 了,當他試著要從 leader partition 複製到 follower partition 的時候,就一直失敗,所以就一直噴錯。
這時候又再回去kafka image 官網再研究了一下它的設定說明,
終於看到致命的一句話,It's important to note that if you are overriding any configuration, then none of the default configurations will be used。所以我只要動到隨便任何一個參數,其他預設的參數就會全部失效。
最後我把我另外設定的參數全部拿掉,只留下在起 container 時的對應 port 號設定,然後就一切 happy 了。
docker run -d --name broker -p 9092:9092 apache/kafka:latest
原本以為,這應該是點像玩具般的 side project 而已,沒想到會在這種地方卡這麼久……。默默的把這些坑筆記起來。
github.com/segmentio/kafka-go 比較好用