SpringBoot在宝塔频繁掉线主因是JVM内存不足触发Linux OOM Killer,宝塔未守护进程且默认堆配置过小;应显式设置-Xms/-Xmx、改用Systemd管理并校准反向代理配置。

SpringBoot在宝塔里频繁掉线,大概率是Java进程被OOM Kill了
宝塔面板本身不管理Java进程生命周期,它只是把你的 java -jar xxx.jar 当成普通命令启动,一旦JVM因内存不足触发Linux OOM Killer,进程就被静默干掉,面板里只剩个“已停止”状态,毫无日志提示。
典型现象包括:网站访问几分钟后502、后台看不到Java进程、dmesg -T | grep -i "killed process" 能查到类似 Killed process 12345 (java) 的记录。
- 宝塔默认没设JVM堆内存参数,全靠系统自动推断,往往给得太小(尤其小内存VPS)
- SpringBoot内置Tomcat会额外占用堆外内存,
-Xmx只管堆,不管Metaspace和Direct Buffer - 用宝塔“网站”模块添加的Java项目,实际走的是Shell脚本启动,没做进程守护,崩溃即消失
必须显式配置 -Xms 和 -Xmx,并预留足够系统内存
别信“让JVM自己决定”,小内存机器上它大概率选错。以2G内存VPS为例,建议这样配:
java -Xms512m -Xmx768m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -jar /www/wwwroot/myapp/app.jar
关键点:
-
-Xms和-Xmx设为相同值,避免运行时堆扩容抖动 - 堆内存总和(
-Xmx+-XX:MaxMetaspaceSize+ 直接内存估算)不能超过物理内存的70%,否则OOM Killer必出手 - 别加
-XX:+UseG1GC之类参数除非你真懂——G1在小堆上反而更容易触发并发模式失败 - 检查真实可用内存:
free -h看available列,不是total
用Systemd替代宝塔Shell启动,实现真正的进程守护
宝塔的“开机自启”对Java服务无效,它只管面板自身;而Systemd能自动拉起崩溃进程、限制资源、写标准日志。
新建 /etc/systemd/system/myapp.service:
将 Spring Boot 2.7 项目升级到 Spring Boot 3.5 的实战流程,覆盖版本基线、依赖坐标替换、Jakarta 迁移、配置兼容、异步上下文传递改造与验证门禁。用于企业多模块 Maven 项目升级与排障。
[Unit] Description=My SpringBoot App After=network.target [Service] Type=simple User=www WorkingDirectory=/www/wwwroot/myapp ExecStart=/usr/bin/java -Xms512m -Xmx768m -jar /www/wwwroot/myapp/app.jar Restart=always RestartSec=10 KillSignal=SIGTERM TimeoutStopSec=60 LimitNOFILE=65536 [Install] WantedBy=multi-user.target
然后执行:
systemctl daemon-reload-
systemctl enable myapp.service(开机自启) -
systemctl start myapp.service(立即启动) - 查状态:
systemctl status myapp;看日志:journalctl -u myapp -f
注意:User=www 必须和宝塔网站运行用户一致,否则可能读不到配置文件或连不上MySQL。
宝塔反向代理配置要匹配SpringBoot的server.port和context-path
掉线有时不是Java挂了,而是Nginx根本没把请求转过去——比如SpringBoot跑在 server.port=8080,但宝塔反代填的是8081;或者用了 server.servlet.context-path=/api 却没在反代规则里补上前缀。
检查点:
- 确认
application.yml中server.port值,反代目标地址必须带这个端口(如http://127.0.0.1:8080) - 若配置了
context-path,宝塔反代的“目标URL”末尾要加对应路径,例如http://127.0.0.1:8080/api - 删掉宝塔自动生成的“强制HTTPS”规则里可能存在的重复
proxy_set_header Host行,避免Host头异常导致Spring Security拦截
最麻烦的其实是内存配置和Systemd之间的配合:-Xmx设高了,Systemd的 MemoryLimit 没同步调,照样被cgroup杀;设低了,应用自己OOM。得两边都盯住。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










