现代主流发行版(Ubuntu 16.04+、Debian 8+、RHEL/CentOS 7+、Fedora)都用 systemd 做初始化系统。日常打交道最多的是两件事:用 systemctl 管服务,用 journalctl 看日志。本文再进一步:写一个自己的 unit 文件,把脚本变成受管服务。
systemctl 日常操作速查
systemctl status nginx # 状态 + 最近几行日志sudo systemctl start nginx # 启动sudo systemctl stop nginx # 停止sudo systemctl restart nginx # 重启sudo systemctl reload nginx # 重载配置(进程不中断,需服务支持)sudo systemctl enable nginx # 开机自启(不改当前状态)sudo systemctl enable --now nginx # 自启 + 立即启动sudo systemctl disable --now nginx # 取消自启并停止status 输出里最值钱的两行:Active: active (running) since ... 和 Main PID。如果看到 failed,先别急着 restart——失败原因往往就在 status 显示的最近日志里。
几个容易混淆的点:
enable只管开机自启,不影响当前运行状态;--now把两件事一起做。reload依赖服务自己支持(ExecReload),不支持时会报错,这时只能用restart。systemctl is-active nginx、is-enabled、is-failed返回简单状态,适合写脚本判断。
看懂 unit 文件
unit 文件通常在 /etc/systemd/system/(自定义)和 /usr/lib/systemd/system/(软件包安装)下。systemctl cat nginx 能直接查看。
一个最小可用的自定义服务,把 /opt/myapp/run.sh 变成服务:
[Unit]Description=My AppAfter=network-online.targetWants=network-online.target
[Service]Type=simpleUser=myappWorkingDirectory=/opt/myappExecStart=/opt/myapp/run.shRestart=on-failureRestartSec=5
[Install]WantedBy=multi-user.target三个段落的分工:
[Unit]:元信息和启动顺序。After=network-online.target保证网络就绪后再启动——依赖网络的服务只写network.target是不够的。[Service]:怎么跑。Type=simple表示 ExecStart 的进程就是主进程;Restart=on-failure异常退出时自动拉起;User=让服务以非 root 身份运行,是安全基线。[Install]:何时被启用。WantedBy=multi-user.target表示enable后随正常多用户模式启动。
改完 unit 文件必须执行 sudo systemctl daemon-reload 让 systemd 重新读取,然后 sudo systemctl enable --now myapp。
journalctl:结构化日志的正确用法
systemd 把服务标准输出、错误输出和内核日志统一收进 journal。基本用法:
journalctl -u myapp # 某个服务的全部日志journalctl -u myapp -n 200 # 最近 200 行journalctl -u myapp -f # 实时跟踪(类似 tail -f)journalctl -u myapp --since "1 hour ago"journalctl -u myapp --since "2026-09-12 20:00" --until "2026-09-12 21:00"journalctl -p err # 只看 err 及以上优先级(所有服务)journalctl -k # 内核日志(等价 dmesg)journalctl -b # 本次开机以来的日志journalctl --disk-usage # 日志占了多少磁盘两个实用技巧:
-o json-pretty输出完整结构化字段,能看到_PID、_EXE等元数据,写日志收集脚本时用得上。-x给部分日志附加解释文字(如 OOM、core dump),排障时值得一看。
排查套路:服务起不来怎么办
systemctl status myapp:看退出码和最后几行输出。journalctl -u myapp -n 100 --no-pager:看完整错误。- 常见根因对号入座:
status=203/EXEC:ExecStart 路径错误或文件不可执行;status=217/USER:User=指定的用户不存在;code=exited, status=1:程序自己报错,去读程序日志;- 权限问题:检查 WorkingDirectory、日志目录对
User=是否可写。
- 修复后
daemon-reload(改了 unit 才需要)→reset-failed→start。
journal 默认持久化程度因发行版而异:/var/log/journal/ 存在才持久,否则重启即丢。生产机器建议确认 Storage=persistent(/etc/systemd/journald.conf),并用 SystemMaxUse= 限制体积。
延伸阅读
- systemd 官方文档
man 5 systemd.service、man 1 journalctl、man 5 journald.conf- freedesktop: systemd Service 单元说明
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
最后更新于 ,距今已过 40 天
部分内容可能已过时