項目馬上要上線了,突然發現預發佈環境的 etcd 連不上了。雖然別人催的很緊急,但出於保存現場的目的,還是詳查了一下爲啥 etcd 連不上。
排查結果
- 排查過程就不詳細列舉了,就是一個抽絲剝繭的過程。很艱難,其實最後發現真相才覺得過程都不值一提。
- 結論是:jetcd 在創建 watcher 之後,如果要關掉它,不管是
Client.close()
、還是watcher.close()
,都無法馬上關掉連接,然後連接會越來越多,最後把連接數佔滿。通過lsof -i:2379
可以看到答案。 - 於是乎,我去提了一個 ISSUES,截至發稿時,沒有人回覆。
- 但是馬上要上線了,必須想辦法解決一下這個問題。首先在開發的時候,就已經搭建了 jetcd 的環境,隨時可以改源碼自己出包。諮詢了一下熟悉 grpc 的同事,很明顯問題是
ManagedChannel
在 shutdown 之後,關不掉這個連接;同事建議我用 shutdownNow,遂改源碼試了一下,果然可以。不過爲什麼 shutdown 之後關不掉,仍然需要詳細排查。
2019-06-01 補充
- 通過抓包分析,發現使用 shutdown 時,客戶端不會主動發起 FIN 請求斷開連接,而 shutdownNow 就會。
結束語
- etcd 的學習還需要繼續努力。