应使用 systemd 注册 spring boot 应用,需在 pom.xml 中配置 true 使 jar 可执行,配合 /etc/systemd/system/your-app.service 文件(含 user、execstart、successexitstatus=143 等关键项),并执行 daemon-reload、enable、start;日志统一用 journalctl 查看。

直接用 systemd 注册,别碰 init.d 或手动写 shell 脚本启动——CentOS 7+ / Ubuntu 16.04+ 都默认用 systemd,它原生支持进程守护、日志聚合、依赖管理、优雅重启,而其他方式要么过时,要么要自己补一堆逻辑。
打包时必须加 <executable>true</executable>
不加这个,.jar 文件只是普通可运行包,不是 Linux 可执行文件,systemd 无法直接调用(会报 Failed at step EXEC spawning)。在 pom.xml 的 spring-boot-maven-plugin 配置里确认有:
<configuration><executable>true</executable></configuration>
- 打包后用
file your-app.jar检查:输出应含ELF 64-bit LSB executable,不是Java archive data - 如果没生效,清掉
target/重跑mvn clean package - 不加
executable也能硬配ExecStart=/usr/bin/java -jar ...,但会丢失systemd对 Java 进程的原生信号转发(比如SIGTERM无法触发 Spring Boot 的优雅停机)
your-app.service 文件里最关键的三行
放在 /etc/systemd/system/your-app.service,内容精简到只留核心项:
[Unit] Description=My Spring Boot App After=network.target [Service] Type=simple User=appuser WorkingDirectory=/opt/myapp ExecStart=/opt/myapp/myapp.jar SuccessExitStatus=143 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
-
User=appuser:绝不能用root。提前建用户:sudo useradd --shell /bin/false --home-dir /opt/myapp appuser,再sudo chown -R appuser:appuser /opt/myapp -
ExecStart=/opt/myapp/myapp.jar:路径必须是绝对路径,且该文件要有+x权限(chmod +x myapp.jar) -
SuccessExitStatus=143:Spring Boot 收到SIGTERM后正常退出码是 143,加这行能让systemd不把它当崩溃处理;否则每次stop都触发Restart
启动前必须 reload,且日志别乱 redirect
改完 .service 文件不 daemon-reload,systemctl 就读不到新配置;自己加 > /var/log/app.log 2>&1 会绕过 journald,丢掉时间戳、优先级、unit 标识等关键上下文。
- 执行顺序固定:
sudo systemctl daemon-reload && sudo systemctl enable your-app && sudo systemctl start your-app - 查日志统一用:
journalctl -u your-app -f(实时)、journalctl -u your-app --since "2 hours ago"(按时间查) - 如果非要落盘日志,用
systemd原生方式:StandardOutput=append:/var/log/your-app.log,但会失去结构化查询能力 - 首次启动失败?先
sudo systemctl status your-app看最后一屏错误,再journalctl -u your-app -n 50翻前 50 行
真正容易被忽略的是权限和信号链路:jar 文件属主不对,User 字段就形同虚设;没配 SuccessExitStatus,systemctl stop 会立刻触发重启,你以为服务“停不掉”,其实是它被当成异常崩溃了。











