天天看點

Go程式在容器中部署需要注意的小問題問題描述造成的後果解決方法

引用書籍<<GO語言程式設計之旅>>

問題描述

在Go語言中,Go scheduler的P數量非常重要,因為它會極大地影響Go在運作時的表現。

在目前的Go語言中,P的數量預設是系統的CPU核數。在容器化的環境中,Go程式所擷取的CPU核數是錯誤的,它所擷取的是主控端的CPU核數。即使容器和主控端的CPU核數是共享的,但在叢集中我們會針對每個Pod配置設定指定的核數,是以實際上我們需要的是Pod的核數,而不是主控端的CPU核數。

造成的後果

曾提到Go的M:N排程模型,其要求M必須與P進行綁定,然後才能不斷地在M上循環尋找可運作的G來執行相應的任務。

注意,M必須與P進行綁定,其綁定的這個P,要求必須是空閑狀态。

但在容器化的部署環境中,P 的數量由于被“錯誤”設定,是以擁有大量空閑的 P。可以這樣了解,隻要有足夠多的M,那麼P就可以都被綁定。這時又産生了另外一個問題,M的數量是否會不斷增加呢?答案是會的。在程式運作過程中,由于産生了網絡I/O阻塞,導緻M會随着程式的不斷執行而不斷增加,,即能夠達到前面假設的情況。最終導緻Go程式的延遲加大,程式響應緩慢。

解決方法

産生這個問題的本質原因是Go程式沒有正确地獲得我們所期望的CPU核數(應當擷取具體配置設定給Pod的配額),是以解決方案有兩種:· 結合部署情況,主動設定正确的GOMAXPROCS核數。· 通過cgroup資訊,讀取容器内的正确GOMAXPROCS核數。

目前,Go 尚沒有非常完美的辦法來解決這個問題,是以這裡推薦使用 Uber 公司推出的uber-go/automaxprocs 開源庫,它會在 Go 程式運作時根據 cgroup 的挂載資訊來修改GOMAXPROCS核數,并基于一定規則選擇一個最合适的數值

在main裡面初始化導入這個包

Go程式在容器中部署需要注意的小問題問題描述造成的後果解決方法

我們隻需在 Go 程式啟動時進行引用即可,如果有特殊的需求,那麼主動設定GOMAXPROCS也是可以的。