🐧 第03课:进程管理

📚 核心概念

🎯 进程:Linux系统的核心抽象

进程是程序的运行实例,是资源分配的基本单位。理解进程管理是排查线上问题、优化系统性能的关键技能。每个进程都有唯一的PID,由init进程(PID=1)派生。

🔄 进程生命周期

                    fork()
  父进程 ──────────────────▶ 子进程
    │                           │
    │     exec()                │
    │  ┌───────────────┐       │
    │  │ 加载新程序代码  │       │
    │  └───────┬───────┘       │
    │          ▼                ▼
    │     ┌─────────┐    ┌─────────┐
    │     │ Running │    │ Running │
    │     └────┬────┘    └────┬────┘
    │          │               │
    │    ┌─────┴─────┐   ┌────┴────┐
    │    ▼           ▼   ▼         ▼
    │ Ready      Sleeping  Zombie
    │ (可运行)   (等待I/O) (已终止)
    │                │          │
    │           ┌────┘    wait()│
    │           ▼         ◀─────┘
    │      Wake Up     资源回收
    │           │
    │           ▼
    │      Running
    │
    └── wait()/waitpid() 回收子进程

📊 进程状态详解

状态代码说明常见场景
运行中R正在CPU上执行或等待调度计算密集型任务
可中断睡眠S等待事件(I/O、信号)等待网络响应
不可中断睡眠D等待不可中断事件等待磁盘I/O
已停止T被信号暂停Ctrl+Z暂停
僵尸Z已终止但父进程未回收编程Bug

🔢 信号系统

信号是进程间通信的基本机制,也是我们管理进程的主要手段:

信号编号含义用途
SIGHUP1挂起重载配置(nginx -s reload)
SIGINT2中断Ctrl+C终止前台进程
SIGKILL9强制终止无法捕获,最后手段
SIGTERM15优雅终止kill默认信号,允许清理
SIGSTOP19停止无法捕获,暂停进程
SIGUSR110用户自定义1nginx重新打开日志

⌨️ 命令实操

⌨️ 实操命令

1. 进程查看 ✅

进程查看
# ps命令 - 静态快照
ps aux                    # BSD风格,查看所有进程
ps -ef                    # System V风格
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head
# PID  PPID CMD              %MEM %CPU
# 1234 1    /usr/bin/python3  12.3 45.2
# 5678 1    /usr/sbin/nginx   2.1  0.5

# top/htop - 动态监控
top -b -n 1 | head -20    # 批处理模式
htop                       # 交互式(需安装)

# pgrep/pkill - 按名称查找/杀进程
pgrep -af nginx           # 查找nginx进程
# 1234 nginx: master process
# 1235 nginx: worker process

pgrep -P 1234             # 查找子进程
pkill -f "python app.py"  # 按命令行匹配杀进程

2. 进程管理 ✅

进程管理
# 启动后台进程
nohup python3 app.py > app.log 2>&1 &
# [1] 12345

# 查看后台任务
jobs -l
# [1]+ 12345 Running    nohup python3 app.py &

# 前后台切换
fg %1        # 将后台任务调到前台
Ctrl+Z       # 暂停当前前台进程
bg %1        # 将暂停的任务放后台运行

# 发送信号
kill -15 12345       # SIGTERM,优雅终止
kill -9 12345        # SIGKILL,强制终止(最后手段!)
kill -HUP $(pgrep nginx | head -1)  # 重载nginx配置
killall -TERM nginx  # 按名称终止

# 进程优先级
nice -n 10 ./heavy_task.sh    # 低优先级运行
renice -n -5 -p 12345         # 提高优先级(需root)
ps -eo pid,ni,cmd | grep task # 查看nice值

3. systemd服务管理 ✅

systemd
# 创建自定义服务
sudo tee /etc/systemd/system/myapp.service << 'EOF'
[Unit]
Description=My DevOps Application
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=appuser
Group=appgroup
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/start.sh
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/opt/myapp/bin/stop.sh
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536

# 安全加固
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/opt/myapp/data /var/log/myapp

[Install]
WantedBy=multi-user.target
EOF

# 启用并启动
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

# 查看服务状态和日志
sudo systemctl status myapp
sudo journalctl -u myapp -f          # 实时日志
sudo journalctl -u myapp --since today

4. 进程资源限制 ✅

资源限制
# 查看当前限制
ulimit -a
# core file size          (blocks, -c) 0
# open files                      (-n) 1024
# max user processes              (-u) 4096

# 临时修改(当前会话)
ulimit -n 65535           # 增加文件描述符限制

# 永久修改 /etc/security/limits.conf
sudo tee -a /etc/security/limits.conf << 'EOF'
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
root soft nofile 65535
root hard nofile 65535
EOF

# cgroups v2 限制进程资源
sudo systemctl set-property myapp.service MemoryMax=512M
sudo systemctl set-property myapp.service CPUQuota=200%

5. 僵尸进程处理脚本 ✅

僵尸处理
#!/bin/bash
# 僵尸进程检测与处理
echo "🧟 僵尸进程检测"
echo "================"

# 查找僵尸进程
ZOMBIES=$(ps aux | awk '$8=="Z" {print $2}')
COUNT=$(echo "$ZOMBIES" | grep -c . || echo 0)

if [ "$COUNT" -eq 0 ]; then
    echo "✅ 没有僵尸进程"
    exit 0
fi

echo "⚠️ 发现 $COUNT 个僵尸进程:"
echo "$ZOMBIES" | while read pid; do
    ppid=$(ps -o ppid= -p "$pid" | tr -d ' ')
    cmd=$(ps -o comm= -p "$pid")
    echo "  PID=$pid PPID=$ppid CMD=$cmd"
done

echo ""
echo "修复方案:"
echo "1. 找到父进程,发送SIGCHLD或重启父进程"
echo "2. 如果父进程是init(PID=1),僵尸会自动回收"
echo "3. 最后手段:杀掉父进程(僵尸变为init子进程后回收)"

📐 架构图

📐 架构图:Linux进程调度与资源管理

                    用户空间
    ┌────────────────────────────────────────┐
    │  App1   App2   App3   Shell   Nginx   │
    └──┬───────┬───────┬──────┬───────┬──────┘
       │       │       │      │       │
    ┌──▼───────▼───────▼──────▼───────▼──────┐
    │          系统调用接口 (syscall)          │
    └──┬───────────────────────────────────┬──┘
       │                                   │
    ┌──▼───────────────────────────────────▼──┐
    │            内核空间                       │
    │                                          │
    │  ┌──────────────────────────────────┐   │
    │  │       CFS调度器 (Completely      │   │
    │  │       Fair Scheduler)            │   │
    │  │  ┌─────┐ ┌─────┐ ┌─────┐       │   │
    │  │  │CPU 0│ │CPU 1│ │CPU 2│       │   │
    │  │  │RunQ │ │RunQ │ │RunQ │       │   │
    │  │  └──┬──┘ └──┬──┘ └──┬──┘       │   │
    │  └────┼───────┼───────┼───────────┘   │
    │       │       │       │                 │
    │  ┌────▼───────▼───────▼───────────┐    │
    │  │         cgroups v2              │    │
    │  │  ┌──────┐ ┌──────┐ ┌──────┐   │    │
    │  │  │CPU   │ │Memory│ │ I/O  │   │    │
    │  │  │限制  │ │限制  │ │限制  │   │    │
    │  │  └──────┘ └──────┘ └──────┘   │    │
    │  └────────────────────────────────┘    │
    └──────────────────────────────────────────┘

🔧 故障排查

🔧 故障排查

❌ 问题1:进程D状态(不可中断睡眠)导致load average飙升

# 识别D状态进程
ps aux | awk '$8 ~ /D/'
# root  4567  0.0  0.1  D  0:00 /usr/bin/storage-sync

# 查看等待的内核栈
cat /proc/4567/stack
# [] io_schedule+0x12/0x40
# [] wait_on_page_bit+0x82/0xa0

# 常见原因:NFS挂载超时、磁盘故障、iSCSI断连
# 解决:修复底层存储问题,无法kill -9 D状态进程

# 如果是NFS导致的D状态
umount -f /mnt/nfs        # 强制卸载
# 或:设置NFS超时参数
mount -t nfs -o hard,intr,timeo=10 server:/share /mnt/nfs

❌ 问题2:OOM Killer杀掉了关键进程

# 查看OOM记录
dmesg | grep -i "oom-killer" | tail -5
journalctl -k | grep -i oom

# 查看OOM评分
cat /proc/$(pgrep myapp)/oom_score
cat /proc/$(pgrep myapp)/oom_score_adj

# 防止关键进程被OOM杀掉
echo -1000 | sudo tee /proc/$(pgrep myapp)/oom_score_adj

# 或在systemd服务中配置
# OOMScoreAdjust=-1000

# 根本解决:增加内存或限制进程内存使用
sudo systemctl set-property myapp.service MemoryMax=1G

🏆 成就解锁:进程猎手!

掌握进程生命周期、信号机制、systemd服务管理、cgroups资源限制——这是排障和性能优化的核心技能。