關於 ulimit 的兩個天坑

SRETalk發表於2024-04-03

稍微有點 Linux 經驗的人一定會遇到過 “Too many open files” 錯誤,這個錯誤本質是 ulimit 設定不合理導致的。關於 ulimit 設定,有哪些需要注意的點呢?本文給大家做一個介紹,希望對大家有所幫助。

如何確認 ulimit 設定生效了?

很多人設定了 ulimit 最後發現還是報錯 “Too many open files”。先不論如何操作,我們先要知道怎麼確認程序的 ulimit 到底是多少。這不是透過 ulimit -n 來看的,而是找到程序的 pid,然後檢視 /proc/<程序的PID>/limits 檔案,這個檔案裡面記錄了程序的真實 ulimit 資訊。比如:

20240401155313

如何設定 ulimit?

如果 ssh 到機器上,透過 nohup 之類的方式啟動程序,ulimit 將受限於 /etc/security/limits.conf 檔案的配置。比如我這個機器:

[root@aliyun-2c2g40g3m ~]# cat /etc/security/limits.conf | grep -v '^#' | grep -v '^$'
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535

這是 aliyun 的一臺虛機,看起來阿里雲已經幫我們設定了 ulimit 為 65535,這個是 OK 的,挺大的了。但是,如果你是透過 systemd 啟動的服務,ulimit 將受限於 systemd 的配置。比如某個服務的 service 檔案設定為:

[Unit]
Description="Categraf"
After=network.target

[Service]
Type=simple

ExecStart=/opt/categraf/categraf
WorkingDirectory=/opt/categraf

Restart=on-failure
SuccessExitStatus=0
LimitNOFILE=65535
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=categraf


[Install]
WantedBy=multi-user.target

看到 LimitNOFILE 那行配置了麼?就是它。

如果 service 檔案中沒有配置 LimitNOFILE,systemd 會有個預設配置,systemd 的預設配置可以透過如下方式檢視:

[root@aliyun-2c2g40g3m systemd]# pwd
/etc/systemd
[root@aliyun-2c2g40g3m systemd]# grep FILE *.conf
system.conf:#DefaultLimitNOFILE=
user.conf:#DefaultLimitNOFILE=

咱也不用關心預設配置是多少,反正每個 service 都配置一下 LimitNOFILE 就好了。

其他程序管理工具對 ulimit 也有影響

如果你不是透過 systemd 託管程序的,而是使用了其他的程序管理工具,比如 supervisor,那麼 ulimit 將受限於 supervisor 的配置。如果你是透過 Saltstack 之類的工具,批次透過 shell 啟動程序,還要小心 salt minion 的 ulimit 設定,至於 supervisor 和 salt minion 如何調整 ulimit,這裡就不展開了,說多了都是淚。

控制代碼限制不止是 ulimit

實際上,作業系統對控制代碼的限制不止是 ulimit,還有 /proc/sys/fs/file-max 這個引數,這個引數限制了整個系統的控制代碼數量。如果你的系統控制代碼數量設定過小,那麼即使你設定了 ulimit,也會受限於這個引數。比如我的系統如下:

[root@aliyun-2c2g40g3m systemd]# cat /proc/sys/fs/file-max
188844

如何調整這個引數呢?操作命令如下:

[root@aliyun-2c2g40g3m systemd]# echo 100000 > /proc/sys/fs/file-max
[root@aliyun-2c2g40g3m systemd]# cat /proc/sys/fs/file-max
100000
[root@aliyun-2c2g40g3m systemd]# echo 188844 > /proc/sys/fs/file-max
[root@aliyun-2c2g40g3m systemd]# cat /proc/sys/fs/file-max
188844

如果想要機器重啟也能生效,就要修改 sysctl.conf 檔案,比如:

fs.file-max = 188844

如何監控控制代碼相關問題?

系統層面總共分配了多少控制代碼可以透過 /proc/sys/fs/file-nr 檔案檢視,比如:

[root@aliyun-2c2g40g3m systemd]# cat /proc/sys/fs/file-nr
1760	0	188844

第一個數字是已經分配的控制代碼數量,第三個數字是系統總共可分配的控制代碼數量。如果第一個數字接近第三個數字,那麼就要小心了。

夜鶯的內建告警規則中,有針對 categraf 的機器指標的告警規則,其中就有檔案控制代碼使用率的告警:

linux_sysctl_fs_file_nr / linux_sysctl_fs_file_max > 0.9

另外,如果你使用了 categraf 的 procstat 程序監控外掛,並且開啟了 gather_more_metrics 中的 limit,還會採集到 procstat_rlimit_num_fds_soft 指標,夜鶯的內建規則中還有這麼一條告警規則:

procstat_rlimit_num_fds_soft < 2048

這是採集程序的軟控制代碼限制,如果軟控制代碼限制過小,就告警。通常,小於 2048,大機率就是運維人員忘記做作業系統的引數調優了。

如上知識,希望對你有幫助。文末請允許我插播一個小廣告。本人創業兩年了,我們公司的業務如下,如果你有這方面的需求,歡迎聯絡我們做產品技術交流哈。

🎯 關於快貓星雲

快貓星雲是一家雲原生智慧運維科技公司,由知名開源專案“夜鶯(Nightingale)”的核心開發團隊組成,創始團隊均來⾃阿⾥、百度、滴滴等互聯⽹公司。夜鶯是一款開源雲原生監控工具,是中國計算機學會接受捐贈並託管的第一個開源專案,在GitHub上有超過8000顆星,迭代釋出了超過100多個版本,上百位社群貢獻者,是國內領先的開源可觀測性解決方案。

快貓星雲以開源夜鶯為核心打造的“Flashcat平臺”,是國內頂級互聯⽹公司可觀測性實踐的產品化落地,致力於讓可觀測性技術更好的服務企業,保障服務穩定性。Flashcat 平臺具有以下特點:

  • 統一採集:採用外掛化思路,內建整合上百種採集外掛,伺服器、網路裝置、中介軟體、資料庫、應用、業務,均可監控,開箱即用。
  • 統一告警:支援幾十種資料來源對接,收集各類監控系統的告警事件,進行統一的告警收斂、降噪、排班、認領、升級、協同,大幅提升告警處理效率。
  • 統一觀測:將 Metrics、Logs、Traces、Events、Profiling 等多種可觀測性資料融會貫通,並預置行業最佳實踐,既提供全域性業務視角、技術視角的駕駛艙,也提供層層下鑽的故障定位能力,有效縮短故障發現和定位時間。

快貓星雲,讓可觀測性資料更有價值!
https://flashcat.cloud/

相關文章