【问题分析】打开的文件过多
【问题分析】open too many files,打开的文件过多
·
背景
系统上线运行一段时间之后突然崩溃,重启后正常运行,过一段时间后再次崩溃。查看系统日志发现,原因是open too many files,打开的文件过多。
先紧急处理一下,输入命令ulimt -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) 29896
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) 29896
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
可以看到open files
的值是1024,表示单个进程最多只能打开1024个文件(也可使用ulimit -n
直接查看)。那就先把这个值调大,为分析原因争取时间。
vim /etc/security/limits.conf
# 在文件尾部写入配置
* - nofile 65535
问题分析
系统除了打开依赖的jar包以及日志等文件以外,就是业务需要打开一些EXCEL和PDF模板,初步猜测可能是业务打开了这些模板之后没有关闭,时间长了就到了open files阈值。
测试
在测试环境上部署,测试那些需要使用EXCEL和PDF模板的业务,并在LINUX中监控打开的文件。
# 查看进程号
jps -l
# 打印PID进程打开的文件,按照第9列(文件名)排序展示
lsof -p PID | sort -k9
每次操作完之后都执行上述命令查看打开的文件,然后发现PDF文件每次打开了都不会关闭,越积累越多。
解决
最后定位到调用模板填充PDF这个公共方法,其中PdfReader
对象使用完未关闭可能是根本原因。
修改代码后再次测试,问题解决。
/**
* 根据模板填充PDF
*/
public static void templetTicket(Object model,String templatePdfPath,String targetPdfpath) throws Exception {
// PdfReader 需要关闭
PdfReader reader = new PdfReader(templatePdfPath);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper ps = new PdfStamper(reader, bos);
FileOutputStream fos = new FileOutputStream(targetPdfpath);
try {
// 省略代码...
} catch (Exception e) {
throw e;
}finally {
ps.close();
fos.close();
bos.close();
// 关闭 PdfReader
reader.close();
}
}
更多推荐
已为社区贡献3条内容
所有评论(0)