golang 進程出現too many open files的排查過程

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

1. 現象

服務的cpu跑滿(golang實現), 並大量報too many open files錯誤.服務使用systemd來運行,部署在阿里ecs上.


2.分析

從日誌來看,cpu的上升主要為到達檔案數限制引起的,但之前已經更改過系統的檔案數及所有使用者的檔案數,按道理是不應該出現這個問題的,後來查閱資料發現,檔案數可以從三個維度限制分別為作業系統限制,使用者態限制,以及進程限制,對於這三個維度選取最小值生效.於是對系統進行分析.


首先查看當前開啟檔案數, 進程佔用的檔案數並不多.

lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more

然後擷取系統級檔案數限制

輸入命令

cat /etc/sysctl.conf

得到

fs.file-max = 1000000


查詢使用者級檔案數限制

cat /etc/security/limits.conf

得到

* soft nofile 655350

* hard nofile 655350


單獨擷取程式檔案數限制(9928為進程id)

cat /proc/9928/limits

得到

Max open files 1024 4096 files

如上可以發現, 雖然系統及使用者的檔案數調大了,但是程式的仍然是一個很低的值, 這裡進程的檔案數一般情況下是預設繼承使用者級的值的,而這裡卻沒有繼承,一開始懷疑是systemd啟動的問題,但是手寫了另外一個測試服務,發現該服務又繼承了使用者檔案數.

百思不得其解的情況下在systemd的啟動指令碼裡加了檔案數的初始化值.

 如下:

[Service]

Type=simple

LimitNOFILE=40960

LimitNPROC=40960

單獨擷取程式(9928為進程id)

cat /proc/9928/limits

得到

Max open files 40960 40960 files


發現檔案數被設定成了啟動時的初始化值.至於為什麼沒有繼承使用者級的值,懷疑是程式裡做了參數設定,這裡如果有人知道golang裡具體情況的話,還望不吝賜教.


3. 總結

歸結來說出現檔案描述符的錯誤的排查步驟如下:

首先,判斷配置參數是否正確,這裡涉及到對上面提到的三個維度檢查,特別時進程維度,如果只是ulimit -n 一下就完事了,那估計舊要像我一樣進坑了.

如果參數都正確,那麼查看一下當前系統被使用了多少檔案數,如果使用的確實多,那要看一下使用在什麼地方,這裡一般有兩種情況,大量串連未關閉,或者大量讀檔案的控制代碼未關閉.具體原因相信到這裡就可以排查出來了.



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.