ulimit最詳解

本文屬於原創,轉載註明出處,歡迎關注微信小程序小白AI或者網站 https://xiaobaiai.net

前言

這篇文章應該是網絡上關於ulimit最全的介紹了,有擴展,有打破沙鍋追到底。文章儘可能的保證正確性,參考了多篇國外獲得多數贊同的文章。文章實際操作內容均在Ubuntu16.04上測試通過。

術語 釋義
File Descriptor 文件描述符(FD),在Unix和相關的計算機操作系統中,文件描述符(FD,較不常見的fildes)是用於訪問文件或其他輸入/輸出資源的抽象指示符(句柄),例如管道網絡套接字
Shell Session shell會話
User Level 用戶級別
System Level 系統級別

1 ulimit命令

  • ulimit可以限制使用系統資源的範圍。是一個內置BASH命令。
  • ulimit設置項僅在當前shell作用(類似export命令,永久生效可以寫入相關配置文件),即Shell Session級別作用
  • 寫入~/.profile或~/.bashrc只對當前用戶持久性生效
  • 寫入/etc/security/limits.conf可針對性配置,系統級持久性生效
  • 調整相關硬限制值(Hard Limit),設置一次後,以後的值只能小於上一次設置的值
  • 如果不加S或H修飾,則默認同時修改Soft LimitHard Limit
$ help limit
Syntax
      ulimit [-acdfHlmnpsStuv] [limit]

Key(設置項)
   -S   Set a soft limit for the given resource(設置軟資源限制,設置後可以增加,但是不能超過硬資源設置)
   -H   Set a hard limit for the given resource(設置硬資源限制,一旦設置不能增加)

   -a   All current limits are reported(顯示當前所有的 limit 信息). 
   -c   The maximum size of core files created(最大的 core 文件的大小, 以 blocks 爲單位). 
   -d   The maximum size of a process's data segment(進程最大的數據段的大小,以 Kbytes 爲單位). 
   -f   The maximum size of files created by the shell(default option,進程可以創建文件的最大值,以 blocks 爲單位)
   -l   The maximum size that can be locked into memory(最大可加鎖內存大小,以 Kbytes 爲單位). 
   -m   The maximum resident set size(最大內存大小,以 Kbytes 爲單位). 
   -n   The maximum number of open file descriptors(可以打開最大文件描述符的數量). 
   -p   The pipe buffer size(管道緩衝區的大小,以 Kbytes 爲單位). 
   -s   The maximum stack size(線程棧大小,以 Kbytes 爲單位). 
   -t   The maximum amount of cpu time in seconds(最大的 CPU 佔用時間,以秒爲單位). 
   -u   The maximum number of processes available to a single user(用戶最大可用的進程數). 
   -v   The maximum amount of virtual memory available to the process(進程最大可用的虛擬內存,以 Kbytes 爲單位).

注:所有設置blocks均指文件系統的最小分配單位block,典型值將介於1k和4k之間,對於超大型文件系統,最高可達16k及以上。

相關設置示例:

# 示例1:查看所有默認設置項值
$ 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) 7823
    max locked memory       (kbytes, -l) 64
    max memory size         (kbytes, -m) unlimited
    open files                      (-n) 1024
    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) 7823
    virtual memory          (kbytes, -v) unlimited
    file locks                      (-x) unlimited

# 示例2:軟限制設置core dump文件最大大小爲2048
$ ulimit -Sc 51200

# 示例3:core dump文件大小無限制
$ ulimit -c unlimited

# 限制管道緩衝區大小爲512Kbytes(KB)
$ ulimit -p 512

# 示例5:查看當前終端進程limits
$ echo $$ | cat /proc/`awk '{print $1}'`/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        0                    unlimited            bytes
    Max resident set          unlimited            unlimited            bytes
    Max processes             8041                 8041                 processes
    Max open files            1024                 4096                 files
    Max locked memory         65536                65536                bytes
    Max address space         unlimited            unlimited            bytes
    Max file locks            unlimited            unlimited            locks
    Max pending signals       8041                 8041                 signals
    Max msgqueue size         819200               819200               bytes
    Max nice priority         40                   40
    Max realtime priority     0                    0
    Max realtime timeout      unlimited            unlimited            us

2 hard limit 和 soft limit

  • 軟限制是內核對相應資源強制執行的值,硬限制作爲軟限制的上限,即軟限制值無法超過硬限制的值。
  • 如果沒有相應的設置權限,如root,只能將其軟限制設置爲0到硬限制範圍內的值,並且(不可逆地)降低其硬限制,即硬限制值修改了,後面再修改只能降低不能升高,當然軟限制值只要在硬限制值範圍內都是可以修改的。而擁有設置權限的用戶可以對任一限制的值進行任意更改。

3 更改默認limit值

3.1 持久性更改

3.1.1 用戶級更改

通過配置/etc/security/limits.conf文件,可以更改ulimit的默認資源限制值。包括對指定用戶使用資源的限制配置。

# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain>        <type>  <item>  <value>
#
#Where:
#<domain> can be:
#        - a user name
#        - a group name, with @group syntax
#        - the wildcard *, for default entry
#        - the wildcard %, can be also used with %group syntax,
#                 for maxlogin limit
#        - NOTE: group and wildcard limits are not applied to root.
#          To apply a limit to the root user, <domain> must be
#          the literal username root.
#
#<type> can have the two values:
#        - "soft" for enforcing the soft limits
#        - "hard" for enforcing hard limits
#
#<item> can be one of the following:
#        - core - limits the core file size (KB)
#        - data - max data size (KB)
#        - fsize - maximum filesize (KB)
#        - memlock - max locked-in-memory address space (KB)
#        - nofile - max number of open files
#        - rss - max resident set size (KB)
#        - stack - max stack size (KB)
#        - cpu - max CPU time (MIN)
#        - nproc - max number of processes
#        - as - address space limit (KB)
#        - maxlogins - max number of logins for this user
#        - maxsyslogins - max number of logins on the system
#        - priority - the priority to run user process with
#        - locks - max number of file locks the user can hold
#        - sigpending - max number of pending signals
#        - msgqueue - max memory used by POSIX message queues (bytes)
#        - nice - max nice priority allowed to raise to values: [-20, 19]
#        - rtprio - max realtime priority
#        - chroot - change root to directory (Debian-specific)
#
#<domain>      <type>  <item>         <value>
#

# examples:
#*               soft    core            0
#root            hard    core            100000
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#ftp             -       chroot          /ftp
#@student        -       maxlogins       4

# End of file 

通過設置domain來指定生效範圍,如可以指定用戶名或者組名等。配置項說明如下:

core - 限制內核文件的大小
date - 最大數據大小
fsize - 最大文件大小
memlock - 最大鎖定內存地址空間
nofile - 打開文件的最大數目(socket fd也屬於文件,因此可以設置該項)
rss - 最大持久設置大小
stack - 最大棧大小
cpu - 以分鐘爲單位的最多 CPU 時間
noproc - 進程的最大數目
as - 地址空間限制
maxlogins - 此用戶允許登錄的最大數目

注意修改完limits.conf文件後,需要重啓才能生效,通過ulimit -a檢驗是否生效。

3.1.2 單用戶級更改

用戶登錄的時候執行shell腳本的順序:

在這裏插入圖片描述

  • 我們所使用的基本上都是交互式登陸(interactive-login)
  • interactive-login登陸執行腳本順序
    • /etc/profile
    • ~/.bash_profile
    • ~/.bashrc
    • ~/.bash_login
    • /etc/bashrc
    • ~/.profile
  • non-interactive-login shell加載環境變量的順序是
    • ~/.bashrc
    • /etc/bashrc

因此我們可以將ulimit配置寫入到上述相關配置文件中。一般來說profile是與環境變量相關的配置,如PATH,而bashrc與shell相關的配置。

3.2 臨時性更改

直接在終端中執行ulimit,則就是臨時性更改,類似export命令

3.3 系統級更改

file-max是可以在整個系統(內核)中打開的最大文件數。這是在內核級別強制執行的。該值可以臨時調整,無需重啓生效,示例:

# 方式一
echo 100000 > /proc/sys/fs/file-max
# 方式二
$ vim /etc/sysctl.conf
fs.file-max = 100000
$ sysctl -p
# 方式三
$ sysctl -w fs.file-max = 100000

4 ulimit的應用

大多數類UNIX操作系統(包括Linux和macOS)提供了在每個進程和每個用戶的基礎上限制和控制系統資源(如線程,文件和網絡連接)使用的方法。這些“ulimits”阻止單個用戶使用太多系統資源。有時,這些限制具有較低的默認值,這可能會導致正常操作過程中出現許多問題,因此需要另外重新設置。

紅帽企業版Linux、CentOS 6及Ubuntu默認最大進程限制爲1024,core dump文件大小限制爲0blocks。

4.1 ulimit與core dump文件

首先需要設置好/etc/security/limits.conf

* soft core 2048
* hard core 2048

測試用例hello.c:

#include <stdio.h>

int main()
{
    char *str = "hello, core dump!";
    str[0] = 0;
    return 0;
}
$ gcc hello.c -o hello
$ ./hello
Segmentation fault (core dumped)
# 在當前可執行文件目錄下生成了core文件,如果沒有可以去/var/crash/目錄下查找

或者在硬限制的範圍內在終端通過ulimit臨時修改軟限制的值:

# 查看當前core是否開啓,0未開啓,大於0表示core文件最大blocks大小
$ ulimit -c
# 設置core文件最大blocks大小
$ ulimit -c {num}

注:1. 如果出現ulimit core file size cannot modify limit operation not permitted錯誤提示,就是你設置的值超過了硬限制值,需要檢查下。如果core文件沒有生成,再次檢查/etc/security/limits.conf是否設置對了。2. 如果配置好了,還是沒有生成core文件,可能原因就是配置的blocks大小比生成的core要小,所以無法生成。

gdb調試core文件:

# gdb -c core文件名  程序名稱
$ gdb -c {your_core_filename} {process_name}
# 然後輸入bt查看 dump 堆棧信息

其他配置:

  • /proc/sys/kernel/core_uses_pid可以控制core文件的文件名中是否添加pid作爲擴展,0不加,1則加。
  • 指定core文件生成路徑命名方式
    • $ cat /proc/sys/kernel/core_pattern 查看得到的結果是|/usr/share/apport/apport %p %s %c %P,開頭的|表示,core文件會交給apport程序去處理,而apport會將core dump文件保存在/var/crash目錄下
    • $ sudo vim /etc/sysctl.conf
      • kernel.core_pattern=/var/crash/%E.%p.%t.%s E代表路徑,p指進程pid,t指時間戳,s指哪個信號讓程序崩潰了,配置生成路徑爲/var/crash
      • $ sudo sysctl -p 讓修改了sysctl.conf立即生效

4.2 ulimit與網絡連接數

首先我們要知道幾個含義:

  • file-max是可以在整個系統(內核)中打開的最大文件數。這是在內核級別強制執行的。
    • cat /proc/sys/fs/file-max 可以查看
    • sysctl fs.file-nr 最後一項就是file-max
  • lsof: 在沒有任何選項的情況下,lsof列出屬於所有活動進程的所有打開文件。
    • lsof | wc -l計算所有活動進程打開的文件數目,這個值是小於等於file-max
  • ulimit是用於在用戶級別強制執行的資源限制,比如某個用戶某個進程(shell)所能打開的文件句柄個數
    • lsof -u {username} | wc -l 獲取指定用戶當前打開的文件個數
    • lsof -u root | wc -l 獲取root用戶當前打開的文件個數
    • lsof -p {pid} | wc -l 獲取指定pid所打開的文件個數
    • ls -1 /proc/{pid}/fd | wc -l 獲取被該pid打開的文件個數,但是相比lsof包含更多其他句柄,如epollinotify句柄。(參考

修改網絡連接數即修改open files參數數值:

#/etc/security/limits.conf
*   hard    nofile      20000

或者在硬限制的範圍內在終端通過ulimit臨時修改軟限制的值。

# 查看當前shell當前用戶打開文件個數限制
$ ulimit -n
# 設置
$ ulimit -n {num}

測試:

  • 在一個shell終端中設置ulimit -n 512,在該shell終端打開服務端,等該客戶端連接
  • 在另一個shell終端中設置ulimit -n 1024,開始不斷創建socket連接
    • 當達到512個連接時(包含服務端shell終端所有打開的描述符個數),提示Network Error之類信息

其他擴展:

  • 查看端口限制範圍
    • $ sysctl -a | grep port_range$ cat /proc/sys/net/ipv4/ip_local_port_range
  • 增加可用端口範圍
    • $ sudo vim /etc/sysctl.conf
      • net.ipv4.ip_local_port_range = {min_num} {max_num} min_num爲端口起始範圍,max_num爲端口終止範圍
      • sudo sysctl -p 立即生效

5 參考

  • https://ss64.com/bash/ulimit.html
  • https://linux.die.net/man/5/limits.conf
  • https://linux.xiao5tech.com/linux/advance/linux_optimize_ulimit_error.html
  • http://www.361way.com/linux-core-dump/3830.html
  • https://docs.mongodb.com/manual/reference/ulimit/
  • http://senlinzhan.github.io/2017/12/31/coredump/
  • https://www.kernel.org/doc/Documentation/sysctl/fs.txt
  • http://linux-sxs.org/bedtime/bs_login.html
  • https://en.wikipedia.org/wiki/File_descriptor
  • https://superuser.com/questions/789448/choosing-between-bashrc-profile-bash-profile-etc
  • https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell
  • https://www.cyberciti.biz/tips/linux-procfs-file-descriptors.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章