前言
本人入职工作不久,发现公司自动化运维工具中某设置环境变量的shell脚本开头有如下几行代码:
# 放开文件和core文件大小限制
ulimit -c unlimited
ulimit unlimited
有些不解这两句代码的含义。
ulimit 命令简介
ulimit 属 Shell 内建命令,用于查看或设置 Shell 以及通过 Shell 启动的进程使用系统资源的上限。限制分为软限制(当前限制)和硬限制,其中硬限制是软限制的上限值。
由于系统资源有限,比如开启文件描述符的数量,进程堆栈的大小,CPU 时间,虚拟内存大小,等等,操作系统对每一个进程都有严格的限制。资源的合理限制和分配,不仅仅是保证系统可用性的必要条件,也与进程性能密不可分。这时,ulimit 可以起到很大的作用,它是一种简单并且有效的实现资源限制的方式。
ulimit 命令使用
ulimit [-HSTabcdefilmnpqrstuvx [limit]]
或
ulimit[-aHS][-c<core文件上限>][-d<数据节区大小>][-f<文件大小>][-m<内存大小>][-n<文件数目>][-p<缓冲区大小>][-s<堆叠大小>][-t<CPU时间>][-u<程序数目>][-v<虚拟内存大小>]
其中,limit 是对指定类型资源的具体限制,参数 S 表示设置软限制,H 表示设置硬限制,当都不指定时,表示同时设置软限制和硬限制。
选项说明
-H
设定资源的硬限制,只有 root 用户可以操作
-S
设置资源的软限制
-a
显示目前所有资源设定的限制
-b
socket 缓冲的最大值,单位
-c
core 文件的最大值,单位 blocks
-d
进程数据段的最大值,单位 KB
-e
调度优先级上限,这里的优先级指 NICE 值。只针对普通用户进程有效
-f
当前 Shell 可创建文件总大小的上限,单位 blocks
-i
被挂起/阻塞的最大信号数量
-l
可以锁住的物理内存的最大值,单位 KB
-m
可以使用的常驻内存的最大值,单位 KB
-n
每个进程可以同时打开的最大文件数
-p
管道的最大值,单位 block,1 block = 512 bytes
-q
POSIX 消息队列的最大值
-r
限制程序实时优先级,只针对普通用户进程有效
-s
进程栈最大值,单位 KB
-t
最大 CPU 时间,单位 s
-u
用户最多可启动的进程数目
-v
当前 Shell 可使用的最大虚拟内存,单位 KB
-x
文件锁的最大数量
-T
线程的最大数量
命令帮助说明
[root@host10 ~]# ulimit --help
ulimit: ulimit [-SHabcdefiklmnpqrstuvxPT] [限制]
修改 shell 资源限制。
在允许此类控制的系统上,提供对于 shell 及其创建的进程所可用的
资源的控制。
选项:
-S 使用软 (`soft') 资源限制
-H 使用硬 (`hard') 资源限制
-a 所有当前限制都被报告
-b 套接字缓存尺寸
-c 创建的核文件的最大尺寸
-d 一个进程的数据区的最大尺寸
-e 最高的调度优先级 (`nice')
-f 有 shell 及其子进程可以写的最大文件尺寸
-i 最多的可以挂起的信号数
-k 分配给此进程的最大 kqueue 数量
-l 一个进程可以锁定的最大内存尺寸
-m 最大的内存进驻尺寸
-n 最多的打开的文件描述符个数
-p 管道缓冲区尺寸
-q POSIX 信息队列的最大字节数
-r 实时调度的最大优先级
-s 最大栈尺寸
-t 最大的CPU时间,以秒为单位
-u 最大用户进程数
-v 虚拟内存尺寸
-x 最大的文件锁数量
-P 最大伪终端数量
-T 最大线程数量
并非所有选项在所有系统上可用。
如果提供了 LIMIT 变量,则它为指定资源的新的值;特别的 LIMIT 值为
`soft'、`hard'和`unlimited',分别表示当前的软限制,硬限制和无限制。
否则打印指定资源的当前限制值,不带选项则假定为 -f
取值都是 1024 字节为单位,除了 -t 以秒为单位,-p 以 512 字节递增,
-u 为无范围的进程数量。
退出状态:
返回成功,除非使用了无效的选项或者错误发生。
[root@host10 ~]#
使用 ulimit 设置应用进程资源使用限制案例
- 查看现有系统资源限制(ulimit -a=ulimit -aS)
[root@host10 ~]# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 4183391
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) 4183391
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@host10 ~]#
2. 控制进程发生段错误(Segmentation Fault)时生成 coredump 文件大小为unlimited(文章标题)
ulimit -c unlimited
3. 设置shell 及其子进程可以写的最大文件大小的上限(文章标题)
实现这个可以有两种方式:
ulimit -f unlimited
或
ulimit unlimited
第二种方式为直接省略-f,参见帮助,如果不带选项,则默认选项为-f。
[root@host10 ~]# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) 2000000
pending signals (-i) 4183391
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) 4183391
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@host10 ~]# ulimit unlimited
[root@host10 ~]# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 4183391
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) 4183391
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@host10 ~]#
3. 设置进程的栈大小没有限制。
ulimit -s unlimited
注意:
(1)在root用户使用ulimit 设置的资源限制值,将针对root用户和普通用户均生效
[root@hadoop102 ~]# ulimit -s
8192
[root@hadoop102 ~]# su - atguigu
上一次登录:三 2月 28 18:43:08 CST 2024pts/3 上
[atguigu@hadoop102 ~]$ ulimit -s
8192
[atguigu@hadoop102 ~]$ exit
登出
[root@hadoop102 ~]#
[root@hadoop102 ~]# ulimit -s 9216
[root@hadoop102 ~]#
[root@hadoop102 ~]# ulimit -s
9216
[root@hadoop102 ~]# su - atguigu
上一次登录:三 2月 21 08:37:14 CST 2024pts/0 上
[atguigu@hadoop102 ~]$ ulimit -s
9216
[atguigu@hadoop102 ~]$
(2)在普通用户使用ulimit设置的资源限制值,仅仅可以设置不超过硬限制的值(否则会报错),且修改仅针对普通用户生效
[atguigu@hadoop102 ~]$ ulimit -s
9216
[atguigu@hadoop102 ~]$
[atguigu@hadoop102 ~]$
[atguigu@hadoop102 ~]$ ulimit -s 10000
-bash: ulimit: stack size: 无法修改 limit 值: 不允许的操作
[atguigu@hadoop102 ~]$
[atguigu@hadoop102 ~]$ ulimit -s 1000
[atguigu@hadoop102 ~]$
[atguigu@hadoop102 ~]$ ulimit -s
1000
[atguigu@hadoop102 ~]$
[atguigu@hadoop102 ~]$ exit
登出
您在 /var/spool/mail/root 中有新邮件
[root@hadoop102 ~]# ulimit -s
9216
[root@hadoop102 ~]# ulimit -aH
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 31761
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 4096
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 9216
cpu time (seconds, -t) unlimited
max user processes (-u) 31761
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@hadoop102 ~]# ulimit -aS
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 31761
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) 9216
cpu time (seconds, -t) unlimited
max user processes (-u) 31761
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
永久生效
上面在一个session中输入命令的方式,是临时生效的方式,当session关闭之后,设置的值将会被恢复设置之前的值。
下面介绍几种永久生效的方式,这里永久生效指每次登陆shell
时,都会按配置重新设定ulimit
,以达到永久生效的效果。
- 修改/etc/security/limits.conf
原文件的内容如下:
# /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
#
#<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 file descriptors
# - 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
#
#<domain> <type> <item> <value>
#
#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student - maxlogins 4
# End of file
案例:将-u和-n的软限制和硬限制同时修改为65535,在其末尾加上要限制的项目
#<domain> <type> <item> <value>
#
#* soft core 0
#* hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student - maxlogins 4
* hard nproc 65535
* soft nproc 65535
* hard nofile 65535
* soft nofile 65535
修改之后重启服务器生效(或重新登录生效),可以命令通过查看:
ulimit -a # 查看所有项目软限制
ulimit -aS # 查看所有项目软限制
ulimit -aH # 查看所有项目硬限制
2. 也可修改/etc/profile文件
打开该文件,在其最后加上以下两条:
ulimit -u 65535
ulimit -n 65535
这样每次登陆shell
后,会初始执行这两条ulimit
命令,并使其生效。
为了使刚配的/etc/profile文件最后两行生效,还需执行source
命令:
[root@mysrs ~]# source /etc/profile
[root@mysrs ~]#
注1:这里重新登录也可使其生效。
注2:source
使当前shell
对指定文件内容生效,日常维护中使用频率高。
ulimit 中 限制值 Hard 和 Soft 的详解
-H 设定资源的硬限制,只有 root 用户可以操作
soft值用户可以自行通过ulimit用户设置,但是不能超过hard值,只有root用户可以调整hard值。
在 Linux 系统中,在每个进程中都有一组资源限制,进程默认打开的最大文件数个数为 1024 个,可以通过如下配置查看:
# ulimit -n
1024
在应用程序开发过程中,比如向 server 发起连接的客户端超过 1024 个时,server 由于 1024 个最大的文件个数限制而出现打开文件失败,进而出现Too many open files 错误。
在linux中这些限制是分为软限制 (soft limit) 和 硬限制 ( hard limit )。他们的区别就是软限制可以在程序的进程中自行改变(突破限制),而硬限制则不行(除非有 root 权限)。
软限制是内核实际执行的限制,任何进程都可以将软限制设置为任意小于等于对进程限制的硬限制的值。
硬限制充当软限制的上限:非特权进程只能将其软限制设置为从 0 到硬限制的范围内的值,只有超级用户进程可以提高硬限制的值。
任何一个进程都可以降低其硬限制的值,但它必须大于或等于其软限制的值。
查看软限制的命令
# ulimit -Sn
1024
查看硬限制的命令
# ulimit -Hn
4096
ulimit对资源的限制区分为soft和hard两类,即同一个资源(如nofile)存在soft和hard两个值。在命令上,ulimit通过-S和-H来区分soft和hard。如果没有指定-S或-H,在显示值时指的是soft,而在设置的时候指的是同时设置soft和hard值。但soft和hard的区别是什么是什么呢?下面这段解释较为准确(来自man 2 getrlimit )
- The soft limit is the value that the kernel enforces for the corresponding resource. The hard limit acts as a ceiling for the soft limit: an unprivileged process may set only its soft limit to a value in the range from 0 up to the hard limit, and (irre‐versibly) lower its hard limit. A privileged process (under Linux: one with the CAP_SYS_RESOURCE capability) may make arbitrary changes to either limit value.
总结起来就三点:
- 无论何时,soft总是小于等于hard
- 无论是超过了soft还是hard,操作都会被拒绝。(即用户应用进程的相关操作会失败)
- soft和hard在控制上其实并没有区别,都会限制资源的使用,但soft限制可以被进程在使用前自己修改。非root用户可以把soft提高,但是不能超过hard限制,且不能提高hard限制。