Linux服务器systemd服务单元配置与cgroups资源限制实战

systemd是现代Linux发行版的标准初始化系统,承担进程管理、服务编排、日志收集和资源控制职责。服务器运维中,通过systemd服务单元管理应用进程比传统supervisor或nohup方案更可靠。结合cgroups资源限制,可实现CPU、内存、IO的精细化管控。本文以Linux系统管理实战为切入点,覆盖systemd单元配置、cgroups资源配额、服务依赖管理和日志轮转等核心场景。

systemd服务单元文件结构与配置详解

服务单元文件位于/etc/systemd/system/目录,扩展名.service。一个完整的单元文件包含[Unit]、[Service]、[Install]三个主要段:

[Unit]
Description=Order Processing Service
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service

[Service]
Type=simple
User=appuser
Group=appgroup
WorkingDirectory=/opt/order-service
ExecStart=/usr/bin/java -jar order-service.jar --spring.profiles.active=prod
ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s

# 资源限制
MemoryMax=4G
MemoryHigh=3G
CPUQuota=200%
TasksMax=512
LimitNOFILE=65536

# 安全加固
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/order-service/logs

# 环境变量
Environment="JAVA_OPTS=-Xms2g -Xmx3g"
EnvironmentFile=/etc/order-service/env.conf

[Install]
WantedBy=multi-user.target

Type字段决定服务启动行为。Type=simple表示ExecStart启动的进程即为主进程,systemd立即认为服务已启动。Type=forking适用于daemon进程,systemd等待子进程fork后父进程退出才认为启动完成。Type=notify要求服务通过sd_notify接口主动通知systemd就绪状态,适用于支持该接口的应用。

cgroups资源控制参数配置

systemd v2集成了cgroups v2资源控制接口。常用资源限制参数:

# CPU控制
CPUQuota=150%          # 限制使用1.5个CPU核心
CPUWeight=512          # CPU权重,默认100,范围1-10000
CPUQuotaPeriodSec=100ms # 调度周期

# 内存控制
MemoryMax=4G           # 硬上限,超出触发OOM Kill
MemoryHigh=3G          # 软上限,超出后开始回收
MemorySwapMax=1G       # swap使用上限
MemoryPressureWatch=on # 内存压力监控

# IO控制
IOWeight=500           # IO权重
IOReadBandwidthMax=/dev/sda 100M
IOWriteBandwidthMax=/dev/sda 50M

# 进程数限制
TasksMax=512           # 最大进程/线程数

验证资源配置是否生效:

# 查看服务cgroups
systemctl status order-service

# 查看实际资源使用
systemd-cgls --unit=order-service

# 实时监控
systemd-cgtop

# 手动调整运行时配置
systemctl set-property order-service CPUQuota=250%
systemctl set-property order-service MemoryMax=6G

服务依赖管理与启动顺序控制

After/Before定义启动顺序,Requires/Wants定义依赖关系。两者区别在于:Requires是硬依赖,依赖服务启动失败则本服务不启动;Wants是软依赖,依赖失败不影响本服务启动。

对于需要远程数据库的服务,推荐配置PartOf和BindsTo实现联动重启:

[Unit]
PartOf=postgresql.service
BindsTo=postgresql.service
After=postgresql.service

[Service]
ExecStartPre=/usr/bin/pg_isready -h 127.0.0.1 -p 5432
ExecStartPre=/opt/scripts/wait-for-db.sh
ExecStart=/usr/bin/java -jar order-service.jar

ExecStartPre按顺序执行,前一个失败则后续不执行,服务启动中止。适合做前置健康检查。

systemd日志收集与日志轮转配置

journald是systemd的日志收集组件,替代传统syslog。应用通过stdout/stderr输出的日志自动被journald收集。配置文件/etc/systemd/journald.conf:

[Journal]
Storage=persistent          # 持久化存储到/var/log/journal
Compress=yes                 # 压缩旧日志
MaxRetentionSec=30day        # 保留30天
MaxFileSec=7day              # 每个文件最大7天
RateLimitIntervalSec=30s     # 限流间隔
RateLimitBurst=10000         # 限流阈值
SystemMaxUse=2G              # 系统日志最大占用2G
SystemMaxFileSize=100M       # 单个文件最大100M

查询日志的常用命令:

# 查看指定服务日志
journalctl -u order-service -f

# 按时间范围查询
journalctl -u order-service --since "2026-08-20 09:00" --until "2026-08-20 12:00"

# 按优先级过滤
journalctl -u order-service -p err

# 查看内核日志
journalctl -k --since today

# 导出日志
journalctl -u order-service --since today -o json > /tmp/order-logs.json

生产环境服务管理最佳实践

Restart策略选择:on-failure仅异常退出时重启,always无论退出码都重启。生产环境推荐on-failure配合RestartSec=5s,避免崩溃循环。对于已知可能非零退出的场景,使用RestartPreventExitStatus指定不重启的退出码。

资源限制的渐进式调优方法:先不设限制运行,通过systemd-cgtop观察实际资源使用峰值。MemoryMax设为峰值的1.2倍,MemoryHigh设为峰值的0.9倍。CPUQuota根据服务优先级分配,核心业务设200%-300%,辅助任务设50%-100%。

安全加固方面,ProtectSystem=strict配合ReadWritePaths只开放必要写入路径,防止服务进程篡改系统文件。NoNewPrivileges=true阻止服务进程通过setuid提权。PrivateTmp=true隔离/tmp目录,避免与其他服务共享临时文件。

配置变更后执行systemctl daemon-reload重载单元文件,再执行systemctl restart生效。频繁修改时可使用systemctl edit order-service创建override文件,不改动原始单元文件,便于版本管理和回滚。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/linux-fu-wu-qi-systemd-fu-wu-dan-yuan-pei-zhi-yu-cgroups-zi/

(0)
小编小编
上一篇 8小时前
下一篇 8小时前

相关推荐