背景
最近在java代码中,升级了一些二方库和三方库的版本。在现网运行了一段时间之后,服务突然出现异常。
查看错误日志,是因为 File not found or permission denied 引起的,是一个升级过的二方库报的错。尝试重启服务,重启之后没有出现错误,业务恢复正常
问题定位
仔细查看这个升级后的二方库的代码,发现提示 File not found or permission denied 的文件,应该是在 /tmp 目录下的。服务重启之后,/tmp 目录是有这个文件的。尝试把这个文件删除,再去构造请求触发代码逻辑,查看日志文件,是会报相同的错误。
从笔者的认知角度里,/tmp 目录下应该是所有用户都可以读写的,如果一个用户创建了文件,理论上不太可能出现 permission denied 问题。尝试Google “tmp下文件被自动清理”,果然找到了相关原因(Google大法好):centos操作系统有一个自动清理临时文件的 systemd-tmpfiles 服务,会自动清理/tmp 下超过10天的内容
好吧,应该是找到根因了,接下来稍微学习并验证一下,是不是这个 systemd-tmpfiles 导致的
systemd-tmpfiles 服务
先贴几个链接:
- Managing temporary files with systemd-tmpfiles on Red Hat Enterprise Linux 7
- systemd-tmpfiles 中文手册
- tmpfiles.d 中文手册
为了方便管理(创建、删除)操作系统中的临时目录和文件,redhat和fedora提供了 systemd-tmpfiles 服务
systemd-tmpfiles 主要有以下3个服务:
- systemd-tmpfiles-setup.service
- systemd-tmpfiles-setup-dev.service
- systemd-tmpfiles-clean.service。它并不是一直运行着的,而是通过 systemd-tmpfiles-clean.timer 来定时启动
相关的配置文件也有3个地方:
/etc/tmpfiles.d/*.conf
/run/tmpfiles.d/*.conf
/usr/lib/tmpfiles.d/*.conf
/tmp目录的清理规则主要取决于/usr/lib/tmpfiles.d/tmp.conf
文件的设定,查看笔者 centos8 的配置文件:
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# See tmpfiles.d(5) for details
# Clear tmp directories separately, to make them easier to override
q /tmp 1777 root root 10d
q /var/tmp 1777 root root 30d
# Exclude namespace mountpoints created with PrivateTmp=yes
x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
x /var/tmp/systemd-private-%b-*
X /var/tmp/systemd-private-%b-*/tmp
# Remove top-level private temporary directories on each boot
R! /tmp/systemd-private-*
R! /var/tmp/systemd-private-*
可以看到 /tmp 目录下的文件是保留10天的,10天后文件会被删除(下面exclude的文件除外)
systemd-tmpfiles 功能测试
修改/usr/lib/tmpfiles.d/tmp.conf
,把 10d 修改为 60s
在 /tmp 目录下创建 test.txt 文件,60s 之后,执行 systemctl start systemd-tmpfiles-clean.service
,查看文件是否还在。测试结果如下图所示