一、作用
Linux對於每個用戶,系統限制其最大進程數。為提高性能,可以根據設備資源情況,設置各linux 用戶的最大進程數。
ulimit主要是用來限制進程對資源的使用情況的,它支持各種類型的限制,常用的有:
內核文件的大小限制
進程數據塊的大小限制
Shell進程創建文件大小限制
可加鎖內存大小限制
常駐內存集的大小限制
打開文件句柄數限制
分配堆棧的最大大小限制
CPU占用時間限制用戶最大可用的進程數限制
Shell進程所能使用的最大虛擬內存限制
有個疑問:服務器資源是有限制的,limits.conf會限制資源,但是對於ulimit來說限制是粒度是哪些?
1)用戶 ? 進程?
2)如果是進程的限制,系統中會有多個進程,那所有的進程同時需要受限於用戶或整個系統的資源限制。
二、用法
ulimit使用的基本格式為:ulimit [options] [limit]
具體的options參數含義如下表所示:
選項 含義 -a 顯示當前系統所有的limit資源信息。 -H 設置硬資源限制,一旦設置不能增加。 -S 設置軟資源限制,設置后可以增加,但是不能超過硬資源設置。 -c 最大的core文件的大小,以 blocks 為單位。 -f 進程可以創建文件的最大值,以blocks 為單位. -d 進程最大的數據段的大小,以Kbytes 為單位。 -m 最大內存大小,以Kbytes為單位。 -n 查看進程可以打開的最大文件描述符的數量。 -s 線程棧大小,以Kbytes為單位。 -p 管道緩沖區的大小,以Kbytes 為單位。 -u 用戶最大可用的進程數。 -v 進程最大可用的虛擬內存,以Kbytes 為單位。 -t 最大CPU占用時間,以秒為單位。 -l 最大可加鎖內存大小,以Kbytes 為單位。
其中ulimit -n用於限制進程能夠打開的文件描述符的最大數目。因為任何設備在linux下都是文件,通信的接口也有專門的接口文件負責,所以linux下進程tcp鏈接的最大並發量也受限於該值。
[root@centos5 ~]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited max nice (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 4096 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 max rt priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 4096 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited||<
其中 "open files (-n) 1024 "是Linux操作系統對一個進程打開的文件句柄數量的限制(也包含打開的SOCKET數量,可影響MySQL的並發連接數目)。
這個值可用ulimit 命令來修改,但ulimit命令修改的數值只對當前登錄用戶的目前使用環境有效,系統重啟或者用戶退出后就會失效.
有時候為了方便起見,也可以將用戶資源的限制統一由一個文件來配置,這個文件就是/etc/security/limits.conf,該文件不但能對指定用戶的資源進行限制,還能對指定組的資源進行限制。該文件的使用規則如下:
<domain> <type> <item> <value>
其中:
domain表示用戶或者組的名字,還可以使用 * 作為通配符,表示任何用戶或用戶組。
Type 表示限制的類型,可以有兩個值,soft 和 hard,分別表示軟、硬資源限制。軟限制是指限制用戶同時打開的文件數目,硬限制是指系統根據硬件資源(主要指內存)計算出來的最多可打開的文件數目。通常軟限制低於硬限制;建議不要將軟限制和硬限制修改過大。
item 表示需要限定的資源名稱,常用的有nofile、cpu、stack等。分別表示最大打開句柄數、占用的cpu時間、最大的堆棧大小。
value 表示限制各種資源的具體數值。
除了limits.conf文件之外,還有一個/etc/security/limits.d目錄,可以將資源限制創建一個文件放到這個目錄中,默認系統會首先去讀取這個目錄下的所有文件,然后才去讀取limits.conf文件。所有資源限制設置完成后,退出shell終端,再次登錄shell終端后,ulimit設置即可自動生效。
注意:各種配置的生效方式。
對於需要做許多 socket 連接並使它們處於打開狀態的Java 應用程序而言,最好通過使用 ulimit -n xx 修改每個進程可打開的文件數,缺省值是 1024。
ulimit -n 4096 將每個進程可以打開的文件數目加大到4096,缺省為1024
其他建議設置成無限制(unlimited)的一些重要設置是:
數據段長度:ulimit -d unlimited
最大內存大小:ulimit -m unlimited
堆棧大小:ulimit -s unlimited
CPU 時間:ulimit -t unlimited
虛擬內存:ulimit -v unlimited
配置生效方式
暫時地,適用於通過 ulimit 命令登錄 shell 會話期間。
永久地,通過將一個相應的 ulimit 語句添加到由登錄 shell 讀取的文件中, 即特定於 shell 的用戶資源文件,如:
1)、解除 Linux 系統的最大進程數和最大文件打開數限制:
vi /etc/security/limits.conf
# 添加如下的行
* soft noproc 11000
* hard noproc 11000
* soft nofile 4100
* hard nofile 4100
說明:* 代表針對所有用戶,noproc 是代表最大進程數,nofile 是代表最大文件打開數
2)、讓 SSH 接受 Login 程式的登入,方便在 ssh 客戶端查看 ulimit -a 資源限制:
a、vi /etc/ssh/sshd_config
把 UserLogin 的值改為 yes,並把 # 注釋去掉
b、重啟 sshd 服務:
/etc/init.d/sshd restart
3)、修改所有 linux 用戶的環境變量文件:
vi /etc/profile
ulimit -u 10000
ulimit -n 4096
ulimit -d unlimited
ulimit -m unlimited
ulimit -s unlimited
ulimit -t unlimited
ulimit -v unlimited
保存后運行#source /etc/profile 使其生效
在使用ulimit時,有以下幾種使用方法:
(1)在用戶環境變量中加入
如果用戶使用的是bash,那么就可以在用戶目錄的環境變量文件.bashrc或者.bash_profile中加入“ulimit -u 128”來限制用戶最多可以使用128個進程。
(2)在應用程序的啟動腳本中加入
如果應用程序是tomcat,那么就可以在tomcat的啟動腳本startup.sh腳本中加入“ulimit -n 65535”來限制用戶最多可以使用65535個文件描述符。
(3)直接在shell命令終端執行ulimit命令
這種方法的資源限制僅僅在執行命令的終端生效,退出或者關閉終端后,設置失效,並且這個設置不影響其它shell終端。
公司服務器需要調整 ulimit的stack size 參數調整為unlimited 無限,使用ulimit -s unlimited時只能在當時的shell見效,重開一個shell就失效了。。於是得在/etc/profile 的最后面添加ulimit -s unlimited 就可以了,source /etc/profile使修改文件生效。
如果碰到類似的錯誤提示ulimit: max user processes: cannot modify limit: 不允許的操作 ulimit: open files: cannot modify limit: 不允許的操作
為啥root用戶是可以的?普通用戶又會遇到這樣的問題?
看一下/etc/security/limits.conf大概就會明白。
linux對用戶有默認的ulimit限制,而這個文件可以配置用戶的硬配置和軟配置,硬配置是個上限。超出上限的修改就會出“不允許的操作”這樣的錯誤。
在limits.conf加上
* soft noproc 10240
* hard noproc 10240
* soft nofile 10240
* hard nofile 10240
就是限制了任意用戶的最大進程數和文件數為10240。
查看系統級別資源限制:
1.系統級別:
sysctl -a (-a:顯示當前所有可用的值)
系統總限制:cat /proc/sys/fs/file-max 等一系列值,修改/etc/sysctl.conf 中也可以控制
/proc/sys/fs/file-nr,可以看到整個系統目前使用的文件句柄數量
修改此硬限制的方法是修改/etc/rc.local腳本,在腳本中添加如下行:
echo 8000037 > /proc/sys/fs/file-max
這是讓Linux在啟動完成后強行將系統級打開文件數硬限制設置為800037。
這表明這台Linux系統最多允許同時打開(即包含所有用戶打開文件數總和)800037個文件,是Linux系統級硬限制,所有用戶級的打開文件數限制都不應超過這個數值。該值是Linux系統在啟動時根據系統硬件資源狀況計算出來的最佳的最大同時打開文件數限制,如果沒有特殊需要,不應該修改此限制,除非想為用戶級打開文件數限制設置超過此限制的值。
查找文件句柄問題的時候,lsof可以很方便看到某個進程開了那些句柄.也可以看到某個文件/目錄被什么進程占用了.
2.session 設置:
ulimit -a # 查看所有的
ulimit -S -n1024 #設置當前會話的打開文件數軟連接數為 1024.
ulimit -H -n1024 #設置當前會話的打開文件數硬連接數為 1024.
ulimit -n 996 #設置當前會話的打開文件數硬&&軟連接數都為 1024.
3.設置用戶(只針對用戶的每個進程):
#<domain> <type> <item> <value>
#
* soft nofile 32768
* hard nofile 65536
ulimit -n vs. file-max ?
簡單的說, ulimit -n控制進程級別能夠打開的文件句柄的數量, 而max-file表示系統級別的能夠打開的文件句柄的數量。
ulimit -n的設置在重啟機器后會丟失,因此需要修改limits.conf的限制,limits.conf中有兩個值soft和hard,soft代表只警告,hard代表真正的限制
Cat /etc/security/limits.conf
* soft nofile 150000 * hard nofile 150000
這里我們把soft和hard設置成一樣的。
“cat /proc/sys/fs/file-max”,或“sysctl -a | grep fs.file-max”查看系統能打開的最大文件數。查看和設置例如:
[root@vm014601 ~]# sysctl -a |grep fs.file-max fs.file-max = 200592 [root@vm014601 ~]# echo "fs.file-max = 2005920" >> /etc/sysctl.conf [root@vm014601 ~]# sysctl -p [root@vm014601 ~]# cat /proc/sys/fs/file-max 2005920
file-nr是只讀文件,第一個數代表了目前分配的文件句柄數;第二個數代表了系統分配的最大文件句柄數;比如線上系統查看結果:
# cat /proc/sys/fs/file-max 1106537 # cat /proc/sys/fs/file-nr 1088 0 1106537 # lsof | wc -l 1506
可以看到file-nr和lsof的值不是很一致,但是數量級一致。為什么會不一致?原因如下:
寫到lsof是列出系統所占用的資源,但是這些資源不一定會占用打開文件號的。如共享內存,信號量,消息隊列,內存映射.等,雖然占用了這些資源,但不占用打開文件號.
我曾經在前端機上很長時間都無法得到lsof | wc -l 的結果,這個時候可以通過file-nr粗略的估算一下打開的文件句柄數。
參考資料:
linux下進程的進程最大數、最大線程數、進程打開的文件數和ulimit命令修改硬件資源限制
http://ixdba.blog.51cto.com/2895551/1432521
通訊系統經驗談【二】解讀內核參數 - socket/文件句柄資源限制參數