背景:
線上有個服務用作視頻通信用,偶爾會產生大量的tcp連接,在一次使用過程中發現視頻無法新建通信,同時服務日誌一直刷錯誤日誌,日誌內容包含open too many files。通過搜索得知,linux系統一切皆文件的原則,每產生一個tcp連接就相當於新建一個文件,於是進程的連接數超過系統設置的句柄數,導致無法增加新連接,因此也就視頻通信業務異常。所以解決這個問題的最直接辦法就是增加進程句柄數限制,以下就是圍繞這個設置過程產生的一些問題記錄。
過程:
1.按照慣例,以前一般性得知,設置句柄數:
查看當前單個用戶限制數量:
ulimit -Sn: 軟限制數量-用戶可設置的最大句柄數量,不能超過硬限制大小。
ulimit -Hn: 硬限制數量-系統給與用戶可設置的最大句柄數量
查看系統文件總限制數量:
cat /proc/sys/fs/file-max
臨時設置:
ulimit -SHn 65535
設置軟限制和硬限制爲65535。
永久設置:
/etc/security/limits.conf 添加:
* soft nofile 65535
* hard nofile 65535
2.按照上面設置完後,以爲這就結束了,但是在重啓服務一段時間後,又發現開始報錯,查看限制ulimit命令確實是增加了,於是開始更詳細的查找問題原因,經過百度一堆的誤導,終於找到一些可用的命令:
1.查看系統當前打開文件數:
/proc/sys/fs/file-nr
4192 0 791172
最左邊:當前系統打開文件數
中間:不管
右邊:系統可打開的文件數
2.查看進程當前打開文件數:
ls -l /proc/$pid/fd/* |wc -l
這個命令是最真實的,lsof -n之類的都不準。
通過上面命令看到實際的打開文件數並沒有達到自己通過ulimit所設置的數量,於是就覺得很奇怪,再次查找,通過下面命令找到了進程限制的大小:
cat /proc/$pid/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes unlimited unlimited processes
Max open files 4096 4096 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 7259 7259 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
max open files 這條顯示才4096,這才發現,原來根本就沒有增加成功。 那到底爲什麼會這樣呢,一直在沒有目標的搜索,突然想到是不是和systemd有關係,因爲業務的服務都是通過systemd守護進程啓動的。 然後一陣搜索,終於找到問題了。
centos7裏的systemd的limit是不受/etc/security/limits.conf管理的,這個在文件中其實就有描述了
#It does not affect resource limits of the system services.
所以要管理文件systemd啓動服務的limit要修改/etc/systemd/system.conf才生效,具體方法如下:
方法一:
/etc/systemd/system.conf 添加
DefaultLimitNOFILE=100000
重啓服務器
方法二:
修改相關服務的啓動文件,添加:
LimitNOFILE=100000
然後
systemctl daemon-reload
systemctl restart xxx
再次查看limits文件,生效了,問題終於解決。