systemd是现代Linux发行版(CentOS 7+、Ubuntu 16.04+、Debian 8+)默认的初始化系统和服务管理器,取代了传统的SysVinit和Upstart。systemd通过并行启动、依赖管理和cgroup资源控制,显著提升系统启动速度和服务管理效率。本文详解systemd服务单元(unit)配置方法、启动流程管理及常见运维操作。
systemd服务单元类型与目录结构
systemd管理多种类型的单元文件,常见类型包括:
.service — 服务单元,管理系统进程
.target — 目标单元,用于分组管理多个单元
.timer — 定时器单元,替代cron任务
.socket — 套接字单元,实现基于socket的服务激活
.mount — 挂载单元,管理文件系统挂载
单元文件存放位置(优先级从高到低):
/etc/systemd/system/ — 管理员手动配置,优先级最高
/run/systemd/system/ — 运行时生成的单元
/usr/lib/systemd/system/ — 软件包安装的默认单元
同名文件在高优先级目录会覆盖低优先级目录中的版本。自定义服务建议放在/etc/systemd/system/目录下。
Service单元文件配置字段详解
一个完整的service单元文件包含三个主要配置段:[Unit]、[Service]、[Install]。
[Unit]
Description=Nginx Web Server
Documentation=https://nginx.org/en/docs/
After=network-online.target
Wants=network-online.target
Conflicts=apache2.service
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/usr/sbin/nginx -s stop
Restart=on-failure
RestartSec=5s
TimeoutStartSec=30
TimeoutStopSec=30
# 资源限制
LimitNOFILE=65535
LimitNPROC=65535
# cgroup资源控制
MemoryMax=2G
CPUQuota=200%
TasksMax=512
# 安全加固
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/log/nginx /var/cache/nginx /run
# 工作目录与用户
WorkingDirectory=/etc/nginx
User=nginx
Group=nginx
[Install]
WantedBy=multi-user.target
Type字段服务类型与启动行为
Type字段决定systemd如何判断服务是否启动成功,直接影响后续服务的并行启动:
Type=simple(默认):ExecStart启动的进程即为服务主进程,systemd立即认为服务启动成功。适用于前台运行的进程。
Type=forking:ExecStart启动的进程会fork子进程并退出,systemd通过PIDFile跟踪子进程。适用于传统守护进程如Nginx、MySQL。
Type=oneshot:服务执行一次性任务后退出,systemd等待ExecStart完成后才继续启动依赖此服务的单元。配合RemainAfterExit=yes可使服务状态显示为active。
Type=notify:服务通过sd_notify()接口向systemd发送就绪通知。需要服务代码集成systemd通知机制,启动最精确。
Type=idle:类似simple,但等到所有任务输出完成后才启动,避免日志混合。不推荐用于关键服务。
服务依赖关系管理
systemd通过After/Before、Requires、Wants、BindsTo等字段管理单元间依赖关系。
After/Before:定义启动顺序,但不强制依赖。After=network.target表示在网络target之后启动,但即使网络target启动失败,服务仍会尝试启动。
Requires:强依赖关系,被依赖的单元启动失败则当前单元也启动失败。但不会因被依赖单元停止而停止当前单元。
Wants:弱依赖关系,被依赖单元失败不影响当前单元启动。推荐使用Wants代替Requires,避免级联失败。
BindsTo:最强依赖,被依赖单元停止时当前单元也停止。
Requisite:被依赖单元必须已启动,否则当前单元不会启动(不做启动操作)。
systemctl命令实战操作
服务管理常用命令:
# 启动/停止/重启/重载服务
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl reload nginx
# 查看服务状态
systemctl status nginx
systemctl is-active nginx
systemctl is-enabled nginx
systemctl is-failed nginx
# 设置开机自启
systemctl enable nginx
systemctl disable nginx
systemctl enable --now nginx # 启动并设置自启
# 查看服务日志
journalctl -u nginx -f # 实时跟踪日志
journalctl -u nginx --since today
journalctl -u nginx -p err # 只看错误级别
journalctl -u nginx -o json # JSON格式输出
# 列出所有服务
systemctl list-units --type=service
systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service --state=enabled
# 重载修改后的单元文件
systemctl daemon-reload
systemd资源限制与cgroup集成
systemd原生集成cgroup v2资源控制,在[Service]段中直接配置资源限制:
[Service]
# CPU限制:单核200%即两个核
CPUQuota=200%
CPUWeight=1024
# 内存限制
MemoryMax=2G
MemoryHigh=1536M # 软限制,超过后开始回收
MemorySwapMax=512M
# 进程数限制
TasksMax=512
# IO限制
IOReadBandwidthMax=/dev/sda 50M
IOWriteBandwidthMax=/dev/sda 20M
IOWeight=500
# 块设备IO限制(cgroup v2)
IODeviceWeight=/dev/sda 500
查看服务的cgroup资源使用情况:
systemctl status nginx
# 输出中的CGroup字段显示资源使用量
systemd-cgls # 查看所有cgroup树
systemd-cgtop # 实时cgroup资源监控
systemd定时器替代cron任务
systemd timer比cron更精确,支持秒级触发、日志记录和依赖管理。
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily Database Backup Timer
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=300
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
[Unit]
Description=Database Backup Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-db.sh
systemctl enable --now backup.timer
systemctl list-timers --all
systemctl status backup.timer
OnCalendar支持多种时间格式:OnCalendar=hourly(每小时)、OnCalendar=weekly(每周)、OnCalendar=Mon *-*-* 09:00:00(每周一9点)。Persistent=true表示错过的任务在系统启动后补执行。RandomizedDelaySec避免多个定时任务同时执行造成资源峰值。
系统启动流程分析与优化
systemd并行启动机制使系统启动时间大幅缩短。分析启动耗时:
# 查看整体启动时间
systemd-analyze time
# 查看各服务启动耗时(按时间排序)
systemd-analyze blame | head -20
# 生成启动流程图
systemd-analyze plot > startup.svg
# 查看关键路径
systemd-analyze critical-chain
优化启动时间的常见方法:
1. 禁用不必要的服务:systemctl disable bluetooth.service
2. 将Type=forking改为Type=notify或Type=simple,减少等待时间
3. 使用socket激活,延迟服务实际启动到首次请求时
4. 调整After/Before依赖关系,减少串行等待
systemd通过cgroup资源控制、并行启动和精确的依赖管理,为Linux服务运维提供了完整的解决方案。掌握service单元配置和systemctl操作,是现代Linux服务器管理的基础技能。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linuxsystemd-fu-wu-dan-yuan-pei-zhi-xiang-jie-yu-xi-tong-qi/