limit資源限制ulimit 詳解
系統性能一直是一個受關注的話題,如何通過最簡單的設置來實現最有效的性能調優,如何在有限資源的條件下保證程序的運作,ulimit 是我們在處理這些問題時,經常使用的一種簡單手段。ulimit 是一種 Linux 系統的內鍵功能,它具有一套參數集,用于為由它生成的 shell進程及其子進程的資源使用設置限制。
命令總結:
查看系統用戶所有限制值:ulimit -a
設置用戶open files(用戶可以打開文件的最大數目):ulimit -n 4096。執行該命令非root用戶只能設置到4096。想要設置到8192需要sudo權限或者root用戶。
查看當前系統打開的文件數量: lsof | wc -l
查看當前進程的打開文件數量:lsof -p pid | wc -l (lsof -p 1234 | wc -l )
查看當前進程的最大可以打開的文件數:cat /proc/PID/limits (如果通過ulimit -n 設置或者修改/etc/security/limits.conf,看看進程是否生效)
查看系統總限制打開文件的最大數量:cat /proc/sys/fs/file-max
lsof只能以root權限執行。在終端下輸入lsof即可顯示系統打開的文件,因為 lsof 需要訪問核心內存和各種文件,所以必須以 root 用戶的身份運行它才能夠充分地發揮其功能。
1、ulimit的功能
假設有這樣一種情況,當一臺 linux 主機上同時登陸了 10 個人,在系統資源無限制的情況下,這 10 個用戶同時打開了 500 個文檔,而假設每個文檔的大小有 10M,這時系統的內存資源就會受到巨大的挑戰。
而實際應用的環境要比這種假設復雜的多,例如在一個嵌入式開發環境中,各方面的資源都是非常緊缺的,對于開啟文件描述符的數量,分配堆棧的大小,CPU 時間,虛擬內存大小等等,都有非常嚴格的要求。資源的合理限制和分配,不僅僅是保證系統可用性的必要條件,也與系統上軟件運行的性能有著密不可分的聯系。這時,ulimit 可以起到很大的作用,它是一種簡單并且有效的實現資源限制的方式。
ulimit 用于限制 shell 啟動進程所占用的資源,支持以下各種類型的限制:
所創建的內核文件的大小、
進程數據塊的大小、
Shell 進程創建文件的大小、
內存鎖住的大小、
常駐內存集的大小、
打開文件描述符的數量、
分配堆棧的最大大小、
CPU 時間、
單個用戶的最大線程數、
Shell 進程所能使用的最大虛擬內存。同時,它支持硬資源和軟資源的限制。
作為臨時限制,ulimit 可以作用于通過使用其命令登錄的 shell 會話,在會話終止時便結束限制,并不影響于其他 shell 會話。而對于長期的固定限制,ulimit 命令語句又可以被添加到由登錄 shell 讀取的文件中,作用于特定的 shell 用戶。
2、使用ulimit
ulimit 通過一些參數選項來管理不同種類的系統資源。
ulimit 命令的格式為:ulimit [options] [limit]

主要關注兩個:
1)open files:– 用戶可以打開文件的最大數目
對應ulimit 的命令ulimit -n,可以使用ulimit -n 臨時設置。
對應/etc/security/limits.conf的資源限制類型是:nofile
* soft nofile 4096
* hard nofile 4096
2)max user processes – 用戶可以開啟進程/線程的最大數目
對應ulimit 的命令ulimit -u 臨時修改max user processes的值:ulimit -u 8192。
對應/etc/security/limits.conf的資源限制類型是: noproc
* soft nproc 8192
具體的 options 含義以及簡單示例可以參考以下表格。
ulimit 參數說明
選項 含義-a 顯示當前系統所有的limit資源信息。 -H 設置硬資源限制,一旦設置不能增加。例如:ulimit – Hs 64;限制硬資源,線程棧大小為 64K。-S 設置軟資源限制,設置后可以增加,但是不能超過硬資源設置。例如:ulimit – Sn 32;限制軟資源,32 個文件描述符。-c 最大的core文件的大小,以 blocks 為單位。例如:ulimit – c unlimited; 對生成的 core 文件的大小不進行限制。-f 進程可以創建文件的最大值,以blocks 為單位.例如:ulimit – f 2048;限制進程可以創建的最大文件大小為 2048 blocks。-d 進程最大的數據段的大小,以Kbytes 為單位。例如:ulimit -d unlimited;對進程的數據段大小不進行限制。-m 最大內存大小,以Kbytes為單位。例如:ulimit – m unlimited;對最大內存不進行限制。-n 可以打開的最大文件描述符的數量。例如:ulimit – n 128;限制最大可以使用 128 個文件描述符-s 線程棧大小,以Kbytes為單位。例如:ulimit – s 512;限制線程棧的大小為 512 Kbytes。-p 管道緩沖區的大小,以Kbytes 為單位。例如ulimit – p 512;限制管道緩沖區的大小為 512 Kbytes。-u 用戶最大可用的進程數。例如 limit – u 65536;限制用戶最多可以使用 65536個進程。-v 進程最大可用的虛擬內存,以Kbytes 為單位。ulimit – v 200000;限制最大可用的虛擬內存為 200000 Kbytes。-t 最大CPU占用時間,以秒為單位。ulimit – t unlimited;對最大的 CPU 占用時間不進行限制。-l 最大可加鎖內存大小,以Kbytes 為單位。
1
我們可以通過以下幾種方式來使用 ulimit:
一、在用戶的啟動腳本中
如果用戶使用的是 bash,就可以在用戶的目錄下的 .bashrc 文件中,加入 ulimit – u 64,來限制用戶最多可以使用 64 個進程。此外,可以在與 .bashrc 功能相當的啟動腳本中加入 ulimt。
二、在應用程序的啟動腳本中
如果用戶要對某個應用程序 myapp 進行限制,可以寫一個簡單的腳本 startmyapp。
ulimit – s 512
myapp
以后只要通過腳本 startmyapp 來啟動應用程序,就可以限制應用程序 myapp 的線程棧大小為 512K。
三、直接在控制臺輸入
ulimit – p 256
限制管道的緩沖區為 256K。
四、修改所有 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 使其生效
四、也可以針對單個用戶的.bash_profile設置:
vi ~./.bash_profile
#ulimit -n 1024
重新登陸ok
3、用戶進程的有效范圍
ulimit 作為對資源使用限制的一種工作,是有其作用范圍的。那么,它限制的對象是單個用戶,單個進程,還是整個系統呢?事實上,ulimit 限制的是當前 shell 進程以及其派生的子進程。舉例來說,如果用戶同時運行了兩個 shell 終端進程,只在其中一個環境中執行了 ulimit – s 100,則該 shell 進程里創建文件的大小收到相應的限制,而同時另一個 shell終端包括其上運行的子程序都不會受其影響:
Shell 進程 1
ulimit –s 100
cat testFile > newFile
File size limit exceeded
Shell 進程 2
cat testFile > newFile
ls –s newFile
323669 newFile
針對用戶永久生效:
那么,是否有針對某個具體用戶的資源加以限制的方法呢?答案是有的,方法是通過修改系統的 /etc/security/limits.conf配置文件。該文件不僅能限制指定用戶的資源使用,還能限制指定組的資源使用。該文件的每一行都是對限定的一個描述。
limits.conf的格式如下:
<domain> <type> <item> <value>
username|@groupname type resource limit
domain:username|@groupname:設置需要被限制的用戶名,組名前面加@和用戶名區別。也可以用通配符*來做所有用戶的限制。
type:有 soft,hard 和 -,soft 指的是當前系統生效的設置值。hard 表明系統中所能設定的最大值。soft 的最大值不能超過hard的值。用 – 就表明同時設置了 soft 和 hard 的值。
resource:
core – 限制內核文件的大小
date – 最大數據大小
fsize – 最大文件大小
memlock – 最大鎖定內存地址空間
nofile – 打開文件的最大數目
rss – 最大持久設置大小
stack – 最大棧大小
cpu – 以分鐘為單位的最多 CPU 時間
noproc – 進程的最大數目(系統的最大進程數)
as – 地址空間限制
maxlogins – 此用戶允許登錄的最大數目
要使 limits.conf 文件配置生效,必須要確保 pam_limits.so 文件被加入到啟動文件中。
查看 /etc/pam.d/login 文件中有:
session required /lib/security/pam_limits.so
例如:解除 Linux 系統的最大進程數和最大文件打開數限制:
vi /etc/security/limits.conf
# 添加如下的行
* soft noproc 20000 #軟連接
* hard noproc 20000 #硬連接
* soft nofile 4096
* hard nofile 4096
說明:* 代表針對所有用戶,noproc 是代表最大進程數,nofile 是代表最大文件打開數
需要注意一點:/etc/security/limits.d下也有noproc最大進參數的限制:
即 /etc/security/limits.d/下的文件覆蓋了/etc/security/limits.conf設置的值
這個是官網答疑:https://access.redhat.com/solutions/406663
# /etc/security/limits.conf
#This file sets the resource limits for the users logged in via PAM.
#It does not affect resource limits of the system services.
#Also note that configuration files in /etc/security/limits.d directory,
#That means for example that setting a limit for wildcard domain here
[root@tr10-46-65-29 ~]# cat /etc/security/limits.d/20-nproc.conf
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.
* soft nproc 8192
root soft nproc unlimited
現在已經可以對進程和用戶分別做資源限制了,看似已經足夠了,其實不然。很多應用需要對整個系統的資源使用做一個總的限制,這時候我們需要修改 /proc 下的配置文件。/proc 目錄下包含了很多系統當前狀態的參數,例如 /proc/sys/kernel/pid_max,/proc/sys/net/ipv4/ip_local_port_range 等等,從文件的名字大致可以猜出所限制的資源種類。
注意:
通過讀取/proc/sys/fs/file-nr可以看到當前使用的文件描述符總數。另外,對于文件描述符的配置,需要注意以下幾點:
所有進程打開的文件描述符數不能超過/proc/sys/fs/file-max
單個進程打開的文件描述符數不能超過user limit中nofile的soft limit
nofile的soft limit不能超過其hard limit
nofile的hard limit不能超過/proc/sys/fs/nr_open
4、用戶進程的有效范圍
問題1:su切換用戶時提示:Resource temporarily unavailable
或者通過進程跟蹤 strace -p pid 看到:Resource temporarily unavailab
通過ulimit -a,得到結果:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 63463
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 4096
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
在上面這些參數中,通常我們關注得比較多:
open files: 一個進程可打開的最大文件數.
max user processes: 系統允許創建的最大進程數量.
通過 ps -efL|grep java |wc -l
#24001
這個得到的線程數竟然是2萬多,遠遠超過4096
我們可以使用 ulimit -u 20000 修改max user processes的值,但是只能在當前終端的這個session里面生效,重新登錄后仍然是使用系統默認值。
正確的修改方式是修改/etc/security/limits.d/20-nproc.conf文件中的值。先看一下這個文件包含什么:
$ cat /etc/security/limits.d/90-nproc.conf # Default limit for number of user's processes to prevent# accidental fork bombs.# See rhbz #432903 for reasoning.* soft nproc 8192
我們只要修改上面文件中的8192這個值,即可。
問題2:linux 打開文件數 too many open files 解決方法
在運行某些命令或者 tomcat等服務器持續運行 一段時間后可能遇到 too many open files。
出現這句提示的原因是程序打開的文件/socket連接數量超過系統設定值。
java進程如果遇到java.net.SocketException: Too many open files,接著可能導致域名解析ava.net.UnknownHostException:
原因是用戶進程無法打開系統文件了。
查看每個用戶最大允許打開文件數量
ulimit -a
其中 open files (-n) 65535 表示每個用戶最大允許打開的文件數量是65535 。 默認是1024。1024很容易不夠用。
永久修改open files 方法
vim /etc/security/limits.conf
在最后加入
* soft nofile 65535
* hard nofile 65535
或者只加入
* - nofile 65535
最前的 * 表示所有用戶,可根據需要設置某一用戶,例如
fdipzone soft nofile 8192
fdipzone hard nofile 8192
注意"nofile"項有兩個可能的限制措施。就是項下的hard和soft。 要使修改過得最大打開文件數生效,必須對這兩種限制進行設定。 如果使用"-"字符設定, 則hard和soft設定會同時被設定。
改完后注銷一下就能生效。
通過 ulimit -n或者ulimit -a 查看系統的最大文件打開數已經生效了。但此時查看進程的最大文件打開數沒有變,原因是這個值是在進程啟動的時候設定的,要生效必須重啟!
ok,那就重啟吧,重啟完畢,結果發現依然沒變!這奇了怪了,后來經過好久的排查,最終確認問題是,該程序是通過 supervisord來管理的,也就是這進程都是 supervisord 的子進程,而 supervisord 的最大文件打開數還是老的配置,此時必須重啟 supervisord 才可以。
當大家遇到limits修改不生效的時候,請查一下進程是否只是子進程,如果是,那就要把父進程也一并重啟才可以
————————————————
版權聲明:本文為CSDN博主「我為AI領域做了奉獻」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/skiwnc/article/details/84100095

浙公網安備 33010602011771號