Skip to content

服务管理

本章将介绍 Linux 服务管理,包括 systemd 服务管理器、服务配置、开机启动、日志管理以及定时任务等内容。

systemd 概述

什么是 systemd?

systemd 是现代 Linux 系统的初始化系统和服务管理器,负责启动系统和管理服务。

mermaid
graph TD
    A[systemd] --> B[服务管理]
    A --> C[套接字管理]
    A --> D[设备管理]
    A --> E[挂载点管理]
    A --> F[定时器管理]
    A --> G[日志管理]

systemd 组件

组件功能
systemctl服务管理命令
journalctl日志管理命令
systemd-analyze启动分析
hostnamectl主机名管理
timedatectl时间日期管理
localectl区域设置管理
loginctl登录会话管理

systemctl 基本操作

服务管理

bash
# systemctl - 服务管理命令

# 启动服务
sudo systemctl start nginx

# 停止服务
sudo systemctl stop nginx

# 重启服务
sudo systemctl restart nginx

# 重新加载配置
sudo systemctl reload nginx

# 查看服务状态
sudo systemctl status nginx

# 查看是否运行
sudo systemctl is-active nginx

# 查看是否启用开机启动
sudo systemctl is-enabled nginx

# 启用开机启动
sudo systemctl enable nginx

# 禁用开机启动
sudo systemctl disable nginx

# 启用并立即启动
sudo systemctl enable --now nginx

# 禁用并立即停止
sudo systemctl disable --now nginx

# 屏蔽服务(防止启动)
sudo systemctl mask nginx

# 取消屏蔽
sudo systemctl unmask nginx

查看服务

bash
# 列出所有正在运行的服务
systemctl list-units --type=service --state=running

# 列出所有服务(包括未运行的)
systemctl list-units --type=service --all

# 列出已启用的服务
systemctl list-unit-files --type=service --state=enabled

# 列出已禁用的服务
systemctl list-unit-files --type=service --state=disabled

# 查看失败的服务
systemctl list-units --type=service --state=failed

# 查看服务详细信息
systemctl show nginx

# 查看特定属性
systemctl show nginx -p ActiveState
systemctl show nginx -p MainPID

# 查看服务依赖
systemctl list-dependencies nginx

# 查看反向依赖
systemctl list-dependencies nginx --reverse

系统管理

bash
# 重启系统
sudo systemctl reboot

# 关机
sudo systemctl poweroff

# 挂起
sudo systemctl suspend

# 休眠
sudo systemctl hibernate

# 混合休眠
sudo systemctl hybrid-sleep

# 救援模式
sudo systemctl rescue

# 紧急模式
sudo systemctl emergency

# 切换运行级别
sudo systemctl isolate multi-user.target    # 多用户模式
sudo systemctl isolate graphical.target     # 图形模式

# 查看默认目标
systemctl get-default

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

服务单元文件

单元文件位置

bash
# 系统单元文件
/usr/lib/systemd/system/    # 软件包安装的单元文件
/lib/systemd/system/        # 同上(软链接)

# 系统配置覆盖
/etc/systemd/system/        # 管理员自定义的单元文件

# 运行时单元文件
/run/systemd/system/        # 运行时动态生成的单元文件

# 用户单元文件
~/.config/systemd/user/     # 用户自定义的单元文件
/usr/lib/systemd/user/      # 系统提供的用户单元文件

# 查看单元文件路径
systemctl show --property=UnitPath

# 查看单元文件位置
systemctl status nginx | grep "Loaded"

服务单元文件结构

bash
# /etc/systemd/system/myapp.service

[Unit]
Description=My Application Service    # 服务描述
Documentation=https://example.com/docs    # 文档链接
After=network.target    # 在 network.target 之后启动
Before=nginx.service    # 在 nginx.service 之前启动
Requires=mysql.service    # 依赖 mysql.service
Wants=redis.service    # 期望 redis.service(非必须)
Conflicts=apache2.service    # 冲突的服务

[Service]
Type=simple    # 服务类型
User=www-data    # 运行用户
Group=www-data    # 运行组
WorkingDirectory=/var/www/myapp    # 工作目录
Environment="NODE_ENV=production"    # 环境变量
EnvironmentFile=/etc/myapp/config.env    # 环境变量文件

ExecStart=/usr/bin/node /var/www/myapp/app.js    # 启动命令
ExecStartPre=/usr/bin/node /var/www/myapp/migrate.js    # 启动前执行
ExecStartPost=/usr/bin/echo "Service started"    # 启动后执行
ExecStop=/usr/bin/node /var/www/myapp/shutdown.js    # 停止命令
ExecReload=/bin/kill -HUP $MAINPID    # 重载命令

Restart=on-failure    # 重启策略
RestartSec=5    # 重启间隔
TimeoutStartSec=30    # 启动超时
TimeoutStopSec=30    # 停止超时

PIDFile=/run/myapp.pid    # PID 文件
StandardOutput=journal    # 标准输出
StandardError=journal    # 标准错误

LimitNOFILE=65535    # 文件描述符限制
LimitNPROC=4096    # 进程数限制

PrivateTmp=true    # 私有临时目录
NoNewPrivileges=true    # 禁止提升权限

[Install]
WantedBy=multi-user.target    # 安装到哪个目标

服务类型

bash
# Type=simple(默认)
# 服务进程作为主进程运行,ExecStart 启动的进程就是守护进程

# Type=forking
# 服务会 fork 子进程,父进程退出,子进程作为守护进程
# 需要指定 PIDFile

# Type=oneshot
# 服务执行一次性任务后退出
# 适合执行脚本、备份等任务

# Type=notify
# 服务启动完成后会发送通知
# 需要 sd_notify 支持

# Type=dbus
# 服务通过 D-Bus 启动
# 需要指定 BusName

# Type=idle
# 等待所有任务完成后启动

重启策略

bash
# Restart=no(默认)
# 不自动重启

# Restart=on-success
# 仅当服务正常退出时重启

# Restart=on-failure
# 当服务异常退出时重启

# Restart=on-abnormal
# 当服务被信号终止、超时等异常情况时重启

# Restart=on-watchdog
# 当看门狗超时时重启

# Restart=on-abort
# 当服务收到 SIGABRT 信号时重启

# Restart=always
# 总是重启

创建自定义服务

bash
# 创建服务文件
sudo vim /etc/systemd/system/myapp.service

[Unit]
Description=My Application
After=network.target

[Service]
Type=simple
User=myuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/start.sh
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

# 重新加载 systemd
sudo systemctl daemon-reload

# 启用并启动服务
sudo systemctl enable --now myapp

# 查看状态
sudo systemctl status myapp

修改现有服务

bash
# 方法一:创建 drop-in 配置文件
sudo systemctl edit nginx

# 创建的文件位于:/etc/systemd/system/nginx.service.d/override.conf

# 示例:修改重启策略
[Service]
Restart=always
RestartSec=10

# 方法二:复制并修改
sudo cp /usr/lib/systemd/system/nginx.service /etc/systemd/system/
sudo vim /etc/systemd/system/nginx.service

# 重新加载
sudo systemctl daemon-reload
sudo systemctl restart nginx

日志管理

journalctl 基本使用

bash
# journalctl - 查看 systemd 日志

# 查看所有日志
journalctl

# 查看最新日志并持续输出
journalctl -f

# 查看指定数量的日志
journalctl -n 100

# 查看今天的日志
journalctl --since today

# 查看指定时间范围的日志
journalctl --since "2024-01-15 00:00:00" --until "2024-01-15 23:59:59"
journalctl --since "1 hour ago"
journalctl --since yesterday

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

# 查看多个服务的日志
journalctl -u nginx -u mysql

# 查看指定优先级的日志
journalctl -p err    # 错误级别
# 优先级:emerg, alert, crit, err, warning, notice, info, debug

# 查看内核日志
journalctl -k

# 查看指定用户的日志
journalctl _UID=1000

# 查看指定进程的日志
journalctl _PID=1234

# 显示详细信息
journalctl -o verbose

# JSON 格式输出
journalctl -o json

# 只显示消息
journalctl -o cat

# 反向输出(最新的在前)
journalctl -r

日志持久化

bash
# 默认日志存储在 /run/log/journal(重启后丢失)
# 持久化存储在 /var/log/journal

# 创建持久化目录
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald

# 日志配置文件
/etc/systemd/journald.conf

# 主要配置项:
# Storage=auto        # auto/persistent/volatile/none
# Compress=yes        # 压缩
# Seal=yes            # 密封
# SplitMode=uid       # 分割模式
# RateLimitIntervalSec=30s    # 速率限制
# RateLimitBurst=1000         # 突发限制
# SystemMaxUse=4G     # 最大使用空间
# SystemMaxFileSize=128M      # 单文件最大大小
# MaxRetentionSec=1month      # 最大保留时间

# 查看日志使用情况
journalctl --disk-usage

# 清理日志(保留最近的大小)
sudo journalctl --vacuum-size=1G

# 清理日志(保留最近的时间)
sudo journalctl --vacuum-time=7d

# 验证日志文件
journalctl --verify

rsyslog 日志

bash
# rsyslog - 传统日志服务

# 配置文件
/etc/rsyslog.conf
/etc/rsyslog.d/

# 常见日志文件
/var/log/syslog       # 系统日志(Debian/Ubuntu)
/var/log/messages     # 系统日志(RHEL/CentOS)
/var/log/auth.log     # 认证日志(Debian/Ubuntu)
/var/log/secure       # 认证日志(RHEL/CentOS)
/var/log/kern.log     # 内核日志
/var/log/cron         # 定时任务日志
/var/log/mail.log     # 邮件日志

# 查看日志
tail -f /var/log/syslog
less /var/log/auth.log

# 日志轮转配置
/etc/logrotate.conf
/etc/logrotate.d/

# 手动轮转
sudo logrotate -f /etc/logrotate.conf

# 查看日志轮转状态
cat /var/lib/logrotate/status

定时任务

systemd timer

bash
# systemd timer - 现代定时任务

# 创建服务文件 /etc/systemd/system/backup.service
[Unit]
Description=Backup Service

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

# 创建定时器文件 /etc/systemd/system/backup.timer
[Unit]
Description=Backup Timer

[Timer]
OnCalendar=daily    # 每天执行
# OnCalendar=*-*-* 02:00:00    # 每天凌晨2点
# OnCalendar=weekly    # 每周
# OnCalendar=monthly    # 每月
# OnCalendar=hourly    # 每小时
# OnBootSec=5min    # 启动后5分钟
# OnUnitActiveSec=1h    # 服务运行后1小时
Persistent=true    # 错过的任务会在启动后执行

[Install]
WantedBy=timers.target

# 启用定时器
sudo systemctl enable --now backup.timer

# 查看定时器
systemctl list-timers

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

# 查看定时器详情
systemctl status backup.timer

cron 定时任务

bash
# cron - 传统定时任务

# 查看服务状态
sudo systemctl status cron
sudo systemctl status crond

# 编辑当前用户的定时任务
crontab -e

# 查看当前用户的定时任务
crontab -l

# 删除当前用户的定时任务
crontab -r

# 编辑指定用户的定时任务
sudo crontab -e -u username

# 系统级定时任务
/etc/crontab
/etc/cron.d/
/etc/cron.hourly/
/etc/cron.daily/
/etc/cron.weekly/
/etc/cron.monthly/

# cron 表达式格式
# 分钟(0-59) 小时(0-23) 日(1-31) 月(1-12) 星期(0-7) 命令
# 星期:0和7都表示周日

# 示例
# 每天凌晨2点执行
0 2 * * * /opt/backup/backup.sh

# 每小时执行
0 * * * * /opt/scripts/hourly.sh

# 每5分钟执行
*/5 * * * * /opt/scripts/check.sh

# 每周一早上8点执行
0 8 * * 1 /opt/scripts/weekly.sh

# 每月1号凌晨执行
0 0 1 * * /opt/scripts/monthly.sh

# 工作日早上9点执行
0 9 * * 1-5 /opt/scripts/workday.sh

# 特殊字符
# * - 任意值
# , - 列表分隔符
# - - 范围
# / - 步长

# 输出重定向
0 2 * * * /opt/backup/backup.sh >> /var/log/backup.log 2>&1

# 使用环境变量
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
MAILTO=admin@example.com

0 2 * * * /opt/backup/backup.sh

anacron

bash
# anacron - 适合非持续运行的系统

# 配置文件
/etc/anacrontab

# 格式
# 周期(天)  延迟(分钟)  任务标识  命令

# 示例
1       5       cron.daily      nice run-parts /etc/cron.daily
7       25      cron.weekly     nice run-parts /etc/cron.weekly
@monthly 45     cron.monthly    nice run-parts /etc/cron.monthly

# 查看任务时间戳
ls /var/spool/anacron/

# 手动运行
sudo anacron -f    # 强制运行所有任务
sudo anacron -u    # 更新时间戳但不运行

系统资源管理

cgroups

bash
# cgroups - 控制组,限制和监控进程资源

# 查看 cgroups
cat /proc/cgroups

# systemd 使用 cgroups 管理服务
systemd-cgls    # 查看 cgroup 树
systemd-cgtop   # 实时查看 cgroup 资源使用

# 在服务单元中设置资源限制
[Service]
MemoryMax=1G           # 最大内存
MemoryHigh=800M        # 内存高水位
CPUQuota=50%           # CPU 配额
CPUShares=512          # CPU 权重
IOReadBandwidthMax=/dev/sda 10M    # 读带宽限制
IOWriteBandwidthMax=/dev/sda 10M   # 写带宽限制

# 使用 systemctl 设置资源限制
sudo systemctl set-property nginx.service MemoryMax=512M
sudo systemctl set-property nginx.service CPUQuota=50%

资源监控

bash
# 查看系统资源使用
systemd-cgtop

# 查看服务资源使用
systemctl show nginx -p MemoryCurrent
systemctl show nginx -p CPUUsageNSec

# 查看系统状态
systemd-analyze

# 查看启动时间
systemd-analyze time

# 查看启动过程
systemd-analyze blame

# 查看启动依赖图
systemd-analyze plot > boot.svg

# 查看关键链
systemd-analyze critical-chain

小结

本章介绍了 Linux 服务管理:

内容命令功能
服务管理systemctl启动、停止、重启服务
日志管理journalctl查看系统日志
定时任务systemd.timer, cron定时执行任务
资源管理cgroups限制进程资源

常用命令速查

bash
# 服务管理
sudo systemctl start nginx       # 启动服务
sudo systemctl stop nginx        # 停止服务
sudo systemctl status nginx      # 查看状态
sudo systemctl enable nginx      # 开机启动

# 日志查看
journalctl -u nginx              # 查看服务日志
journalctl -f                    # 实时日志
journalctl --since today         # 今天的日志

# 定时任务
crontab -e                       # 编辑定时任务
crontab -l                       # 查看定时任务
systemctl list-timers            # 查看 systemd 定时器

下一步

下一章我们将学习 安全配置,了解 Linux 系统安全加固。