systemctl 服务管理:注册自定义应用为系统服务
前言
在 Linux 服务器上,我们经常需要将自研的应用程序(如 Web API、WebSocket 服务、后台任务进程等)以守护进程的方式长期运行,并具备开机自启、崩溃自动恢复、日志统一管理等功能。
systemd 是当今绝大多数 Linux 发行版(CentOS 7+、Ubuntu 16.04+、Debian 8+ 等)默认的 init 系统,而 systemctl 是其管理服务的核心命令。
通过编写一个 .service 单元文件,就可以将任意可执行程序注册为系统服务,享受与 nginx、sshd 等系统服务同等级别的管理能力——包括 start/stop/restart、enable/disable 自启、journalctl 日志查看、以及进程崩溃后自动重启。
本文以二进制可执行文件和 Jar 包两种常见场景为例,走通从编写 .service 文件到启停验证的完整流程。
添加服务
准备一个最小单元文件。
假设你的可执行文件放在 /data/wwwjarapi/8931mcws/xh-control-ws,示例中用 root 用户(生产环境建议创建专用系统用户运行)。
创建文件
1 | vi /etc/systemd/system/xh-control-ws.service |
启动GO服务示例
内容
1 | [Unit] |
启动 Jar 包示例
如果你的应用是 Spring Boot / Quarkus 等 Jar 包,ExecStart 改为 java -jar,并建议指定 JVM 参数。
/etc/systemd/system/xhschool-suser.service
1 | [Unit] |
与二进制示例的区别说明:
SuccessExitStatus=143是 Jar 服务特有的配置。Spring Boot 默认注册了 shutdown hook,收到SIGTERM后优雅关闭、进程退出码为 143,若不设置此项,systemctl stop后status可能会显示Failed,容易误判。
配置说明
[Unit]:Description 为服务描述,After=network.target 表示等网络就绪后再启动。
[Service] 配置说明:
Type=simple→ 拉起进程就算启动完成
User=root→ 用 root 身份跑(示例用,生产建议专用用户)
Group=root→ 用户组 root
WorkingDirectory=…→ 先 cd 到该目录再启动
ExecStart=…→ 要执行的命令(必须绝对路径)
Restart=always→ 一挂就重启
RestartSec=5s→ 等待5秒再重启
StartLimitInterval=60s + StartLimitBurst=10→ 60 秒内超 10 次重启就放弃
StandardOutput=journal→ 把 stdout 打进 systemd 日志
StandardError=journal→ 把 stderr 也打进 systemd 日志
启用并立即启
1 | sudo systemctl daemon-reload |
之后若修改过 .service 文件,需要先执行 daemon-reload 再 start 或 restart。
验证
手动 kill 进程:
1 | ps -ef | grep xh-control-ws |
几秒后执行 systemctl status xh-control-ws,应看到 Active: active (running),说明已被自动拉起。
查看状态
1 | systemctl status xh-control-ws |
查看实时日志:
1 | journalctl -u xh-control-ws -f |
服务启动/停止
正常停止/启动
1 | # 只停掉当前运行实例(下次开机若 enable 了仍会自启) |
彻底禁用自启
1 | # --now 顺便帮你 stop |