systemd是现代Linux发行版的默认初始化系统和服务管理器,取代了传统的SysV init。掌握systemd服务单元配置是服务器运维和Linux系统管理的核心技能。从服务依赖管理、资源限制到日志收集,systemd提供了一套完整的声明式服务管理框架,支撑着从单机到高可用集群的基础设施运行。
systemd Unit单元类型与服务管理基础
systemd通过Unit单元文件定义各类资源,常用类型包括:
- .service:系统服务(守护进程),使用最频繁
- .target:服务组,用于定义启动层级和依赖关系
- .timer:定时任务单元,替代crontab
- .socket:套接字激活单元,实现按需启动
- .mount:文件系统挂载单元
# 服务管理常用命令
systemctl start nginx # 启动服务
systemctl stop nginx # 停止服务
systemctl restart nginx # 重启服务
systemctl reload nginx # 重载配置(不中断连接)
systemctl status nginx # 查看运行状态
systemctl enable nginx # 设置开机自启动
systemctl disable nginx # 取消开机自启动
systemctl is-enabled nginx # 检查是否启用自启动
systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service --state=enabled
Service单元文件结构与核心指令详解
自定义服务需要创建单元文件,目录优先级从高到低为:
- /etc/systemd/system/(管理员自定义,优先级最高)
- /run/systemd/system/(运行时临时单元)
- /usr/lib/systemd/system/(软件包安装的默认单元)
完整的service单元文件包含三个主要段落:
[Unit]
Description=My Application Server
Documentation=https://example.com/docs
After=network-online.target
Wants=network-online.target
Conflicts=old-app.service
[Service]
Type=notify
ExecStart=/opt/myapp/bin/server --config /etc/myapp/config.yaml
ExecStartPre=/opt/myapp/bin/migrate.sh
ExecStop=/usr/bin/kill -SIGTERM $MAINPID
ExecReload=/usr/bin/kill -SIGHUP $MAINPID
Restart=on-failure
RestartSec=5s
TimeoutStartSec=60
TimeoutStopSec=30
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
Environment=NODE_ENV=production
Environment=MAX_CONNECTIONS=1000
EnvironmentFile=/etc/myapp/env
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Type指令与服务生命周期管理
Type指令决定systemd如何判断服务启动完成,是最关键的配置项:
- Type=simple(默认):ExecStart启动的进程即主进程,systemd立即认为启动完成
- Type=forking:进程会fork子进程并退出父进程,systemd通过PIDFile跟踪主进程
- Type=notify:服务通过sd_notify()发送READY=1信号通知systemd启动完成
- Type=exec:systemd在ExecStart执行成功后认为启动完成
- Type=oneshot:一次性任务,配合RemainAfterExit=yes可保持active
# 配置notify类型服务(需代码中调用sd_notify)
from systemd import daemon
daemon.notify('READY=1') # 启动完成通知
daemon.notify('WATCHDOG=1') # 心跳
daemon.notify('STATUS=Processing batch job #42') # 自定义状态
Restart策略与故障自恢复配置
生产环境中服务的故障自恢复能力至关重要:
[Service]
Restart=on-failure
# always: 总是重启(包括正常退出)
# on-failure: 非正常退出时重启
# on-abnormal: 仅信号终止或超时时重启
# on-watchdog: 看门狗超时时重启
RestartSec=5s
StartLimitBurst=5
StartLimitIntervalSec=300
[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5
当服务在StartLimitIntervalSec时间内重启次数超过StartLimitBurst时,systemd会停止重启并标记为failed状态。需要执行systemctl reset-failed清除状态后才能重新启动。
资源限制与cgroups集成
systemd原生集成cgroups v2,可以直接在单元文件中限制服务资源:
[Service]
CPUQuota=200% # 限制使用2个CPU核心
CPUWeight=500 # CPU权重(默认100)
MemoryMax=2G # 内存硬上限
MemoryHigh=1500M # 内存软上限
MemorySwapMax=512M # Swap使用上限
IOWeight=500
IOReadBandwidthMax=/dev/sda 50M
IOWriteBandwidthMax=/dev/sda 20M
TasksMax=512
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
# 查看服务资源使用情况
systemctl status myapp.service
# 查看cgroup层级
systemd-cgls | grep myapp
systemd-cgtop
# 运行时修改资源限制(不重启服务)
systemctl set-property myapp.service CPUQuota=300%
systemctl set-property myapp.service MemoryMax=4G
Timer定时任务单元替代crontab
systemd timer比crontab提供更精确的时间控制和依赖管理:
# /etc/systemd/system/myapp-backup.timer
[Unit]
Description=Daily Database Backup Timer
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
# /etc/systemd/system/myapp-backup.service
[Unit]
Description=Database Backup Service
[Service]
Type=oneshot
ExecStart=/opt/myapp/scripts/backup.sh
User=root
Nice=10
# 启用timer定时任务
systemctl daemon-reload
systemctl enable --now myapp-backup.timer
# 查看所有定时任务
systemctl list-timers --all
# 查看下次执行时间
systemctl list-timers myapp-backup.timer
日志管理与journalctl查询技巧
# 查看指定服务日志
journalctl -u myapp.service
# 实时跟踪日志
journalctl -u myapp.service -f
# 时间范围过滤
journalctl -u myapp.service --since "2026-08-15 10:00" --until "2026-08-15 12:00"
journalctl -u myapp.service --since "1 hour ago"
# 按优先级过滤(0-7,0为最高)
journalctl -u myapp.service -p err
# 查看上一次启动的日志
journalctl -u myapp.service -b -1
# 导出JSON格式
journalctl -u myapp.service -o json --since today
# 磁盘空间管理
journalctl --disk-usage
journalctl --vacuum-size=500M
journalctl --vacuum-time=7d
常见故障排查与调试
# 服务启动失败时查看详细错误
systemctl status myapp.service
journalctl -u myapp.service --no-pager -n 50
# 检查单元文件语法
systemd-analyze verify /etc/systemd/system/myapp.service
# 启动耗时分析
systemd-analyze blame
systemd-analyze critical-chain myapp.service
# 依赖关系
systemctl list-dependencies myapp.service
systemctl list-dependencies --reverse myapp.service
# 调试模式
SYSTEMD_LOG_LEVEL=debug systemctl start myapp.service
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linuxsystemd-fu-wu-dan-yuan-pei-zhi-yu-kai-ji-zi-qi-dong/