ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

11 · systemd 服务管理

11 · systemd 服务管理

11 · systemd 服务管理

一句话定位:把你的 Java 应用做成系统服务——崩了自动拉起、随机器开机自启、日志统一管理。比 nohup 更专业。


1. 为什么用 systemd 而不是 nohup

nohupsystemd
开机自启❌ 要自己写✅ 一条命令
崩溃自动重启❌✅
统一管理❌ 到处找PID✅systemctl统管
日志自己重定向✅journalctl统一

systemd 是现代 Linux(CentOS7+/Ubuntu16+)的标准服务管理器,几乎所有服务(nginx/mysql/docker)都归它管。


2. systemctl 操作已有服务

systemctl start nginx# 启动systemctl stop nginx# 停止systemctl restart nginx# 重启systemctl reload nginx# 重载配置(不中断)systemctl status nginx# ★查看状态(最常用,看运行情况+最近日志)systemctlenablenginx# 设为开机自启systemctl disable nginx# 取消开机自启systemctl is-enabled nginx# 查是否自启systemctl is-active nginx# 查是否在运行systemctl list-units--type=service# 列出所有服务

没权限前面加sudo。


3. 把自己的 Java 应用做成 systemd 服务

创建服务定义文件/etc/systemd/system/myapp.service:

[Unit] Description=My Spring Boot App After=network.target # 网络就绪后再启动 [Service] Type=simple User=deploy # 用哪个用户跑(别用root) WorkingDirectory=/opt/app # 工作目录 # 启动命令(注意用绝对路径) ExecStart=/opt/jdk-17/bin/java -Xms2g -Xmx2g -Dspring.profiles.active=prod -jar /opt/app/app.jar # 停止用 SIGTERM(优雅停机) ExecStop=/bin/kill -15 $MAINPID SuccessExitStatus=143 # 143 = 被SIGTERM正常终止,算成功 Restart=always # ★崩溃自动重启 RestartSec=5 # 重启间隔5秒 # 环境变量(可选) Environment="JAVA_HOME=/opt/jdk-17" # 日志(交给 journald,或自己重定向) StandardOutput=append:/opt/app/logs/app.log StandardError=append:/opt/app/logs/app.log [Install] WantedBy=multi-user.target # 开机自启的目标

4. 启用你的服务

# 1. 改了 .service 文件后,重载 systemd 配置systemctl daemon-reload# 2. 启动systemctl start myapp# 3. 查看状态(确认 active running)systemctl status myapp# 4. 设为开机自启systemctlenablemyapp# 之后日常操作就和操作 nginx 一样systemctl restart myapp systemctl stop myapp

5. 查服务日志:journalctl

journalctl-umyapp# 看 myapp 服务的全部日志journalctl-umyapp-f# ★实时追踪(类似 tail -f)journalctl-umyapp-n200# 最近200行journalctl-umyapp--since"10:00"# 从10点开始journalctl-umyapp--sincetoday# 今天的journalctl-umyapp-perr# 只看 error 级别journalctl-umyapp--since"2026-10-14 10:00"--until"10:30"# 时间段

如果.service里已经把日志重定向到文件(StandardOutput=append:...),也可以直接tail -f /opt/app/logs/app.log。


6. 实战:完整部署一个服务

# 1. 上传 jar(本地)scpapp.jar prod:/opt/app/# 2. 写 service 文件(服务器)sudovim/etc/systemd/system/myapp.service# 粘贴上面的模板# 3. 启用sudosystemctl daemon-reloadsudosystemctlenablemyappsudosystemctl start myapp# 4. 验证systemctl status myapp journalctl-umyapp-f# 5. 以后升级scpapp.jar prod:/opt/app/# 传新包sudosystemctl restart myapp# 一条命令重启

7. 坑与最佳实践

  • ✅ 改完.service文件必须systemctl daemon-reload,否则不生效。
  • ✅ExecStart里的java、jar都要写绝对路径(systemd 环境没有你的 PATH)。
  • ✅Restart=always让服务崩溃自愈,生产必备。
  • ✅ExecStop用kill -15(优雅),配SuccessExitStatus=143避免被误判为失败。
  • ⚠️ 用非 root 用户(User=deploy)跑,注意目录和日志文件该用户要有权限。
  • ⚠️ 启动失败看systemctl status myapp和journalctl -u myapp -n 50,错误都在里面。
  • 💡 想禁止自动重启排查问题,临时systemctl stop myapp,别一直被拉起干扰。

8. 本篇速记

systemctl start/stop/restart/status 服务# 控制服务systemctl enable/disable 服务# 开机自启systemctl daemon-reload# 改配置后重载 ★journalctl-u服务-f# 实时日志journalctl-u服务-n200# 最近200行# 服务定义:/etc/systemd/system/xxx.service
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进