Spring boot内置Tomcat的临时目录被删除导致文件上传不了-问题解析
2020-02-27 22:38
239 查看
[TOC]
1、问题
在过年后,部分运营人员反应说运营后台上传不了图片,然后查看日志,发现报错内容是
/tmp/tomcat* 目录不存在。
环境:
- spring boot 1.5.15
- Centos7.6(aliyun)
2、 问题解析
- 为什么需要使用这个
/tmp/tomcat*
? - 那个
/tmp/tomcat*
目录为什么不存在?
2.1、 为什么需要使用这个/tmp/tomcat*
?
默认情况下,spring boot 的内置 Tomcat ,会在
/tmp创建两个目录
/tmp/tomcat*,这个目录用于存储编译的JSP 和 上传的文件。
2.2、那个 /tmp/tomcat*
目录为什么不存在?
不存在是因为被Linux 的机制进行清除了。
这个机制是什么原理: 首先我们得从服务
systemd-tmpfiles-clean说起。
[root@djx ~]# systemctl status systemd-tmpfiles-clean ● systemd-tmpfiles-clean.service - Cleanup of Temporary Directories Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.service; static; vendor preset: disabled) Active: inactive (dead) since Tue 2020-02-25 09:10:36 CST; 12h ago Docs: man:tmpfiles.d(5) man:systemd-tmpfiles(8) Process: 21819 ExecStart=/usr/bin/systemd-tmpfiles --clean (code=exited, status=0/SUCCESS) Main PID: 21819 (code=exited, status=0/SUCCESS) Feb 25 09:10:36 djx systemd[1]: Starting Cleanup of Temporary Directories... Feb 25 09:10:36 djx systemd[1]: Started Cleanup of Temporary Directories.
我们可以看到这个服务今天上午 9点执行了一次,我们继续看看这个服务对应的执行命令是什么?
cat /usr/lib/systemd/system/systemd-tmpfiles-clean.service # 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. [Unit] Description=Cleanup of Temporary Directories Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8) DefaultDependencies=no Conflicts=shutdown.target After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target time-sync.target Before=shutdown.target [Service] Type=oneshot ExecStart=/usr/bin/systemd-tmpfiles --clean IOSchedulingClass=idle
我们先记住这个执行命令是
/usr/bin/systemd-tmpfiles --clean,我们再来关心下,与这个服务相关的定时器
/usr/lib/systemd/system/systemd-tmpfiles-clean.timer
cat /usr/lib/systemd/system/systemd-tmpfiles-clean.timer # 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. [Unit] Description=Daily Cleanup of Temporary Directories Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8) [Timer] OnBootSec=15min OnUnitActiveSec=1d
我们从这知道在
启动后的15分钟或者距离上一次执行一天会执行我们上面的命令
/usr/bin/systemd-tmpfiles --clean。
那么上面这个命令具体又执行了什么? 我们在
man systemd-tmpfiles中找到了一些东西。
DESCRIPTION systemd-tmpfiles creates, deletes, and cleans up volatile and temporary files and directories, based on the configuration file format and location specified in tmpfiles.d(5). If invoked with no arguments, it applies all directives from all configuration files. If one or more filenames are passed on the command line, only the directives in these files are applied. If only the basename of a configuration file is specified, all configuration directories as specified in tmpfiles.d(5) are searched for a matching file.
从上面这个描述我得到了两个信息:
- 就是 systemd-tmpfiles 用来创建和清理临时性的目录和文件。
- systemd-tmpfiles 会从 tmpfiles.d 中获取配置文件。
当然我们在
man systemd-tmpfiles中还可以了解到一些参数命令。
我们接着去看
tmpfiles.d, 我们在
man tmpfiles.d中可以看到
tmpfiles.d的作用就是用于清理临时文件和目录的配置。 我们还可以看到它的配置存储于
/etc/tmpfiles.d/*.conf /run/tmpfiles.d/*.conf /usr/lib/tmpfiles.d/*.conf
在这里我们还可以看到配置文件里面的相关注解。
接下来我们去上面列出的三个目录里面找找看有没有相关清理
/tmp的东西。 最后在
/usr/lib/tmpfiles.d/tmp.conf里面找到了,
cat /usr/lib/tmpfiles.d/tmp.conf # 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 v /tmp 1777 root root 10d v /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
我们可以看其中的两个配置
v /tmp 1777 root root 10d # 就是当 /tmp 目录不存在的时间进行创建(权限为777,用户和用户组为root),并清理/tmp下超过10天的文件。 x /tmp/systemd-private-%b-* # 忽略清理的目录 X /tmp/systemd-private-%b-*/tmp # 这个只忽略目录,但不忽略该目录下面的内容
意思就是 清理
/tmp目录下超过10天没有变化的文件,但不清理
/tmp/systemd-private-%b-*和
/tmp/systemd-private-%b-*/tmp. 总结 系统会自动进行清理 /tmp 目录下10天没有变化的文件和目录
过年期间我们的 Tomcat 生成的目录如果10天没有发生变化,也就会被删除。
三、解决办法
修改 springboot 配置,不要在/tmp
下创建目录
配置参数 :
server.tomcat.basedir
修改 清理 /tmp 下面的文件的机制
在
/usr/lib/tmpfiles.d/tmp.conf下面增加一个
x /tmp/tomcat*
四、spring boot 官方解答
官方相关的 issue :
- https://github.com/spring-projects/spring-boot/issues/5009
- https://github.com/spring-projects/spring-boot/issues/9616
在 https://github.com/spring-projects/spring-boot/issues/9616, 在最底部我们可以
You can see the list of releases that contain the fix in the commit that closed this issue. In the 2.1.x line it was fixed in 2.1.4.
看到 2.1.4 版本已经解决了该问题。在 1系列的版本中,我们可以看到在 1.5.20 中也修复了,github对应的提交记录
参考:https://www.cnblogs.com/samtech/p/9490166.html
相关文章推荐
- 用eclipse创建tomcat项目后,文件上传目录路径问题
- tomcat文件上传与存储(虚目录、临时存储)
- centos7下jetty临时目录被tmpwatch删除导致资源文件(css/js)无法加载的问题
- tomcat 服务器上传文件,新建目录权限问题
- 解决linux系统下因分区目录划分过小,导致tomcat使用系统临时文件夹(/tmp)没有足够空间而报错的问题
- nginx+tomcat使用apache的FtpClient上传图片时由于多线程问题导致的文件大小为0的问题
- tomcat参数问题,导致上传文件进行被中断
- nginx+tomcat使用apache的FtpClient上传图片时由于多线程问题导致的文件大小为0的问题
- 文件(附件)上传的几种方法(含自建目录,防止文件名重复等问题)
- 关于struts2上传时报临时文件找不到的问题
- 表单同时有中文字段和文件上传,加上enctype="multipart/form-data"后导致的中文乱码问题
- css编码问题导致ie6不能正确解析文件内容
- apache与tomcat负载集群的方法与集群的文件同步问题和图片上传显示问题解决
- springMVC_03文件上传 及 临时目录相关
- Tomcat主要目录文件解析
- 解决ewebeditor的上传组件与IIS大小限制导致无法上传大于200K文件的问题
- Tomcat 配置完毕之后无法下载虚拟目录里的资源文件问题
- 解决Struts2上传文件到tomcat,重启tomcat后 ,文件自动被删除。
- Tomcat目录及配置文件解析
- spring的单例导致webwork文件上传出现问题【原创】