余白

systemd 完整教程

简介

systemd 是 Linux 系统的 init 系统和服务管理器,替代了传统的 SysVinit,提供更快的启动速度和更强大的服务管理能力。


基本概念

单元类型

类型后缀说明
Service.service运行守护进程
Socket.socket套接字激活
Device.device硬件设备
Mount.mount文件系统挂载点
Automount.automount自动挂载
Timer.timer定时任务(替代 cron)
Path.path文件路径监控
Snapshot.snapshot系统快照
Swap.swap交换空间
Target.target单元组

服务管理

启动/停止/重启

# 启动服务
sudo systemctl start nginx

# 停止服务
sudo systemctl stop nginx

# 重启服务
sudo systemctl restart nginx

# 重新加载配置(不中断服务)
sudo systemctl reload nginx

# 重载或重启(根据服务支持)
sudo systemctl reload-or-restart nginx

查看状态

# 查看服务状态
sudo systemctl status nginx

# 检查服务是否活跃
sudo systemctl is-active nginx

# 检查服务是否启用
sudo systemctl is-enabled nginx

# 查看所有运行中的服务
systemctl list-units --type=service --state=running

# 查看所有服务
systemctl list-units --type=service --all

开机自启

# 开机自启
sudo systemctl enable nginx

# 禁用开机自启
sudo systemctl disable nginx

# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 立即激活(不重启)
sudo systemctl enable --now nginx

强制操作

# 强制重启
sudo systemctl --force reboot

# 强制关机
sudo systemctl --force poweroff

# 强制终止服务
sudo systemctl --force kill nginx

日志管理(journalctl)

查看日志

# 查看所有日志
journalctl

# 查看最近日志
journalctl -n 50

# 实时查看日志
journalctl -f

# 查看指定时间之后的日志
journalctl --since "2024-01-01 00:00:00"
journalctl --since "1 hour ago"
journalctl --since "yesterday"

# 查看时间范围内的日志
journalctl --since "2024-01-01 00:00:00" --until "2024-01-02 00:00:00"

按服务筛选

# 查看指定服务日志
journalctl -u nginx

# 查看服务日志(最近)
journalctl -u nginx -n 50

# 实时查看服务日志
journalctl -u nginx -f

# 查看服务重启日志
journalctl -u nginx --since "1 hour ago" | grep "Started\|Stopping"

按优先级筛选

# 0: emerg  系统不可用
# 1: alert  需要立即处理
# 2: crit   严重错误
# 3: err    错误
# 4: warning 警告
# 5: notice 正常但重要
# 6: info   信息
# 7: debug  调试

journalctl -p err          # 只看错误
journalctl -p warning      # 警告及以上
journalctl -p 0..3        # 错误级别0-3

日志维护

# 查看磁盘占用
journalctl --disk-usage

# 清理旧日志(保留最近7天)
sudo journalctl --vacuum-time=7d

# 清理旧日志(保留最近500MB)
sudo journalctl --vacuum-size=500M

# 设置日志大小限制
sudo nano /etc/systemd/journald.conf
# SystemMaxUse=500M
# SystemMaxFileSize=50M

创建服务单元文件

存放位置

/etc/systemd/system/     # 系统服务(优先级高)
/run/systemd/system/    # 运行时创建
/lib/systemd/system/    # 软件包安装

Service 单元示例

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application Service
Documentation=https://example.com
After=network.target        # 网络启动后启动
Wants=network-online.target

[Service]
Type=simple                # 简单进程
ExecStart=/usr/bin/python3 /opt/myapp/server.py
ExecStop=/bin/kill -SIGTERM $MAINPID
ExecReload=/bin/kill -SIGHUP $MAINPID
Restart=on-failure         # 失败时重启
RestartSec=5               # 重启间隔
User=myuser                # 运行用户
Group=mygroup              # 运行组
WorkingDirectory=/opt/myapp
Environment="PORT=8080"    # 环境变量
EnvironmentFile=/etc/myapp/env

# 安全相关
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/myapp /var/log/myapp
PrivateTmp=true

[Install]
WantedBy=multi-user.target  # 多用户模式下启动

Type 类型说明

类型说明
simple主进程即为服务(默认)
execExecStart 执行后才是服务
forking主进程fork后退出
oneshot执行一次后退出(需 RemainAfterExit=yes)
dbus依赖 D-Bus 总线名称
notify服务启动完成后发送通知

WantedBy vs RequiredBy

WantedBy=multi-user.target    # 弱依赖(推荐)
RequiredBy=multi-user.target  # 强依赖

Timer 定时任务

创建定时器单元

# /etc/systemd/system/mytask.timer
[Unit]
Description=My Scheduled Task

[Timer]
OnCalendar=*-*-* *:*:00          # 每分钟
OnCalendar=*-*-* 03:00:00       # 每天凌晨3点
OnCalendar=weekly               # 每周
OnCalendar=monthly              # 每月
OnCalendar=Mon *-*-* 09:00:00  # 每周一9点
OnBootSec=5min                  # 启动5分钟后
OnUnitActiveSec=1hour           # 上次执行1小时后

[Install]
WantedBy=timers.target
# /etc/systemd/system/mytask.service
[Unit]
Description=My Scheduled Task

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /opt/myapp/task.py

定时器示例

# 每周日凌晨3点执行备份
[Timer]
OnCalendar=Sun *-*-* 03:00:00
Persistent=true                # 错过则立即执行

# 每隔5分钟执行一次
[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
Unit=myservice.service

Timer 命令

# 启动定时器
sudo systemctl start mytask.timer

# 查看定时器下次执行时间
systemctl list-timers

# 查看所有定时器
systemctl list-timers --all

# 查看定时器下次/上次触发
systemctl show mytask.timer -property NextElapseUSecRealtime

实战示例

1. 配置 Python Web 服务

# /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn Web Server
After=network.target

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/venv/bin/gunicorn \
    --workers 3 \
    --bind unix:/opt/myapp/gunicorn.sock \
    wsgi:app
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

2. 配置 Node.js 服务

# /etc/systemd/system/nodejs-app.service
[Unit]
Description=Node.js Application
After=network.target

[Service]
Type=simple
User=nodejs
WorkingDirectory=/opt/nodejs-app
ExecStart=/usr/bin/node /opt/nodejs-app/index.js
Restart=on-failure
RestartSec=10
Environment=NODE_ENV=production
Environment=PORT=3000
StandardOutput=journal
StandardError=journal
SyslogIdentifier=nodejs-app

[Install]
WantedBy=multi-user.target

3. 配置 Docker 容器服务

# /etc/systemd/system/docker-nginx.service
[Unit]
Description=Nginx Container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a nginx
ExecStop=/usr/bin/docker stop -t 10 nginx

[Install]
WantedBy=multi-user.target

4. 每日备份定时任务

# /etc/systemd/system/backup.timer
[Unit]
Description=Database Backup Timer

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

[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Database Backup

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh

常用系统目标

目标说明
poweroff.target关机
rescue.target救援模式
multi-user.target多用户(非图形)
graphical.target图形界面
reboot.target重启
emergency.target紧急模式

切换目标

# 切换到多用户模式
sudo systemctl isolate multi-user.target

# 设置默认目标
sudo systemctl set-default multi-user.target

# 查看默认目标
systemctl get-default

故障排查

服务启动失败

# 查看详细状态
sudo systemctl status nginx -l

# 查看启动失败原因
sudo systemctl failed

# 查看完整日志
sudo journalctl -u nginx -xe

# 测试单元文件语法
sudo systemd-analyze verify /etc/systemd/system/my.service

启动缓慢排查

# 查看启动时间分析
systemd-analyze
systemd-analyze critical-chain
systemd-analyze plot > boot.svg  # 生成启动时间图

常用命令速查

命令说明
systemctl start启动服务
systemctl stop停止服务
systemctl restart重启服务
systemctl reload重载配置
systemctl status查看状态
systemctl enable开机自启
systemctl disable禁用自启
systemctl daemon-reload重载配置
systemctl list-dependencies查看依赖
journalctl -u查看服务日志
journalctl -f实时日志
systemctl --failed查看失败服务