用 systemd 管理自建服务:从手动启动到开机自启
很多自建服务一开始都是这样跑起来的:在服务器上敲一行命令,nohup ./myapp &,服务起来了,终端一关,心里却始终不踏实。服务器重启后服务没了,进程半夜崩了没人知道,日志散落在 nohup.out 里,出了问题只能凭记忆去翻。等服务越来越多,这种“手动启动”的方式迟早会出事。用 systemd 把它管起来,是成本最低、收益最明显的一步:写一个 unit 文件,就能得到开机自启、崩溃自动重启、统一日志和规范的启停控制。
为什么是 systemd
主流 Linux 发行版都把 systemd 作为 PID 1 的进程管理器,它天然适合做服务守护。首先是自启:服务随系统启动,不再依赖人工登录操作;其次是自愈:进程异常退出后按策略自动重启,配合 RestartSec 还能避免瞬间反复拉起;再次是可观测:标准输出统一进 journald,用 journalctl 就能按服务、按时间查日志;最后是可控:启动顺序、依赖关系、资源上限、运行用户都能声明式写清楚,换一台机器照抄 unit 文件即可复现。
写第一个 unit 文件
假设你的程序在 /opt/myapp/myapp,监听 8080 端口。新建 /etc/systemd/system/myapp.service:
[Unit]
Description=My demo web service
After=network.target
Wants=network.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp --port 8080
Restart=on-failure
RestartSec=5s
Environment=APP_ENV=prod
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
几个关键点值得单独说。Type=simple 适合前台常驻的程序,不要照搬网上用 Type=forking 的模板,那是给会自己 daemon 化的老程序准备的。ExecStart 必须写绝对路径,也不要直接写 shell 管道,需要 shell 逻辑时再用 /bin/bash -c 包一层。WorkingDirectory 决定了程序的相对路径基准,很多“手动能跑、服务起不来”的问题都是它没配对。User 不要用 root 跑业务进程,单独建一个低权限用户,配合文件权限收紧,是最基本的隔离。
启用、启动与日常运维
写好文件后依次执行:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp
sudo journalctl -u myapp -f
修改 unit 文件后一定要先 daemon-reload 再 restart,否则改动不会生效,这是新手最常踩的坑。日常操作就四条命令:start、stop、restart、status;查日志用 journalctl -u myapp --since “1 hour ago”,比翻散落的日志文件高效得多。需要临时停掉开机自启,用 disable 即可,服务本身不受影响。
常见故障与排查思路
服务起不来时,先看 status 和 journalctl 的报错,而不是反复重启碰运气。启动后立刻退出,常见原因是端口被占用、配置文件路径写成了相对路径、环境变量没传进去——这类问题用 Environment 或 EnvironmentFile=/opt/myapp/.env 显式声明就能解决。反复重启刷屏一般是 Restart 配得太激进,配合 StartLimitIntervalSec 和 StartLimitBurst 做熔断更稳妥。还有一类隐蔽问题:程序依赖的数据库或中间件还没就绪,After=network.target 只保证网络栈就绪,不保证你的数据库可连,启动时加重试逻辑比在 unit 里硬等更可靠。
再进一步:加一点加固
服务稳定运行后,可以顺手加几行加固配置:NoNewPrivileges=true 防止提权,PrivateTmp=true 隔离临时目录,LimitNOFILE=65535 放宽文件句柄上限。这些配置改动小,但能把“能跑”和“跑得稳”区分开。
小结
从手动启动到 systemd 管理,本质上是把散落在终端历史里的操作,沉淀成一份可版本管理、可复现、可审计的配置文件。先让一个服务跑起来,再把日志、重启策略和权限收紧,一次只改一处,改完用 status 和 journalctl 验证。等你习惯了这套流程,就会发现服务器重启、进程崩溃都不再是深夜惊醒的理由,而只是 journal 里的一行记录。
- 点赞
- 收藏
- 关注作者
评论(0)