SpringBoot項(xiàng)目長(zhǎng)時(shí)間未訪問(wèn)導(dǎo)致Tomcat臨時(shí)文件夾被刪除的解決方案
引言
做SpringBoot開(kāi)發(fā)的同學(xué),大概率會(huì)遇到一個(gè)隱蔽的坑:項(xiàng)目部署在Linux服務(wù)器上,通過(guò)java -jar啟動(dòng)后,文件上傳功能一切正常,但如果系統(tǒng)長(zhǎng)時(shí)間(比如10天)無(wú)人訪問(wèn),再次上傳文件就會(huì)報(bào)錯(cuò),排查半天找不到原因,最后重啟項(xiàng)目又神奇恢復(fù)了。
其實(shí)這個(gè)問(wèn)題的根源,和Tomcat的臨時(shí)文件夾、Linux系統(tǒng)的臨時(shí)文件清理機(jī)制密切相關(guān)。今天就帶大家徹底搞懂這個(gè)問(wèn)題,從原因到解決方案,一步到位,再也不用靠“重啟救急”。
一、問(wèn)題復(fù)現(xiàn):隱蔽且易忽略
先明確問(wèn)題場(chǎng)景,避免大家對(duì)號(hào)入座出錯(cuò):
- 項(xiàng)目類型:SpringBoot打Jar包,通過(guò) java -jar xxx.jar 方式啟動(dòng)(非war包部署到獨(dú)立Tomcat);
- 部署環(huán)境:Linux服務(wù)器(CentOS、Ubuntu等均會(huì)出現(xiàn));
- 觸發(fā)條件:系統(tǒng)長(zhǎng)時(shí)間無(wú)人訪問(wèn)(通常10天左右),再次使用文件上傳功能時(shí)報(bào)錯(cuò);
- 臨時(shí)解決:重啟SpringBoot項(xiàng)目,上傳功能恢復(fù)正常。
二、問(wèn)題根源:兩步拆解,一看就懂
這個(gè)問(wèn)題不是SpringBoot的bug,也不是Tomcat的問(wèn)題,而是「Tomcat臨時(shí)文件存儲(chǔ)機(jī)制」和「Linux臨時(shí)文件清理機(jī)制」共同作用的結(jié)果,拆解成兩步就能明白:
1. Tomcat臨時(shí)文件夾的作用
當(dāng)我們用SpringBoot Jar包啟動(dòng)項(xiàng)目時(shí),SpringBoot會(huì)內(nèi)置一個(gè)Tomcat容器。當(dāng)項(xiàng)目中存在「文件上傳」功能時(shí),上傳的文件并不會(huì)直接被處理,而是先轉(zhuǎn)換成臨時(shí)文件,存放在Tomcat的臨時(shí)文件夾中,處理完成后再刪除臨時(shí)文件(或保留,取決于業(yè)務(wù)邏輯)。
重點(diǎn):SpringBoot內(nèi)置Tomcat,在Linux環(huán)境下,默認(rèn)的臨時(shí)文件夾路徑是 /tmp/ 目錄下(比如 /tmp/tomcat.xxxxxx.xxxx/ ),這個(gè)路徑是Tomcat自動(dòng)生成的,無(wú)需手動(dòng)配置。
2. Linux系統(tǒng)的臨時(shí)文件清理規(guī)則
Linux系統(tǒng)為了避免/tmp目錄占用過(guò)多磁盤空間,有一個(gè)默認(rèn)的臨時(shí)文件清理機(jī)制(由tmpwatch或systemd-tmpfiles服務(wù)管理),核心規(guī)則是:
「/tmp目錄下的文件/文件夾,如果連續(xù)10天沒(méi)有被訪問(wèn)、修改,就會(huì)被系統(tǒng)自動(dòng)刪除」。
3. 問(wèn)題閉環(huán)
系統(tǒng)長(zhǎng)時(shí)間無(wú)人訪問(wèn) → /tmp目錄下的Tomcat臨時(shí)文件夾10天未被 操作 → 被Linux系統(tǒng)自動(dòng)刪除 → 再次上傳文件時(shí),Tomcat無(wú)法找到臨時(shí)文件夾存放臨時(shí)文件 → 上傳失敗 → 重啟項(xiàng)目后,Tomcat重新生成臨時(shí)文件夾 → 功能恢復(fù)。
三、解決方案:兩種方式,按需選擇
針對(duì)這個(gè)問(wèn)題,有兩種解決方案,一種是臨時(shí)救急,一種是徹底根治,大家可以根據(jù)自己的部署場(chǎng)景選擇。
方案1:臨時(shí)救急(快速恢復(fù),適合緊急情況)
最簡(jiǎn)單、最快的方式,就是重啟SpringBoot項(xiàng)目。
重啟命令(根據(jù)自己的項(xiàng)目部署方式調(diào)整):
# 1. 查找項(xiàng)目進(jìn)程(假設(shè)項(xiàng)目Jar包名為xxx.jar) ps -ef | grep xxx.jar # 2. 殺死進(jìn)程(替換為查到的進(jìn)程ID) kill -9 進(jìn)程ID # 3. 重啟項(xiàng)目(后臺(tái)啟動(dòng),日志輸出到nohup.out) nohup java -jar xxx.jar
原理:重啟項(xiàng)目后,SpringBoot內(nèi)置的Tomcat會(huì)重新在/tmp目錄下生成臨時(shí)文件夾,恢復(fù)臨時(shí)文件存儲(chǔ)功能。
缺點(diǎn):治標(biāo)不治本,下次系統(tǒng)長(zhǎng)時(shí)間未訪問(wèn),問(wèn)題還會(huì)重復(fù)出現(xiàn);如果項(xiàng)目有狀態(tài)(比如未持久化的會(huì)話),重啟會(huì)導(dǎo)致?tīng)顟B(tài)丟失。
方案2:徹底根治(推薦,一勞永逸)
核心思路:修改Tomcat的臨時(shí)文件夾路徑,將臨時(shí)文件夾從Linux的/tmp目錄(會(huì)被自動(dòng)清理),遷移到自定義目錄(不會(huì)被系統(tǒng)自動(dòng)清理)。
具體操作:在SpringBoot的配置文件(application.yml 或 application.properties)中,配置Tomcat的basedir屬性,指定自定義臨時(shí)目錄。
重點(diǎn):yml配置示例(直接復(fù)制可用,適配大部分場(chǎng)景)
# 開(kāi)發(fā)/生產(chǎn)環(huán)境通用配置
server:
# 服務(wù)器HTTP端口(根據(jù)自己的需求調(diào)整)
port: 6116
servlet:
# 應(yīng)用訪問(wèn)路徑(默認(rèn)/,無(wú)需修改)
context-path: /
tomcat:
# Tomcat URI編碼(避免中文亂碼,必配)
uri-encoding: UTF-8
# Tomcat最大線程數(shù)(根據(jù)服務(wù)器配置調(diào)整,默認(rèn)200)
max-threads: 800
# Tomcat初始化線程數(shù)(默認(rèn)25,優(yōu)化后提升啟動(dòng)速度)
min-spare-threads: 30
# 關(guān)鍵配置:自定義Tomcat臨時(shí)文件夾路徑(避免被Linux清理)
# 注意:Linux環(huán)境請(qǐng)配置絕對(duì)路徑,比如 /home/tomcat/tmp
# Windows環(huán)境可配置 D:\\tmp(雙反斜杠轉(zhuǎn)義)
# 此處為 linux環(huán)境可配置
basedir: /home/tomcat/tmp
配置說(shuō)明(避坑重點(diǎn))
- 路徑格式:Linux環(huán)境必須配置絕對(duì)路徑(比如 /home/tomcat/tmp),Windows環(huán)境用雙反斜杠(D:\tmp),避免路徑解析錯(cuò)誤;
- 權(quán)限問(wèn)題:自定義目錄(比如 /home/tomcat/tmp)需要給啟動(dòng)項(xiàng)目的用戶(比如java用戶)賦予讀寫權(quán)限,否則Tomcat無(wú)法創(chuàng)建臨時(shí)文件,會(huì)報(bào)錯(cuò);
- 無(wú)需手動(dòng)創(chuàng)建目錄:配置完成后,重啟項(xiàng)目,Tomcat會(huì)自動(dòng)創(chuàng)建該目錄,無(wú)需手動(dòng)mkdir;
- 兼容所有SpringBoot版本:不管是2.x還是3.x版本,這個(gè)配置都適用,無(wú)需修改其他參數(shù)。
權(quán)限配置命令(Linux環(huán)境必看)
如果配置后報(bào)錯(cuò)“權(quán)限不足”,執(zhí)行以下命令賦予權(quán)限(替換目錄路徑和用戶名):
# 1. 創(chuàng)建自定義臨時(shí)目錄(如果Tomcat未自動(dòng)創(chuàng)建) mkdir -p /home/tomcat/tmp # 2. 賦予權(quán)限(假設(shè)啟動(dòng)用戶是java,替換為自己的用戶) chown -R java:java /home/tomcat/tmp # 3. 賦予讀寫執(zhí)行權(quán)限 chmod -R 755 /home/tomcat/tmp
四、補(bǔ)充注意事項(xiàng)(避坑必看)
- 不要將臨時(shí)目錄配置在/tmp、/var/tmp等系統(tǒng)默認(rèn)臨時(shí)目錄下,這些目錄都會(huì)被系統(tǒng)定期清理;
- 自定義臨時(shí)目錄無(wú)需擔(dān)心磁盤占用:Tomcat會(huì)自動(dòng)清理過(guò)期的臨時(shí)文件(比如上傳完成后的臨時(shí)文件),無(wú)需手動(dòng)刪除;
- 如果項(xiàng)目部署在Docker容器中,除了配置basedir,還需要將自定義臨時(shí)目錄掛載到宿主機(jī),避免容器重啟后臨時(shí)文件丟失;
- 排查技巧:如果不確定臨時(shí)文件夾是否被刪除,可以通過(guò) ls /tmp | grep tomcat 命令查看,若沒(méi)有相關(guān)文件夾,說(shuō)明已被系統(tǒng)清理。
五、總結(jié)
SpringBoot項(xiàng)目長(zhǎng)時(shí)間未訪問(wèn),Tomcat臨時(shí)文件夾被刪除的問(wèn)題,本質(zhì)是「系統(tǒng)清理機(jī)制」和「Tomcat默認(rèn)配置」的沖突。
緊急情況用「重啟項(xiàng)目」快速恢復(fù),生產(chǎn)環(huán)境推薦用「配置Tomcat自定義臨時(shí)目錄」徹底根治,配置簡(jiǎn)單、一勞永逸,還能避免后續(xù)重復(fù)踩坑。
如果大家在配置過(guò)程中遇到權(quán)限報(bào)錯(cuò)、路徑解析錯(cuò)誤等問(wèn)題,可以在評(píng)論區(qū)留言,我會(huì)及時(shí)回復(fù)排查思路~
以上就是SpringBoot項(xiàng)目長(zhǎng)時(shí)間未訪問(wèn)導(dǎo)致Tomcat臨時(shí)文件夾被刪除的解決方案的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot項(xiàng)目未訪問(wèn)導(dǎo)致Tomcat被刪除的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
quartz實(shí)現(xiàn)定時(shí)功能實(shí)例詳解(servlet定時(shí)器配置方法)
Quartz是一個(gè)完全由java編寫的開(kāi)源作業(yè)調(diào)度框架,下面提供一個(gè)小例子供大家參考,還有在servlet配置的方法2013-12-12
Java實(shí)現(xiàn)將列表數(shù)據(jù)導(dǎo)出為PDF文件并添加水印
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)把列表數(shù)據(jù)導(dǎo)出為PDF文件,同時(shí)加上PDF水印,文中的示例代碼講解詳細(xì),需要的可以參考下2024-02-02
mybatis參數(shù)String與Integer類型的判斷方式
這篇文章主要介紹了mybatis參數(shù)String與Integer類型的判斷方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringMVC框架實(shí)現(xiàn)上傳圖片的示例代碼
本篇文章主要介紹了SpringMVC框架實(shí)現(xiàn)上傳圖片的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
SpringBoot整合Redis的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot整合Redis的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
Spring?Boot項(xiàng)目部署命令java?-jar的各種參數(shù)及作用詳解
這篇文章主要介紹了Spring?Boot項(xiàng)目部署命令java?-jar的各種參數(shù)及作用的相關(guān)資料,包括設(shè)置內(nèi)存大小、垃圾回收器、線程棧大小、系統(tǒng)屬性等,還介紹了SpringBoot專用參數(shù),如修改端口、指定配置文件等,需要的朋友可以參考下2025-04-04
k8s+springboot+CronJob定時(shí)任務(wù)部署實(shí)現(xiàn)
本文主要介紹了k8s+springboot+CronJob定時(shí)任務(wù)部署實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
spring boot 注入 property的三種方式(推薦)
這篇文章主要介紹了spring boot 注入 property的三種方式,需要的朋友可以參考下2017-07-07

