1、查询原因
Linux对打开文件的数量有限制,使用如下命令查看到的最大文件数量是1024,命令如下:
ulimit -a
2、解决方案
一、第一步,修改配置
(1)方案一(临时方案)
使用命令修改可以打开的最大文件数,但是机器重启后,就会失效
ulimit -n 65535
(2)方案二
修改配置文件
在 /etc/security/limits.conf 文件的最后增加如下内容,重启机器即可。
# End of file
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535
(3)方案三
vim /etc/profile
加入一行:ulimit -n 65535
执行:source /etc/profile
再次查看:ulimit -a
二、查看应用进程的资源限制是否调整过来
1、查看当前进程的资源限制情况
cat /proc/进程Id/limits
如果没有调整过来可能要重启应用
再进行检查。
查看当前进程所打开的文件资源
lsof -p 进程Id | wc -l
2、如果不能重启应用,在 linux 中编辑/proc/pid/limits 文件
如果要修改core_file限制,可以输入
prlimit --pid ${pid} --core=soft_limit:hard_limit
修改资源限制openfile
prlimit -p 30081 --nofile=10000:10500
prlimit 的帮助页面是:
Usage:
prlimit [options] [-p PID]
prlimit [options] COMMAND
General Options:
-p, --pid <pid> process id
-o, --output <list> define which output columns to use
--noheadings don't print headings
--raw use the raw output format
--verbose verbose output
-h, --help display this help and exit
-V, --version output version information and exit
Resources Options:
-c, --core maximum size of core files created
-d, --data maximum size of a process's data segment
-e, --nice maximum nice priority allowed to raise
-f, --fsize maximum size of files written by the process
-i, --sigpending maximum number of pending signals
-l, --memlock maximum size a process may lock into memory
-m, --rss maximum resident set size
-n, --nofile maximum number of open files
-q, --msgqueue maximum bytes in POSIX message queues
-r, --rtprio maximum real-time scheduling priority
-s, --stack maximum stack size
-t, --cpu maximum amount of CPU time in seconds
-u, --nproc maximum number of user processes
-v, --as size of virtual memory
-x, --locks maximum number of file locks
-y, --rttime CPU time in microseconds a process scheduled
under real-time scheduling
Available columns (for --output):
DESCRIPTION resource description
RESOURCE resource name
SOFT soft limit
HARD hard limit (ceiling)
UNITS units
For more details see prlimit(1).
3、理解ulimit
1、ulimit的管理的维度
理解ulimit,第一个疑问是限制的维度是什么。比如nofile设置为1024,是指当前用户总共只能打开1024个文件,还是单个shell会话进程只能打开1024个文件?** 实际上help ulimit里已经说清楚了:process,但我们可通过下面的方法程序验证:
下面通过一段java程序,打开800个文件:
@GetMapping("/ulimit")
public String testUlimit(int n) throws IOException {
List<FileInputStream> fileList = new ArrayList<FileInputStream>();
for(int i = 0; i< n; i++) {
File temp = File.createTempFile("ulimit-test", ".txt");
fileList.add(new FileInputStream(temp));
System.out.println("file_seq=" + i + " " + temp.getAbsolutePath());
}
return "ok";
}
查看当前的 ulimit -n 的数字 1024
查看进程的资源限制
测试1:配置为1025个文件
curl http://127.0.0.1:8150/ulimit?n=1025
可以看出,的确是创建了 1025 个临时文件。
测试2:配置为4097个文件
curl http://127.0.0.1:8150/ulimit?n=4097
可以看出,打开的文件数为4067 的时候,就抛出了异常。
测试3:配置ulimit -n 为 65535 ,重启进程
ulimit -n 65535
java -jar ldemo-0.0.1-SNAPSHOT.jar
查看进程的资源限制
cat /proc/43980/limits
创建10000个临时文件 curl http://127.0.0.1:8150/ulimit?n=10000
测试4:先调小值,启动进程,再调大,发现进程资源限制未改变。
总结: ulimit 资源限制主要以当前进程的资源限制为主,直接调整 ulimit 值不会影响进程的资源限制,要重启进程才能生效。想要临时生效可以,进行 prlimit 对进程进行调整。
4、soft和hard的区分
- 无论何时,soft总是小于等于hard
- 无论是超过了soft还是hard,操作都会被拒绝。结合第一点,这句话等价于:超过了soft限制,操作会被拒绝。
- 一个process可以修改当前process的soft或hard。但修改需满足规则:
- 修改后soft不能超过hard。也就是说soft增大时,不能超过hard;hard降低到比当前soft还小,那么soft也会随之降低。
- 非root或root进程都可以将soft可以在[0-hard]的范围内任意增加或降低。
- 非root进程可以降低hard,但不能增加hard。即nofile原来是1000,修改为了900,在修改为1000是不可能的。(这是一个单向的,有去无回的操作)
- root进程可以任意修改hard值。
soft和hard在控制上其实并没有区别,都会限制资源的使用,但soft可以被进程在使用前自己修改。
5、ulimit的修改与生效
知道ulimit很好,但更重要的是怎么修改,这是工作中常见的任务。
关于ulimit的生效,抓住几点即可:
- ulimit的值总是继承父进程的设置。
- ulimit命令可修改当前shell进程的设置。这也说明,为了保证下次生效,修改的地方要具有持久性(至少相当于目标进程而言),比如.bashrc,或进程的启动脚本)
- 从第2点也可以推出,运行中的进程,不受ulimit的修改影响。
- 增加hard值,只能通过root完成
6、其他
1、Java 自动将nofile的soft提升为hard上限
在研究的过程中,我发现java程序似乎不受nofile的soft值影响。查看进程的limits文件(/proc/$pid/limits),才发现nofile的soft被提升为和hard一样。经过全网搜索查询,发现JDK的实现中,会直接将nofile的soft先改成了和hard一样的值,可参考:How and when and where jvm change the max open files value of Linux?
2、file-max控制内核总共可以打开的文件数
除了ulimit控制外,/proc/sys/fs/file-max这个文件控制了系统内核可以打开的全部文件总数。所以,即便是ulimit里nofile设置为ulimited,也还是受限的。
3、ulimit常用选项
ulimit -a # 查看所有soft值
ulimit -Ha # 查看所有hard值
ulimit -Hn # 查看nofile的hard值
ulimit -Sn 1000 # 将nofile的soft值设置为1000
ulimit -n 1000 # 同时将nofiles的hard和soft值设置为1000