systemd 使用与运维指南

本文是一份面向 Debian / Ubuntu 的 systemd 实战指南,重点讲清楚如何理解 unit、使用 systemctl 管理服务、查看 journalctl 日志、编写自定义 service、使用 timer、做 override,以及排查常见启动失败问题。

适用场景

  • 管理系统服务
  • 启停 Web、数据库、SSH、Docker 等守护进程
  • 为自定义程序编写开机自启服务
  • 使用 timer 代替 cron 做定时任务
  • 排查服务启动失败和资源限制问题

systemd 是什么

systemd 是 Linux 的系统和服务管理器。它在系统启动时作为 PID 1 运行,负责初始化和管理用户空间服务。


systemd 相关的核心工具有:

  • systemctl:管理 unit
  • journalctl:查看日志
  • systemd-analyze:分析启动时间和依赖
  • systemd-run:动态运行临时服务

核心概念

Unit

Unit 是 systemd 管理的对象,可以是:

  • service
  • socket
  • timer
  • target
  • mount
  • swap
  • path
  • slice

Service

*.service 是最常见的 unit,用来管理进程或守护程序。

Target

*.target 可以理解为一组 unit 的聚合点,类似更现代的运行级别概念。

Timer

*.timer 用来做定时任务,是 cron 的常见替代方案。

unit 文件位置

常见路径:

/etc/systemd/system/
/lib/systemd/system/
/usr/lib/systemd/system/

一般规则:

  • 自定义服务优先放 /etc/systemd/system/
  • 系统包安装的服务通常在 /lib/systemd/system/ 或 /usr/lib/systemd/system/

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 disable nginx

查看是否启用

systemctl is-enabled nginx
systemctl is-active nginx

列出 unit

systemctl list-units
systemctl list-unit-files
systemctl list-dependencies nginx

重新加载 systemd 配置

修改 unit 文件后,需要让 systemd 重新读取配置:

sudo systemctl daemon-reload

这一步很重要。改了 .service 文件后不做 daemon-reload,系统可能还在用旧配置。

service 文件结构

一个常见的 service 文件由三部分组成:

  • [Unit]
  • [Service]
  • [Install]

示例

[Unit]
Description=My App Service
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

常见字段说明

[Unit]

  • Description:描述
  • After:启动顺序依赖
  • Requires:强依赖
  • Wants:弱依赖
  • Before:在谁之前启动

[Service]

  • Type:服务类型
  • User / Group:运行用户
  • WorkingDirectory:工作目录
  • ExecStart:启动命令
  • ExecStop:停止命令
  • Restart:重启策略
  • RestartSec:重启间隔
  • Environment:环境变量
  • EnvironmentFile:环境变量文件

[Install]

  • WantedBy:被哪个 target 拉起

常见 Type

  • simple:最常见,启动命令即主进程
  • exec:类似 simple,但更强调执行状态
  • forking:旧式守护进程,启动后会 fork
  • oneshot:一次性任务
  • notify:通过 sd_notify 通知就绪

多数现代程序直接用 Type=simple 就够了。

编写自定义 service

假设你的程序在 /opt/myapp/myapp


创建文件:

sudo nano /etc/systemd/system/myapp.service

内容示例:

[Unit]
Description=MyApp Service
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp
Restart=always
RestartSec=3
Environment=APP_ENV=prod

[Install]
WantedBy=multi-user.target

应用配置:

sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

日志查看

systemd 的日志主要通过 journalctl 查看。

查看服务日志

journalctl -u nginx

跟随日志

journalctl -u nginx -f

查看本次启动的日志

journalctl -u nginx -b

查看错误级别日志

journalctl -p err -b

清晰时间显示

journalctl -u nginx --since "today"

override 与 drop-in

不要直接修改系统包提供的 unit 文件。更稳妥的方法是使用 override。


创建 override:

sudo systemctl edit nginx

示例:

[Service]
Restart=always
RestartSec=2

保存后,systemd 会把配置写到:

/etc/systemd/system/nginx.service.d/override.conf

查看最终生效配置:

systemctl cat nginx

environment 文件

有些服务会单独使用环境文件:

EnvironmentFile=/etc/default/myapp

示例内容:

APP_ENV=prod
APP_PORT=8080

timer

Timer 是 systemd 的定时任务机制,常用于替代 cron。

示例 service

[Unit]
Description=Backup Job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

示例 timer

[Unit]
Description=Run backup every day at 03:00

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

启用:

sudo systemctl enable --now backup.timer

查看 timer:

systemctl list-timers

target

target 用于组织一组服务。


常见 target:

  • multi-user.target
  • graphical.target
  • network.target
  • timers.target

查看默认启动目标:

systemctl get-default

常见排障

1. 服务启动失败

先看状态:

systemctl status myapp

再看日志:

journalctl -u myapp -xe

2. unit 改了没生效

执行:

sudo systemctl daemon-reload
sudo systemctl restart myapp

3. 服务一直重启

检查:

  • ExecStart 是否正确
  • 程序是否马上退出
  • Restart 策略是否合适
  • 权限和工作目录是否正确

4. 端口没监听

检查程序是否真的起来:

ss -ltnp

5. 环境变量没生效

检查:

  • Environment 拼写
  • EnvironmentFile 路径
  • 是否重新加载和重启

性能与启动分析

查看启动耗时

systemd-analyze blame
systemd-analyze critical-chain

查看 unit 依赖

systemctl list-dependencies nginx

安全建议

  • 自定义服务尽量不要直接用 root
  • 不要随便改系统包 unit 文件本体
  • 修改 service 后记得 daemon-reload
  • 定时任务优先考虑 timer
  • 日志排障优先看 journal

最小可用流程

如果你想快速把一个程序变成 systemd 服务:

sudo nano /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
systemctl status myapp
journalctl -u myapp -f

结论

systemd 的核心是把“服务管理”标准化:

  • 用 unit 表达服务和依赖
  • 用 systemctl 管理状态
  • 用 journalctl 看日志
  • 用 override 做局部修改
  • 用 timer 做定时任务

如果你要,我可以继续把这篇文档扩成更深入的版本,例如:

  • systemd service 文件写法大全
  • timer 替代 cron 的完整实战
  • journalctl 高级过滤与排障
  • systemd target / dependency 深入说明
  • 自定义程序接入 systemd 的生产模板
本文地址: https://www.vvcms.cn/blog/systemd-guid
版权所有 © admin 未经授权不得转载