简介
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 | 主进程即为服务(默认) |
exec | ExecStart 执行后才是服务 |
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 | 查看失败服务 |