記錄一次“異常bug”,具體資訊如下。主要是記錄一下處理過程,可能口水話比較多,如果想看結果,直接往後拉即可。
最後一行
起初,運維同事找到我,跟我說程式出問題了,系統升級,一直連不上nacos。
我看了日誌資訊之後,剛開始還是沒有在意的。畢竟是nacos報錯,報錯還那麼明顯:java.net.ConnectException: Connection refused (Connection refused)
我信心滿滿告訴他,是nacos沒起起來,或者是配置檔案有問題。這不是程式碼的問題。(這裡帶有一點點僥倖心理)
我很快就被打臉了。其他服務都能起起來,唯獨我們同事寫的這個模組出了bug?就是連不上nacos。此時讓他們重啟nacos,肯定是不現實的,畢竟nacos是沒問題的。重啟這個報錯的模組也試過了,但是模組就是一直在重連nacos,並且最終連不上去。
於是我把nacos的載入順序重新捋一遍。在docker中起服務,首先是載入docker的環境變數,然後替代掉程式中的bootstrap.yml。這裡猜測是啟動命令的問題。
配置的讀取過程
1.當docker容器啟動時,獲取到容器的環境變數(通常是服務名,nacos地址,nacos名稱空間,nacos組,需要的配置檔案)。
2.jar啟動時,會使用容器的環境變數會作為相關引數。(原理可以查詢關鍵詞: spring jar 引數)
3.springboot啟動時會注入相關的引數,從而獲取到nacos的配置資訊,並將nacos做為配置中心,從nacos上讀取相關配置。
4.springboot 讀到相關配置,其中一個配置是將nacos做為註冊中心,將服務註冊到nacos上。 (本次異常的發生點)
於是我又去問運維同事容器的啟動命令。(因為docker中的環境變數,已經在啟動命令中做了對映了,所有我們只用看運維同事的啟動命令即可)
exec java -jar island-serviceconfig.jar --server-addr=sc-nacos:8848 --namespace=public --group=service-cool --config-common=island-common.yaml --config-service=island-serviceconfig.yaml
看著啟動命令,我又陷入了沉思,這是怎麼操作,一定毛病也沒有。就這樣,嘗試了好幾遍。一個下午就沒有了。
後面我仔細回味報錯資訊。這不可能,nacos難道有版本錯誤?很快被我否定,這次升級系統,重新拉了程式碼。之前都是好好的,運維那邊的nacos版本是沒有改動過的。
於是我上去倉庫看程式碼。程式碼也沒有問題,近期沒有人修改過。這很鬱悶吶。
最後迫不得已,去看了nacos的原始碼,最後找到了一點點資訊,nacos是在我們沒有配置nacos地址的時候,才會去載入localhost:8848這個地址。
那麼問題來了,明明我們配置了nacos地址,為什麼還是會去載入localhost:8848?這又回到了原點。又開始懷疑是運維同事的執行命令出了問題,但是確實是沒有問題的。
我慢慢靜下心來。也許是我一開始的出發點就出問題了。我一直以為是運維同事部署出了問題,思維停留在運維那邊,絲毫沒有懷疑是配置問題的問題。
最終快下班了和另一個同事討論,我剛開口描述完問題,他就說了一句:臥槽,我搞了三天。
果然,之前不是好著的,而是有這位同事一直在“擦屁股”,但是git上面的配置問題,他又沒有進行更新。導致運維每次拉取程式碼,都會出現這個問題。具體問題如下
乍一看這配置沒啥問題,我之前檢查配置檔案也是,每次看下去都沒有問題,洽洽是我的以為,導致這個問題沒能及時被發現。這就是一個縮排的問題。
正確的配置如下:
最後,感受一波吐槽,其實最初運維的同事也發現這個縮排有問題,所有他手動改了很多,也反饋了,但是估計開發都很忙,就沒有修改git上的配置檔案。導致埋下了一顆大雷。好在寫程式碼的同事已經離職(手動狗頭保命)
總結:遇到bug不要慌,好好和運維同事做溝通,每個部門都有自己的規範和要求,像簡單的執行命令出了問題,這個還是很好排查的。切記切記,不要有甩鍋心理,不要有甩鍋心理,不要有甩鍋心理。
這次很明顯,運維同事就是被我們開發擺了一道,這也是開發這邊沒有注意的問題,或者說,這是不應該出現的問題,屬於比較低等的問題。饒是如此,我們也要重視起來,否則一個小小的雷,埋久了,他也是會發酵的,威力越來越大。