资源限制
rlimit 可控制的系统资源包括: 内存 、 文件 、 锁 、 CPU调度 、 进程数 等。优秀系统管理员设置合适的 rlimit 值,避免某个用户或某个进程占用过多系统资源而拖垮系统。
本文介绍设置 rlimit 的来龙去脉,具体 rlimit 值属于 系统调优 范畴,暂不全面涉及。
ulimit 是一个 Shell 内置命令,由于查看、调整当前 Shell 进程的 rlimit 值。以 为例,查看所有 rlimit 值:
注解
资源项详细介绍请参考文章末尾处附录的表格。
也可以查看某项资源的限制,以进程打开 文件描述符 数( RLIMIT_NOFILE )为例:
1024
由此可见,当前 Shell 进程最多只能打开 1024 个 ,由该 Shell 启动的程序也是如此。接着实现一个简单的程序,不断创建 套接字 ( socket ),以验证这一点:
$ python detect-max-fd.py
error no: 24
fd range: [3, 1023]
显然,程序无法无限地创建 套接字 。当 文件描述符 达到 rlimit 限制时,相关 将失败,错误码为 EMFILE ,即 Too many open files 。成功打开的套接字文件描述符范围从 3 到 1023 ,与 1024 的上限相吻合。
注解
进程前三个文件描述符 0 、 1 、 2 分别是 stdin 、 stdout 以及 stderr 。
当然了,可以通过 ulimit 调整 文件描述符 上限:
$ ulimit -Sn 512
注解
这时,进程能打开的 变少了:
注解
detect-max-fd.py源码以及原理剖析请查看文章附录,位于末尾处。
软硬之分
资源限制有软硬之分, 软限制 ( soft )和 硬限制 ( hard )。
软限制 是一般意义的资源限制, 直接作用于用户或者进程 。ulimit 默认返回软限制:
1024
也可通过 -S 选项显式指定返回 软限制 :
$ ulimit -Sn
1024
由上一小节,我们知道用户可以将软限制调低或调高。如果普通用户可以无限制调高, rlimit 将失去限制用户的意义。为此,内核引入了 硬限制 ,规定了软限制调整的上限。
ulimit 查看 硬限制 需要指定 -H 选项:
$ ulimit -Hn
1048576
调整 软限制 时,不能超出 硬限制 ,否则报错:
同样,可以将 硬限制 调低:
$ ulimit -n 1024
注解
设置 rlimit 限制时,未指定软硬,则同时设置。
-bash: ulimit: open files: cannot modify limit: Operation not permitted
因此,软硬限制之别可总结为以下几点:
- 软限制 直接起作用;
- 硬限制 只能调低;
通过配置文件设置 rlimit 值,可永久生效,也可突破 ulimit 不能调高 硬限制 的局限。配置文件 位于 /etc/security/limits.conf ,格式如下:
root soft nofile 1000000
root hard nofile 1000000
* soft nofile 1000000
* hard nofile 1000000
每个配置行由 4 个字段组成,分别是:
- 域 ( domain )
- 类型 ( type )
- 资源项 ( item )
- 值 ( value )
其中, 域 可以是用户或者用户组(以 @ 开头,例如 @admin ), * 则表示任意用户;类型 分为两种,分别对应 软限制 ( soft )和 硬限制 ( hard );资源项 列表见附录。
配置编辑完毕后,重新登录即可生效,无需重启。
注解
limits.conf 是 的配置文件,而 pam_limits.so 是 Linux插入式认证模块 ( Pluggable Authentication Modules 简称 PAM )的子模块。
根据 PAM 机制,应用程序启动时,按 /etc/pam.d 配置加载 pam_xxxx.so 模块。/etc/pam.d 下包含了 login 、 sshd 、 su 、 sudo 等程序的 PAM 配置文件,因此用户重新登录时,将调用 加载 limits.conf 配置文件。
附录
detect-max-fd.py源码
这是一个 程序,循环创建套接字,促使进程打开文件描述符达到上限:
第 8 行,用一个列表来存放已创建的套接字( Python 套接字对象);第 12-13 行,循环创建套接字并追加到列表中,直到 OSError 异常(系统调用出错);第 15-16 行,打印错误码;第 18-21 行,打印首尾套接字的文件描述符。
订阅更新,获取更多学习资料,请关注我们的 微信公众号 :