服务与系统管理¶
📌 学习时间:2-3天 📌 难度级别:⭐⭐⭐ 中级 📌 前置知识:Linux基础、进程管理
📚 章节概述¶
服务管理和系统调优是 Linux 运维的核心工作。本章深入讲解 systemd 服务管理体系、Crontab 定时任务、日志系统(syslog/rsyslog/logrotate)、init 系统对比、开机自启动配置以及系统性能调优基础。
🎯 学习目标¶
- 深入理解 systemd 体系(systemctl/journalctl)
- 掌握 Crontab 定时任务配置
- 理解日志系统(syslog/rsyslog/logrotate)
- 了解 SysVinit vs systemd 的区别
- 掌握开机自启动配置
- 了解系统性能调优基础
📖 1. systemd 详解¶
1.1 systemd 概述¶
Bash
# systemd 是现代 Linux 的标准 init 系统(PID=1)
# 取代了传统的 SysVinit 和 Upstart
# systemd 的核心概念:Unit(单元)
# 常见 Unit 类型:
# .service — 服务(最常用)
# .socket — 套接字激活
# .timer — 定时器(替代 cron)
# .mount — 挂载点
# .target — 目标(类似运行级别)
# .path — 路径监控
# .slice — 资源控制组
# 查看 systemd 版本
systemd --version
1.2 systemctl — 服务管理¶
Bash
# 基本操作
sudo systemctl start nginx # 启动服务
sudo systemctl stop nginx # 停止服务
sudo systemctl restart nginx # 重启服务
sudo systemctl reload nginx # 重新加载配置(不中断服务)
sudo systemctl status nginx # 查看服务状态
# 输出示例:
# ● nginx.service - A high performance web server
# Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
# Active: active (running) since Mon 2024-01-15 10:30:00 CST; 5h ago
# Main PID: 1234 (nginx)
# Tasks: 3
# Memory: 15.0M
# CGroup: /system.slice/nginx.service
# ├─1234 nginx: master process
# ├─1235 nginx: worker process
# └─1236 nginx: worker process
# 开机自启动
sudo systemctl enable nginx # 开机自启
sudo systemctl disable nginx # 取消自启
sudo systemctl enable --now nginx # 启动并设置自启
sudo systemctl is-enabled nginx # 检查是否自启
# 查看服务列表
systemctl list-units --type=service # 活动的服务
systemctl list-units --type=service --all # 所有服务
systemctl list-units --type=service --state=running # 运行中的
systemctl list-units --type=service --state=failed # 失败的
systemctl list-unit-files --type=service # 所有服务文件
# 查看服务依赖
systemctl list-dependencies nginx
systemctl list-dependencies nginx --reverse # 被谁依赖
# 其他操作
sudo systemctl mask nginx # 彻底禁用(无法启动)
sudo systemctl unmask nginx # 取消禁用
sudo systemctl daemon-reload # 重新加载服务文件(修改后必须执行)
sudo systemctl isolate multi-user.target # 切换到多用户模式
1.3 自定义 systemd 服务¶
Bash
# 创建自定义服务文件
# 注意:不能用 sudo cat > file(重定向在当前Shell执行,没有sudo权限)
# 正确做法是用 sudo tee
sudo tee /etc/systemd/system/myapp.service > /dev/null << 'EOF'
[Unit]
Description=My Application
Documentation=https://example.com/docs
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStartPre=/opt/myapp/check_config.sh
ExecStart=/opt/myapp/bin/myapp --config /etc/myapp/config.yaml
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
# 安全加固
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
PrivateTmp=true
# 环境变量
Environment=NODE_ENV=production
EnvironmentFile=/etc/myapp/env
# 日志
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
[Install]
WantedBy=multi-user.target
EOF
# 重新加载并启动
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp
# Service Type 类型说明
# simple — 默认,ExecStart 的进程就是主进程
# forking — 进程 fork 后主进程退出,需设 PIDFile
# oneshot — 一次性任务(如初始化脚本)
# notify — 服务就绪后通过 sd_notify 通知 systemd
# idle — 等待其他任务完成后才启动
# Restart 策略
# no — 不重启
# on-success — 正常退出时重启
# on-failure — 异常退出时重启(推荐服务使用)
# on-abnormal — 异常信号时重启
# on-abort — abort 信号时重启
# on-watchdog — 看门狗超时时重启
# always — 总是重启
1.4 journalctl — 日志查看¶
Bash
# journalctl 是 systemd 的日志查看工具
# 查看所有日志
journalctl # 所有日志(从旧到新)
journalctl -r # 逆序(最新在前)
journalctl -f # 实时跟踪(类似 tail -f)
# 按服务过滤
journalctl -u nginx # nginx 的日志
journalctl -u nginx --since "1 hour ago" # 最近1小时
journalctl -u nginx -f # 实时跟踪 nginx 日志
# 按时间过滤
journalctl --since "2024-01-15 10:00:00"
journalctl --since "2024-01-15" --until "2024-01-16"
journalctl --since "1 hour ago"
journalctl --since yesterday
journalctl -b # 本次启动的日志
journalctl -b -1 # 上次启动的日志
# 按优先级过滤
journalctl -p err # 错误及以上
journalctl -p warning # 警告及以上
# 优先级(从高到低): emerg, alert, crit, err, warning, notice, info, debug
# 按进程/用户过滤
journalctl _PID=1234
journalctl _UID=1000
journalctl _COMM=sshd
# 输出格式
journalctl -o json # JSON 格式
journalctl -o json-pretty # 格式化 JSON
journalctl -o short-iso # 短格式带 ISO 时间
# 磁盘空间管理
journalctl --disk-usage # 查看日志占用空间
sudo journalctl --vacuum-size=500M # 限制日志大小
sudo journalctl --vacuum-time=30d # 删除30天前的日志
📖 2. Crontab 定时任务¶
2.1 Crontab 格式¶
Bash
# 格式:分 时 日 月 周 命令
# ┌──────── 分钟 (0-59)
# │ ┌────── 小时 (0-23)
# │ │ ┌──── 日 (1-31)
# │ │ │ ┌── 月 (1-12)
# │ │ │ │ ┌ 周几 (0-7, 0和7都是周日)
# │ │ │ │ │
# * * * * * command
# 特殊字符
# * 任意值
# , 多个值(1,3,5)
# - 范围(1-5)
# / 间隔(*/5 = 每5个单位)
# 示例
# 每分钟
* * * * * /path/to/script.sh
# 每小时第30分钟
30 * * * * /path/to/script.sh
# 每天凌晨2点
0 2 * * * /path/to/backup.sh
# 每周一到周五早上9点
0 9 * * 1-5 /path/to/report.sh
# 每月1日凌晨3点
0 3 1 * * /path/to/monthly_task.sh
# 每5分钟
*/5 * * * * /path/to/check.sh
# 每两小时
0 */2 * * * /path/to/task.sh
# 工作日每天9:30和17:30
30 9,17 * * 1-5 /path/to/notify.sh
# 特殊时间标记
@reboot /path/to/startup.sh # 开机执行
@yearly /path/to/annual.sh # 每年(0 0 1 1 *)
@monthly /path/to/monthly.sh # 每月(0 0 1 * *)
@weekly /path/to/weekly.sh # 每周(0 0 * * 0)
@daily /path/to/daily.sh # 每天(0 0 * * *)
@hourly /path/to/hourly.sh # 每小时(0 * * * *)
2.2 Crontab 管理¶
Bash
# 编辑当前用户的 crontab
crontab -e
# 查看当前用户的 crontab
crontab -l
# 删除当前用户的 crontab(危险!)
crontab -r
# 编辑其他用户的 crontab(需要root)
sudo crontab -u alice -e
sudo crontab -u alice -l
# 系统级 crontab
cat /etc/crontab
ls /etc/cron.d/ # 系统 cron 配置目录
ls /etc/cron.daily/ # 每天执行的脚本
ls /etc/cron.weekly/ # 每周执行的脚本
ls /etc/cron.monthly/ # 每月执行的脚本
# Crontab 最佳实践
# 1. 使用绝对路径
0 2 * * * /usr/bin/python3 /opt/myapp/task.py
# 2. 设置环境变量
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
MAILTO=admin@example.com
# 3. 记录日志
0 2 * * * /opt/backup.sh >> /var/log/backup.log 2>&1
# 4. 避免重复执行(使用 flock)
*/5 * * * * /usr/bin/flock -n /tmp/task.lock /opt/task.sh
# 5. 任务超时控制
0 2 * * * timeout 3600 /opt/long_task.sh
2.3 systemd Timer(Crontab 替代方案)¶
Bash
# systemd timer 可以替代 crontab,功能更强大
# 1. 创建服务文件(定义要执行的任务)
sudo tee /etc/systemd/system/backup.service > /dev/null << 'EOF'
[Unit]
Description=Daily Backup
[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
User=root
EOF
# 2. 创建 timer 文件
sudo tee /etc/systemd/system/backup.timer > /dev/null << 'EOF'
[Unit]
Description=Run backup daily at 2am
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
EOF
# 3. 启用 timer
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
# 查看 timer 状态
systemctl list-timers --all
systemctl status backup.timer
# Timer 时间格式示例
# OnCalendar=hourly 每小时
# OnCalendar=daily 每天
# OnCalendar=weekly 每周
# OnCalendar=*-*-* 02:00:00 每天2点
# OnCalendar=Mon *-*-* 09:00:00 每周一9点
# OnCalendar=*-*-01 03:00:00 每月1号3点
📖 3. 日志系统¶
3.1 syslog / rsyslog¶
Bash
# rsyslog 是 syslog 的增强版,是大多数发行版默认的日志守护进程
# 配置文件
/etc/rsyslog.conf
/etc/rsyslog.d/*.conf
# 日志文件位置
/var/log/syslog # 系统日志(Ubuntu)
/var/log/messages # 系统日志(CentOS)
/var/log/auth.log # 认证日志(Ubuntu)
/var/log/secure # 认证日志(CentOS)
/var/log/kern.log # 内核日志
/var/log/dmesg # 启动日志
/var/log/cron # cron 日志(CentOS)
/var/log/mail.log # 邮件日志
/var/log/nginx/ # Nginx 日志
/var/log/mysql/ # MySQL 日志
# rsyslog 配置格式
# 设施.优先级 动作
# facility.priority action
# Facility(设施):
# auth, authpriv, cron, daemon, kern, lpr, mail,
# news, syslog, user, uucp, local0-local7
# Priority(优先级,从低到高):
# debug, info, notice, warning, err, crit, alert, emerg
# 配置示例
# *.info;mail.none;authpriv.none /var/log/messages
# authpriv.* /var/log/secure
# mail.* /var/log/maillog
# cron.* /var/log/cron
# *.emerg :omusrmsg:*
# 远程日志(收集其他服务器日志)
# 服务端配置(接收日志)
# /etc/rsyslog.conf
# module(load="imudp")
# input(type="imudp" port="514")
# 客户端配置(发送日志)
# *.* @log_server:514 # UDP
# *.* @@log_server:514 # TCP
# 使用 logger 命令记录日志
logger "这是一条测试日志"
logger -p auth.warning "登录警告"
logger -t myapp "应用日志消息"
3.2 logrotate — 日志轮转¶
Bash
# logrotate 自动管理日志文件的大小和数量
# 主配置文件
cat /etc/logrotate.conf
# 应用配置目录
ls /etc/logrotate.d/
# 配置示例
sudo tee /etc/logrotate.d/myapp > /dev/null << 'EOF'
/var/log/myapp/*.log {
daily # 每天轮转
rotate 30 # 保留30个轮转文件
compress # 压缩旧日志
delaycompress # 延迟压缩(最新的不压缩)
missingok # 日志不存在不报错
notifempty # 空日志不轮转
create 0644 myapp myapp # 轮转后创建新文件
dateext # 使用日期作为后缀
dateformat -%Y%m%d # 日期格式
size 100M # 超过100M才轮转
postrotate # 轮转后执行
systemctl reload myapp 2>/dev/null || true # &&前一个成功才执行后一个;||前一个失败才执行
endscript
}
EOF
# 手动执行轮转
sudo logrotate -f /etc/logrotate.d/myapp # 强制轮转
sudo logrotate -d /etc/logrotate.d/myapp # 模拟运行(调试)
# 检查 logrotate 状态
cat /var/lib/logrotate/status
📖 4. init 系统对比¶
Bash
# SysVinit(传统)
# 运行级别:0-6
# 0: 关机
# 1: 单用户(维护模式)
# 2: 多用户(无网络)
# 3: 多用户(有网络,文本模式)
# 4: 未使用
# 5: 图形界面
# 6: 重启
# systemd 目标(Target)对应
# runlevel0 → poweroff.target
# runlevel1 → rescue.target
# runlevel3 → multi-user.target
# runlevel5 → graphical.target
# runlevel6 → reboot.target
# 查看/切换
systemctl get-default # 查看默认目标
sudo systemctl set-default multi-user.target # 设为文本模式
sudo systemctl set-default graphical.target # 设为图形模式
sudo systemctl isolate multi-user.target # 临时切换
# SysVinit 对照
# service nginx start → systemctl start nginx
# service nginx stop → systemctl stop nginx
# chkconfig nginx on → systemctl enable nginx
# /etc/init.d/nginx start → systemctl start nginx
📖 5. 系统性能调优基础¶
5.1 内核参数调优¶
Bash
# 查看内核参数
sysctl -a # 所有参数
sysctl net.ipv4.ip_forward # 特定参数
# 临时修改
sudo sysctl -w net.ipv4.ip_forward=1
# 永久修改
sudo tee -a /etc/sysctl.conf > /dev/null << 'EOF'
# 网络优化
net.ipv4.ip_forward = 1
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
# 文件描述符
fs.file-max = 2097152
# 内存
vm.swappiness = 10
vm.overcommit_memory = 1
EOF
sudo sysctl -p # 立即生效
5.2 文件描述符限制¶
Bash
# 查看当前限制
ulimit -a # 所有限制
ulimit -n # 文件描述符限制
# 临时修改
ulimit -n 65535
# 永久修改 /etc/security/limits.conf
# * soft nofile 65535
# * hard nofile 65535
# * soft nproc 65535
# * hard nproc 65535
# systemd 服务的限制
# 在 service 文件中设置
# [Service]
# LimitNOFILE=65535
📖 6. 面试要点¶
Q1:如何创建一个开机自启动的服务?
编写
.service文件放在/etc/systemd/system/,设置[Install]中的WantedBy=multi-user.target,然后执行systemctl daemon-reload和systemctl enable --now myservice。
Q2:Crontab 中 */5 * * * * 是什么意思?
每5分钟执行一次。分钟字段的
*/5表示从0开始每隔5分钟。
Q3:如何查看某个服务为什么启动失败?
Bash
systemctl status myservice # 查看状态和最近日志
journalctl -u myservice -n 50 # 查看详细日志
journalctl -u myservice --since "5 min ago"
Q4:logrotate 的作用和原理?
logrotate 自动管理日志文件,防止日志无限增长。它可以按时间或大小进行日志轮转(重命名旧日志、创建新文件、压缩归档、删除过期日志)。配置在
/etc/logrotate.d/中,由 cron 每天调用执行。
🔧 练习题¶
- 编写一个 systemd service 文件,管理一个简单的 Python HTTP 服务
- 配置 Crontab 每天凌晨2点备份 /etc 目录,保留7天
- 配置 logrotate 管理自定义应用的日志(每天轮转,保留30天,压缩)
- 使用 journalctl 查找系统中最近1小时的错误日志
✅ 自我检查¶
- 能使用 systemctl 管理服务(启停/自启/状态)
- 能编写自定义 systemd service 文件
- 能使用 journalctl 查看和过滤日志
- 能正确配置 Crontab 定时任务
- 了解 logrotate 配置
- 了解基本的系统调优参数
上一章:07-网络管理 下一章:09-包管理与软件安装