再談Linux的ulimit
測試腳本
[[email protected] ~]# cat /tmp/test_ulimit.py
import sys
def test_n():
total=[]
try:
for i in range(0,100000):
total.append(open(‘/tmp/{}-{}‘.format(‘jjkkll‘,i),‘w‘))
except Exception as err:
print(i, repr(err))
test_n()
關於/etc/security/limit.conf中開篇既有兩句話提示
#This file sets the resource limits for the users logged in via PAM.
#It does not affect resource limits of the system services.
意思就是這裏的限制只對經過PAM驗證的登陸用戶有效,並明確說明對開機自啟的系統服務(經chkconfig 或systemd控制的開機啟動服務)以及 /etc/init.d/rc.local(經試驗亦無效) 中的命令無效。
另外經驗證:同時在/etc/security/limit.conf和/etc/profile中設置不同的值,/etc/profile中的值最終生效(說明PAM認證在profile之前)
那如何在開啟及啟動的服務中突破系統默認的ulimit值呢?
首相嘗試了在/etc/profile
中添加對應設置,經測試對開機自啟的系統服務
和 /etc/init.d/rc.local
仍然無效(並且驗證了系統服務的運行時間要早於/etc/init.d/rc.local)
[[email protected] ~]# cat /tmp/log-init (1021, "IOError(24, ‘Too many open files‘)") Sat Nov 3 06:35:19 EDT 2018 [[email protected] ~]# cat /tmp/log-rc.local (1021, "IOError(24, ‘Too many open files‘)") Sat Nov 3 06:35:25 EDT 2018 [[email protected] ~]# ulimit -n 3000 [[email protected] ~]#
而且在/etc/profile中假如ulimit配置(以及任何需要root權限運行的命令),那在以其他用戶登陸時,就會報一條“無權限”類錯誤。是因為 /etc/profile 在系統啟動過程中執行的時機:(倒數第一或 第二步)即任何用戶登陸前才/先執行/etc/profile,然後再是 ~/.bash_profile(若有的話)
那麽到底該如何解決上面的問題呢?
後經查明,/etc/init.d/xxxx 以及/etc/rc.loca中的命令都是centos7之前的產物,centos7之後系統引導及服務管理由sysV改為了systemd,而systemd對於ulimit中指定的各類限制是在xxxx.service文件中設置的,這也是推薦的方式。例如 LimitNOFILE=65536。
但是如果非要在/etc/init.d/xxxx以及/etc/rc.local中突破默認限制的話
- 對於/etc/rc.local,有如下方法
在 /usr/lib/systemd/system/rc-local.service 的 [Service] 段下增加相應配置,如 LimitNOFILE=3000 - 對於/etc/init.d/xxx
centos7 中還沒找到解決方案(其實執著於此也無意義,因為7的服務管理是systemd)
centos6 中科通過在/etc/init.d/functions
中增加一句ulimit -n 65536
(以及其他設置)來解決
經過實驗看下來,發現了一個特點,一個進程能打開的文件描述符總是比設置的nofile值小3,這是因為還有0,1,2 三個標準輸入,輸出,錯誤的存在。
再談Linux的ulimit