「可直接上线用」的升级方案,在现有 NSSM + Spring Boot 的基础上增加:
✅ JVM 参数系统化优化
✅ 服务异常自动重启
✅ 内存溢出自动 dump
✅ GC 日志
✅ 避免频繁重启(防抖)
✅ 脚本 可重复执行(幂等)
一、升级后的整体能力图
JAR 崩溃
↓
NSSM 自动重启(延迟 5 秒)
↓
最多 3 次 / 10 分钟
↓
超过阈值 → 停止(防止雪崩)
同时 JVM:
- 使用 G1GC
- 控制内存
- OOM 自动 dump
- GC 日志滚动
二、JVM 参数(推荐生产配置)
🔥 JVM_OPTS(通用、稳定)
set JVM_OPTS=^
-Xms512m ^
-Xmx1024m ^
-XX:+UseG1GC ^
-XX:MaxGCPauseMillis=200 ^
-XX:+HeapDumpOnOutOfMemoryError ^
-XX:HeapDumpPath=%APP_HOME%\logs\heapdump ^
-Xlog:gc*,gc+heap=info:file=%APP_HOME%\logs\gc.log:time,uptime:filecount=5,filesize=10M ^
-Dfile.encoding=UTF-8 ^
-Duser.timezone=Asia/Shanghai
为什么这样配?
| 参数 | 作用 |
|---|---|
| Xms / Xmx | 固定堆,避免动态扩容抖动 |
| G1GC | 服务端默认最优 |
| MaxGCPauseMillis | 控制停顿 |
| HeapDump | OOM 可追溯 |
| GC 日志 | 性能分析 |
| 文件滚动 | 防止磁盘爆 |
三、自动重启策略(NSSM)
关键配置说明
| 配置 | 含义 |
|---|---|
| AppRestartDelay | 崩溃后延迟重启 |
| AppThrottle | 多久内允许重启 |
| AppExit | 退出码策略 |
四、🔥 终极升级版脚本(可直接用)
✅ service-install.bat(完整版)
@echo off
setlocal enabledelayedexpansion
REM ==========================
REM 基础配置
REM ==========================
set SERVICE_NAME=ParkOfficeService
set SERVICE_DISPLAY_NAME=Park Office System
set SERVICE_DESC=Park Office Spring Boot Service
set NSSM=D:\tools\nssm\nssm.exe
set JAVA_EXE=C:\Program Files\Java\jdk-17\bin\java.exe
set APP_HOME=D:\app\park-office
set JAR_NAME=app.jar
REM 创建日志目录
if not exist "%APP_HOME%\logs" mkdir "%APP_HOME%\logs"
if not exist "%APP_HOME%\logs\heapdump" mkdir "%APP_HOME%\logs\heapdump"
REM ==========================
REM JVM 参数(生产)
REM ==========================
set JVM_OPTS=^
-Xms512m ^
-Xmx1024m ^
-XX:+UseG1GC ^
-XX:MaxGCPauseMillis=200 ^
-XX:+HeapDumpOnOutOfMemoryError ^
-XX:HeapDumpPath=%APP_HOME%\logs\heapdump ^
-Xlog:gc*,gc+heap=info:file=%APP_HOME%\logs\gc.log:time,uptime:filecount=5,filesize=10M ^
-Dfile.encoding=UTF-8 ^
-Duser.timezone=Asia/Shanghai
REM ==========================
REM 判断服务是否存在
REM ==========================
sc query "%SERVICE_NAME%" >nul 2>&1
if %ERRORLEVEL% EQU 0 (
echo [INFO] 服务已存在,跳过注册
goto CONFIG_SERVICE
)
REM ==========================
REM 注册服务
REM ==========================
echo [INFO] 注册服务中...
"%NSSM%" install "%SERVICE_NAME%" "%JAVA_EXE%" ^
%JVM_OPTS% -jar "%APP_HOME%%JAR_NAME%"
"%NSSM%" set "%SERVICE_NAME%" AppDirectory "%APP_HOME%"
"%NSSM%" set "%SERVICE_NAME%" DisplayName "%SERVICE_DISPLAY_NAME%"
"%NSSM%" set "%SERVICE_NAME%" Description "%SERVICE_DESC%"
REM ==========================
REM 服务配置(无论是否存在都执行)
REM ==========================
:CONFIG_SERVICE
REM 日志
"%NSSM%" set "%SERVICE_NAME%" AppStdout "%APP_HOME%\logs\stdout.log"
"%NSSM%" set "%SERVICE_NAME%" AppStderr "%APP_HOME%\logs\stderr.log"
"%NSSM%" set "%SERVICE_NAME%" AppRotateFiles 1
"%NSSM%" set "%SERVICE_NAME%" AppRotateOnline 1
"%NSSM%" set "%SERVICE_NAME%" AppRotateBytes 10485760
REM ==========================
REM 自动重启策略(重点)
REM ==========================
REM 5 秒后重启
"%NSSM%" set "%SERVICE_NAME%" AppRestartDelay 5000
REM 10 分钟内最多 3 次重启
"%NSSM%" set "%SERVICE_NAME%" AppThrottle 600000
REM 非 0 退出码才重启
"%NSSM%" set "%SERVICE_NAME%" AppExit Default Restart
REM 开机自启
"%NSSM%" set "%SERVICE_NAME%" Start SERVICE_AUTO_START
echo [SUCCESS] 服务配置完成
REM ==========================
REM 启动服务
REM ==========================
net start "%SERVICE_NAME%"
echo [SUCCESS] 服务启动完成
pause
五、运行效果你会看到什么?
✔ 正常运行
Java 17
Spring Boot started
✔ OOM 时
java.lang.OutOfMemoryError
Heap dump created at:
D:\app\park-office\logs\heapdump\java_pid1234.hprof
✔ 崩溃后
NSSM: restarting service in 5000ms
六、常见调优建议(给你几个可选升级)
1️⃣ 机器 8G 内存以上
-Xms1g -Xmx2g
2️⃣ 高并发接口
-XX:MaxGCPauseMillis=100
3️⃣ Spring Boot 优化(建议加)
-Dspring.profiles.active=prod
-Dspring.main.lazy-initialization=true