核心三点:写对.service文件(放/etc/systemd/system/、绝对路径ExecStart、Type=simple、WorkingDirectory、非root用户、Restart策略)、执行sudo systemctl daemon-reload加载、再sudo systemctl enable启动并验证enabled状态及journalctl查日志。

用 systemd 把 Java 项目做成系统服务,核心就三点:写对 .service 文件、加载生效、启用自启。不是加个脚本或改 rc.local 就算完事,得让 systemd 正确识别 Java 是长期运行的主进程,而不是跑完就退出的命令。
服务文件必须放在正确位置并严格命名
自定义服务文件统一放 /etc/systemd/system/ 目录下,文件名必须以 .service 结尾(如 myapp.service),权限设为 644:
- 不能放在
/lib/systemd/system/—— 那是软件包管理器专用路径,手动放进去可能被覆盖 - 不能建子目录或用其他后缀,systemd 不扫描子目录,也不认
.conf或.sh - 编辑完必须立刻执行
sudo systemctl daemon-reload,否则后续enable或start都会静默失败
关键配置项不能漏也不能错
一个能稳定运行的服务文件,这几个字段缺一不可且写法有讲究:
-
ExecStart 必须用绝对路径调用
java和.jar,例如/usr/bin/java -Xms256m -Xmx512m -jar /opt/myapp/app.jar;不能写java -jar app.jar或套 shell 命令 -
Type=simple 是默认值,但必须明确写出——Java 启动后 JVM 就是主进程,不能设成
forking,否则 systemd 会误判 PID -
WorkingDirectory 指向 jar 包所在目录,尤其当应用依赖
application.yml或logback.xml等同级配置文件时,这是唯一可靠方式 -
User 和 Group 建议指定非 root 用户(如
appuser),提升安全性;若用 root,需确保 jar 包和目录权限允许其读取 - Restart=on-failure 或 always 必须设置,否则 OOM 或未捕获异常导致退出后服务就彻底停了
启用开机自启和验证是否真生效
写好文件并 reload 后,启用和验证要分两步走:
立即学习“Java免费学习笔记(深入)”;
- 执行
sudo systemctl enable myapp.service—— 这会在/etc/systemd/system/multi-user.target.wants/下建软链接,才算真正“启用” - 用
systemctl is-enabled myapp.service检查返回是否为enabled,只写文件不 enable,重启后不会自动启动 - 启动服务后,别只看
systemctl status的一句话,重点查日志:journalctl -u myapp -n 50 -f查启动输出,确认端口绑定、配置加载、数据库连接等关键步骤是否成功
常见失败原因和快速定位方法
服务启动失败通常不是 Java 本身问题,而是 systemd 配置没“说服”它:
- 状态卡在
activating (start)或秒退显示failed (result=exit-code),大概率是ExecStart路径错误或 jar 缺 Main-Class - 日志里报
no main manifest attribute,说明打包时没用 Spring Boot 插件或 MANIFEST.MF 缺Main-Class: org.springframework.boot.loader.JarLauncher - 重启多次失败后提示
start-limit-hit,需先sudo systemctl reset-failed myapp.service清除失败计数器 - 怀疑加载的是旧配置?用
systemctl cat myapp.service直接查看 systemd 实际读取的文件内容


















