SpringBoot内嵌Tomcat临时目录问题及解决

 更新时间:2025年04月21日 15:33:10   作者:火冠蜂鸟  
这篇文章主要介绍了SpringBoot内嵌Tomcat临时目录问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

SpringBoot内嵌Tomcat临时目录问题

听说后面上线可能tomcat临时文件夹会被Linux删除,会报找不到错误,现在赶紧记录一下,已被不时之需。

存在文件上传的SpringBoot项目,在Linux系统部署之后,会在系统的tmp目录下生成一个带tomcat 及 随机字符串的临时目录。

该目录有可能被linux系统在一定时间后自动清除掉,导致再次上传文件的时候,系统就会报错。

意思是tomcat的临时目录会被tmpwatch删除掉,甚至可能删除掉class文件,导致错误的发生

1.背景

线上保障,上线运行了几天的SpringBoot应用,突然遇到问题:

/tmp/tomcatXXX/work/Tomcat/localhost/XXX is not valid。

应用不会存在/tmp/tomcatXXX/work/Tomcat/localhost/ROOT目录。经查询,是tomcat在文件上传时,会先对文件进行复制到临时目录,就是该目录。

之前的应用运行是正常的,现在出现这个情况,显然是创建好的目录被删除了。对,就是这个特殊的/tmp目录Linux存在清除策略。

清除策略的配置文件路径如下:

/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

发现会清除10天内没被访问过的文件。但是到了这里,有个疑问就是,昨天可以的也就是该目录是被访问过,今天怎么会被清除咧?

这个本人确实当时很疑惑,然后对应用的假设为:

/tmp/tomcat.4344543554352.8080/work/Tomcat/localhost/test,发现该目录下为空。也就是临时文件会被tomcat清理掉,但是test目录的创建时间确实是在10天前。

到了这里就明白了,虽然test目录下文件每天都会有更新,但是**不会影响test目录的访问时间**,并且该文件被删掉了。/tmp目录的清理机制发现test空目录是10天前,就直接清理了(**test为空目录**)。应用再去访问就报错了。

2.方案

原因搞清楚了,解决方案自然很明了,大致有3种:

  • 1.从Linux层面修改 /tmp目录的清理策略,比较简单,略过
  • 2.指定新的系统临时文件路径
-Djava.io.tmpdir=/var/tmp
  • 3. 配置中修改tomcat的临时目录
server:
    tomcat:
       basedir: /var/tmp/

3.代码中配置tomcat临时目录

@Configuration
public class MultipartConfig {
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
String location = System.getProperty("user.dir") + "/data/tmp";
File tmpFile = new File(location);
if (!tmpFile.exists()) {
tmpFile.mkdirs();
}
factory.setLocation(location);
return factory.createMultipartConfig();
}
}

4.tomcat在临时目录不存在先创建

这个方案稍微麻烦些,就多啰嗦下。

其实该方式在spring-boot2.1.4版本进行了修订:在临时目录不存在就创建临时目录。

在该类spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java中添加了几行代码:

        catch (NoSuchMethodError ex) {
            // Tomcat is < 8.0.30. Continue
        }
        //新增代码开始
        try {
            context.setCreateUploadTargets(true);
        }
        catch (NoSuchMethodError ex) {
            // Tomcat is < 8.5.39. Continue.
        }
         //新增代码结束
         SkipPatternJarScanner.apply(context, this.tldSkipPatterns);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java实现遍历树形菜单两种实现代码分享

    java实现遍历树形菜单两种实现代码分享

    这篇文章主要介绍了java实现遍历树形菜单两种实现代码分享,两种实现:OpenSessionView实现、TreeAction实现。具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Java中ArrayList、Vector、LinkedList的核心区别与应用场景详解

    Java中ArrayList、Vector、LinkedList的核心区别与应用场景详解

    在Java编程语言中ArrayList、Vector和LinkedList是三个常见的列表实现,它们都实现了List接口,这篇文章主要介绍了Java中ArrayList、Vector、LinkedList的核心区别与应用场景的相关资料,需要的朋友可以参考下
    2025-07-07
  • Java 内存溢出的原因和解决方法

    Java 内存溢出的原因和解决方法

    这篇文章主要介绍了Java 内存溢出的原因和解决方法,帮助大家更好的维护Java程序,保持稳定性,感兴趣的朋友可以了解下
    2020-12-12
  • Java错误:进行语法分析时已到达文件结尾的解决

    Java错误:进行语法分析时已到达文件结尾的解决

    这篇文章主要介绍了Java错误:进行语法分析时已到达文件结尾的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • hadoop client与datanode的通信协议分析

    hadoop client与datanode的通信协议分析

    本文主要分析了hadoop客户端read和write block的流程. 以及client和datanode通信的协议, 数据流格式等
    2012-11-11
  • springboot配置允许跨域访问代码实例

    springboot配置允许跨域访问代码实例

    这篇文章主要介绍了springboot配置允许跨域访问代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java微信公众平台之获取地理位置

    Java微信公众平台之获取地理位置

    这篇文章主要为大家详细介绍了Java微信公众平台之获取地理位置的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Spring Bean初始化的三种常用方式(易懂版)

    Spring Bean初始化的三种常用方式(易懂版)

    在Spring框架开发中,Bean的生命周期管理是核心基础知识点,而Bean初始化作为生命周期中的关键环节,负责在Bean实例创建并完成依赖注入后,执行资源加载、参数配置、缓存初始化等核心业务逻辑,本文将详细拆解Spring中3种主流的Bean初始化方式,需要的朋友可以参考下
    2025-12-12
  • Springboot优化内置服务器Tomcat优化方式(underTow)

    Springboot优化内置服务器Tomcat优化方式(underTow)

    本文详细介绍了Spring Boot中Tomcat和Undertow服务器的配置和优化,包括初始线程数、最大线程数、最小备用线程数、最大请求数等参数的优化建议,以及在高并发场景下Undertow相对于Tomcat的优势
    2024-12-12
  • Java中String的intern()方法详细说明

    Java中String的intern()方法详细说明

    这篇文章主要介绍了Java中String的intern()方法详细说明,String::intern()是一个本地方法,他的作用就是如果字符串常量池中已经包含了一个等于此String对象的字符串,则返回代表池中的这个字符串额String对象的引用,需要的朋友可以参考下
    2023-11-11

最新评论