第43集:进程监控工具
章节标题
进程监控工具
核心知识点讲解
进程监控工具概述
进程监控工具是用于实时观察和分析系统中进程行为、资源使用情况的软件工具。它们可以帮助系统管理员和开发人员了解系统状态,识别性能瓶颈,以及排查系统问题。
top 命令
top 命令是最基本的进程监控工具,几乎在所有Linux系统中都默认安装。
基本用法
# 启动top命令
top
# 以批处理模式运行,显示指定次数后退出
top -b -n 1
# 只显示指定PID的进程
top -p PID1,PID2
# 设置更新间隔(秒)
top -d 2交互式命令
在top运行时,可以使用以下快捷键:
| 快捷键 | 功能 |
|---|---|
| q | 退出top |
| k | 终止指定进程 |
| r | 调整进程优先级 |
| f | 自定义显示字段 |
| M | 按内存使用率排序 |
| P | 按CPU使用率排序 |
| T | 按CPU时间排序 |
| 1 | 显示所有CPU核心的使用率 |
| z | 启用彩色显示 |
| h | 显示帮助信息 |
输出解释
top命令的输出分为两部分:
- 顶部系统摘要信息:包括系统时间、运行时间、用户数、负载平均值、CPU使用率、内存使用率等
- 进程列表:按默认或用户指定的排序方式显示进程信息
htop 命令
htop 是 top 命令的增强版本,提供了更友好的界面和更多的功能。
安装
# 在Debian/Ubuntu系统上安装
sudo apt install htop
# 在CentOS/RHEL系统上安装
sudo yum install htop
# 在Fedora系统上安装
sudo dnf install htop基本用法
# 启动htop命令
htop
# 只显示指定用户的进程
htop -u username
# 只显示指定PID的进程
htop -p PID1,PID2
# 以树状结构显示进程
htop -t交互式命令
在htop运行时,可以使用以下快捷键:
| 快捷键 | 功能 |
|---|---|
| F1 | 显示帮助信息 |
| F2 | 配置htop |
| F3 | 搜索进程 |
| F4 | 过滤进程 |
| F5 | 切换树状结构视图 |
| F6 | 选择排序字段 |
| F7 | 降低进程优先级 |
| F8 | 提高进程优先级 |
| F9 | 终止进程 |
| F10 | 退出htop |
| 空格 | 标记/取消标记进程 |
| U | 取消所有标记 |
| K | 终止所有标记的进程 |
| / | 搜索 |
| 过滤 | |
| H | 显示/隐藏用户线程 |
| I | 显示/隐藏空闲进程 |
| P | 按CPU使用率排序 |
| M | 按内存使用率排序 |
| T | 按CPU时间排序 |
| 1 | 显示所有CPU核心 |
atop 命令
atop 是一个高级的性能监控工具,不仅可以实时监控系统状态,还可以记录历史数据以便后续分析。
安装
# 在Debian/Ubuntu系统上安装
sudo apt install atop
# 在CentOS/RHEL系统上安装
sudo yum install atop
# 在Fedora系统上安装
sudo dnf install atop基本用法
# 启动atop命令
atop
# 以批处理模式运行,显示指定次数后退出
atop -b -n 1
# 查看历史数据
atop -r /var/log/atop/atop_20240101
# 设置更新间隔(秒)
atop -i 2交互式命令
在atop运行时,可以使用以下快捷键:
| 快捷键 | 功能 |
|---|---|
| h | 显示帮助信息 |
| q | 退出atop |
| a | 按CPU使用率排序 |
| m | 按内存使用率排序 |
| d | 按磁盘I/O排序 |
| n | 按网络I/O排序 |
| c | 显示/隐藏命令行 |
| u | 显示/隐藏用户信息 |
| t | 向前/向后查看历史数据(在查看历史文件时) |
| b | 显示/隐藏平均负载和CPU使用率 |
| w | 显示/隐藏交换空间使用情况 |
| l | 显示/隐藏磁盘统计信息 |
| e | 显示/隐藏进程环境变量 |
glances 命令
glances 是一个跨平台的系统监控工具,提供了更丰富的信息和更现代化的界面。
安装
# 使用pip安装
sudo pip install glances
# 在Debian/Ubuntu系统上安装
sudo apt install glances
# 在CentOS/RHEL系统上安装
sudo yum install glances
# 在Fedora系统上安装
sudo dnf install glances基本用法
# 启动glances命令
glances
# 以Web服务器模式运行
glances -w
# 以客户端/服务器模式运行
# 服务器端
glances -s
# 客户端
glances -c server_ip
# 以批处理模式运行,显示指定次数后退出
glances -b -n 1交互式命令
在glances运行时,可以使用以下快捷键:
| 快捷键 | 功能 |
|---|---|
| h | 显示帮助信息 |
| q | 退出glances |
| c | 按CPU使用率排序 |
| m | 按内存使用率排序 |
| i | 按I/O使用率排序 |
| p | 按进程名称排序 |
| d | 显示/隐藏磁盘I/O统计信息 |
| n | 显示/隐藏网络统计信息 |
| s | 显示/隐藏传感器信息 |
| t | 显示/隐藏顶部进程 |
| w | 切换到Web界面 |
| z | 切换彩色/单色模式 |
| 1 | 切换全局/每个CPU的统计信息 |
其他进程监控工具
pidstat 命令
pidstat 是 sysstat 包的一部分,用于监控进程的详细统计信息。
# 安装sysstat
sudo apt install sysstat # Debian/Ubuntu
sudo yum install sysstat # CentOS/RHEL
# 监控所有进程的CPU使用率
pidstat
# 监控指定PID的进程
pidstat -p PID
# 监控进程的内存使用情况
pidstat -r
# 监控进程的I/O情况
pidstat -d
# 定期输出统计信息
pidstat 1 5 # 每1秒输出一次,共输出5次psacct 工具集
psacct 工具集用于监控进程的活动和资源使用情况。
# 安装psacct
sudo apt install acct # Debian/Ubuntu
sudo yum install psacct # CentOS/RHEL
# 查看进程的CPU使用情况
lastcomm
# 查看用户的CPU使用情况
ac
# 查看命令的使用情况
sasystemtap 工具
systemtap 是一个高级的系统监控和故障诊断工具。
# 安装systemtap
sudo apt install systemtap # Debian/Ubuntu
sudo yum install systemtap # CentOS/RHEL
# 示例:监控进程创建和终止
stap -e 'probe syscall.fork, syscall.vfork, syscall.clone { printf("Process created by %d\n", pid()); } probe syscall.exit { printf("Process %d exited\n", pid()); }'实用案例分析
案例1:实时监控系统资源
# 使用top实时监控
top
# 使用htop实时监控(更友好的界面)
htop
# 使用glances实时监控(更丰富的信息)
glances
# 使用atop实时监控(更详细的统计)
atop案例2:监控特定进程
# 使用top监控特定进程
top -p $(pgrep nginx | head -1)
# 使用htop监控特定进程
htop -p $(pgrep nginx | head -1)
# 使用pidstat监控特定进程的详细信息
pidstat -p $(pgrep nginx | head -1) 1 10
# 使用glances监控特定进程
glances --process-filter nginx案例3:历史数据分析
# 使用atop查看历史数据
atop -r /var/log/atop/atop_$(date +%Y%m%d)
# 在atop中查看特定时间点的数据
# 启动atop后,使用t键向前/向后移动
# 使用sar查看历史数据(sysstat的一部分)
sar -u # CPU使用情况
sar -r # 内存使用情况
sar -d # 磁盘I/O情况案例4:远程监控
# 使用glances的客户端/服务器模式
# 服务器端
glances -s
# 客户端
glances -c server_ip
# 使用SSH远程运行监控命令
ssh user@server "top -b -n 1"
# 使用netstat监控网络连接
netstat -tuln
# 使用ss监控网络连接(更现代的工具)
ss -tuln案例5:系统瓶颈分析
# 分析CPU瓶颈
# 使用top查看CPU使用率高的进程
top
# 分析内存瓶颈
# 使用top或htop查看内存使用率高的进程
top -o %MEM
# 分析磁盘I/O瓶颈
# 使用iostat查看磁盘I/O情况
iostat -x
# 使用atop查看磁盘I/O情况
atop -d
# 分析网络瓶颈
# 使用netstat或ss查看网络连接
netstat -tuln
# 使用iftop查看网络流量
iftop代码示例
示例1:系统监控脚本
#!/bin/bash
# 系统监控脚本
# 显示帮助信息
show_help() {
echo "系统监控脚本"
echo "用法: $0 [选项]"
echo "选项:"
echo " -c, --cpu 监控CPU使用情况"
echo " -m, --mem 监控内存使用情况"
echo " -d, --disk 监控磁盘使用情况"
echo " -n, --net 监控网络使用情况"
echo " -p, --process <name> 监控指定进程"
echo " -a, --all 监控所有资源"
echo " -i, --interval <sec> 监控间隔(秒),默认1秒"
echo " -t, --time <sec> 监控时长(秒),默认无限"
echo " -h, --help 显示帮助信息"
}
# 解析命令行参数
CPU=false
MEM=false
DISK=false
NET=false
PROCESS=""
ALL=false
INTERVAL=1
TIME=0
while [[ $# -gt 0 ]]; do
case $1 in
-c|--cpu)
CPU=true
shift
;;
-m|--mem)
MEM=true
shift
;;
-d|--disk)
DISK=true
shift
;;
-n|--net)
NET=true
shift
;;
-p|--process)
PROCESS="$2"
shift 2
;;
-a|--all)
ALL=true
CPU=true
MEM=true
DISK=true
NET=true
shift
;;
-i|--interval)
INTERVAL="$2"
shift 2
;;
-t|--time)
TIME="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
*)
echo "未知选项: $1"
show_help
exit 1
;;
esac
done
# 检查参数
if [[ $CPU == false && $MEM == false && $DISK == false && $NET == false && -z "$PROCESS" ]]; then
echo "错误: 必须指定至少一个监控选项"
show_help
exit 1
fi
# 开始监控
echo "=== 系统监控开始 ==="
echo "监控时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "监控间隔: $INTERVAL 秒"
if [[ $TIME -gt 0 ]]; then
echo "监控时长: $TIME 秒"
fi
echo ""
# 计算结束时间
if [[ $TIME -gt 0 ]]; then
end_time=$(( $(date +%s) + $TIME ))
fi
# 监控循环
while true; do
# 检查是否达到结束时间
if [[ $TIME -gt 0 && $(date +%s) -ge $end_time ]]; then
break
fi
# 显示当前时间
echo "[$(date '+%Y-%m-%d %H:%M:%S')]"
echo ""
# 监控CPU
if $CPU; then
echo "=== CPU使用情况 ==="
mpstat
echo ""
fi
# 监控内存
if $MEM; then
echo "=== 内存使用情况 ==="
free -h
echo ""
fi
# 监控磁盘
if $DISK; then
echo "=== 磁盘使用情况 ==="
df -h
echo ""
echo "=== 磁盘I/O情况 ==="
iostat -x
echo ""
fi
# 监控网络
if $NET; then
echo "=== 网络使用情况 ==="
netstat -tuln
echo ""
echo "=== 网络连接情况 ==="
ss -s
echo ""
fi
# 监控特定进程
if [[ -n "$PROCESS" ]]; then
echo "=== 进程 '$PROCESS' 状态 ==="
pgrep -a "$PROCESS"
if [[ $? -eq 0 ]]; then
pid=$(pgrep -f "$PROCESS" | head -1)
if [[ -n "$pid" ]]; then
ps -p $pid -o pid,ppid,user,%cpu,%mem,state,command
echo ""
echo "=== 进程 '$pid' 详细统计 ==="
pidstat -p $pid
fi
else
echo "进程 '$PROCESS' 不存在"
fi
echo ""
fi
# 等待指定的间隔
sleep $INTERVAL
done
echo "=== 系统监控结束 ==="
echo "结束时间: $(date '+%Y-%m-%d %H:%M:%S')"示例2:进程资源使用监控脚本
#!/bin/bash
# 进程资源使用监控脚本
# 显示帮助信息
show_help() {
echo "进程资源使用监控脚本"
echo "用法: $0 [选项]"
echo "选项:"
echo " -p, --pid <pid> 监控指定PID的进程"
echo " -n, --name <name> 监控指定名称的进程"
echo " -i, --interval <sec> 监控间隔(秒),默认1秒"
echo " -c, --count <num> 监控次数,默认无限"
echo " -o, --output <file> 将监控结果输出到文件"
echo " -h, --help 显示帮助信息"
}
# 解析命令行参数
PID=""
NAME=""
INTERVAL=1
COUNT=-1
OUTPUT=""
while [[ $# -gt 0 ]]; do
case $1 in
-p|--pid)
PID="$2"
shift 2
;;
-n|--name)
NAME="$2"
shift 2
;;
-i|--interval)
INTERVAL="$2"
shift 2
;;
-c|--count)
COUNT="$2"
shift 2
;;
-o|--output)
OUTPUT="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
*)
echo "未知选项: $1"
show_help
exit 1
;;
esac
done
# 检查参数
if [[ -z "$PID" && -z "$NAME" ]]; then
echo "错误: 必须指定PID或进程名称"
show_help
exit 1
fi
# 如果指定了进程名称,获取其PID
if [[ -n "$NAME" ]]; then
PID=$(pgrep -f "$NAME" | head -1)
if [[ -z "$PID" ]]; then
echo "错误: 找不到名称为 '$NAME' 的进程"
exit 1
fi
echo "找到进程 '$NAME',PID: $PID"
fi
# 准备输出文件
if [[ -n "$OUTPUT" ]]; then
echo "=== 进程资源使用监控 ===" > "$OUTPUT"
echo "监控进程: $PID" >> "$OUTPUT"
echo "监控时间: $(date '+%Y-%m-%d %H:%M:%S')" >> "$OUTPUT"
echo "监控间隔: $INTERVAL 秒" >> "$OUTPUT"
if [[ $COUNT -gt 0 ]]; then
echo "监控次数: $COUNT" >> "$OUTPUT"
fi
echo "" >> "$OUTPUT"
echo "时间,PID,CPU使用率,内存使用率,虚拟内存(KB),物理内存(KB),状态,命令" >> "$OUTPUT"
fi
# 监控循环
iteration=0
while true; do
# 检查进程是否存在
if ! ps -p $PID > /dev/null 2>&1; then
echo "进程 $PID 不存在或已结束"
if [[ -n "$OUTPUT" ]]; then
echo "进程 $PID 不存在或已结束" >> "$OUTPUT"
fi
break
fi
# 获取当前时间
current_time=$(date '+%Y-%m-%d %H:%M:%S')
# 获取进程状态
process_info=$(ps -p $PID -o pid,%cpu,%mem,vsz,rss,state,command --no-headers)
# 提取信息
read -r pid cpu mem vsz rss state command <<< "$process_info"
# 显示信息
echo "[$current_time] 进程 $PID 状态:"
echo "CPU使用率: $cpu%"
echo "内存使用率: $mem%"
echo "虚拟内存: $vsz KB"
echo "物理内存: $rss KB"
echo "状态: $state"
echo "命令: $command"
echo ""
# 输出到文件
if [[ -n "$OUTPUT" ]]; then
echo "$current_time,$pid,$cpu,$mem,$vsz,$rss,$state,\"$command\"" >> "$OUTPUT"
fi
# 增加迭代计数
iteration=$((iteration + 1))
# 检查是否达到指定的监控次数
if [[ $COUNT -gt 0 && $iteration -ge $COUNT ]]; then
break
fi
# 等待指定的间隔
sleep $INTERVAL
done
echo "监控结束"
if [[ -n "$OUTPUT" ]]; then
echo "监控结束时间: $(date '+%Y-%m-%d %H:%M:%S')" >> "$OUTPUT"
echo "监控结果已保存到: $OUTPUT"
fi示例3:系统负载监控与告警脚本
#!/bin/bash
# 系统负载监控与告警脚本
# 配置告警阈值
CPU_THRESHOLD=80 # CPU使用率阈值(%)
MEM_THRESHOLD=80 # 内存使用率阈值(%)
DISK_THRESHOLD=90 # 磁盘使用率阈值(%)
LOAD_THRESHOLD=1.0 # 系统负载阈值(每个CPU核心)
# 监控间隔
INTERVAL=60 # 秒
# 告警日志文件
ALERT_LOG="/var/log/system_alert.log"
# 创建告警日志文件
if [[ ! -f "$ALERT_LOG" ]]; then
touch "$ALERT_LOG"
chmod 644 "$ALERT_LOG"
fi
# 发送告警
send_alert() {
local message="$1"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] ALERT: $message" >> "$ALERT_LOG"
echo "[$timestamp] ALERT: $message"
# 这里可以添加发送邮件或其他通知的代码
# 例如:echo "$message" | mail -s "System Alert" admin@example.com
}
# 监控CPU使用情况
monitor_cpu() {
local cpu_usage=$(mpstat | awk '/all/{print 100 - $NF}')
local cpu_usage_int=$(printf "%.0f" "$cpu_usage")
if [[ $cpu_usage_int -ge $CPU_THRESHOLD ]]; then
send_alert "CPU使用率过高: ${cpu_usage_int}%"
fi
}
# 监控内存使用情况
monitor_memory() {
local mem_total=$(free | awk '/Mem/{print $2}')
local mem_used=$(free | awk '/Mem/{print $3}')
local mem_usage=$((mem_used * 100 / mem_total))
if [[ $mem_usage -ge $MEM_THRESHOLD ]]; then
send_alert "内存使用率过高: ${mem_usage}%"
fi
}
# 监控磁盘使用情况
monitor_disk() {
local disk_usage=$(df -h | grep -v tmpfs | grep -v devtmpfs | awk '{print $5}' | sed 's/%//g')
for usage in $disk_usage; do
if [[ $usage -ge $DISK_THRESHOLD ]]; then
local mount_point=$(df -h | grep -v tmpfs | grep -v devtmpfs | grep " ${usage}%" | awk '{print $6}')
send_alert "磁盘使用率过高: ${usage}% (挂载点: $mount_point)"
fi
done
}
# 监控系统负载
monitor_load() {
local load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}')
local cpu_count=$(nproc)
local load_per_cpu=$(echo "$load_avg / $cpu_count" | bc -l)
local load_per_cpu_int=$(printf "%.1f" "$load_per_cpu")
if (( $(echo "$load_per_cpu_int >= $LOAD_THRESHOLD" | bc -l) )); then
send_alert "系统负载过高: ${load_avg} (每CPU核心: ${load_per_cpu_int})"
fi
}
# 主监控函数
main_monitor() {
echo "=== 系统负载监控开始 ==="
echo "监控时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "监控间隔: $INTERVAL 秒"
echo "告警日志: $ALERT_LOG"
echo ""
while true; do
# 监控各项指标
monitor_cpu
monitor_memory
monitor_disk
monitor_load
# 等待指定的间隔
sleep $INTERVAL
done
}
# 运行监控
main_monitor总结
本集介绍了 Linux 中常用的进程监控工具,包括:
top命令:最基本的进程监控工具,默认安装在所有Linux系统中htop命令:top的增强版本,提供更友好的界面和更多功能atop命令:高级性能监控工具,支持历史数据记录和分析glances命令:跨平台系统监控工具,提供丰富的信息和现代化界面- 其他进程监控工具:如
pidstat、psacct、systemtap等
同时,本集还介绍了这些工具的安装方法、基本用法、交互式命令和输出解释,以及多个实用案例和代码示例,包括:
- 实时监控系统资源
- 监控特定进程
- 历史数据分析
- 远程监控
- 系统瓶颈分析
- 系统监控脚本
- 进程资源使用监控脚本
- 系统负载监控与告警脚本
通过掌握这些进程监控工具,用户可以更好地了解系统的运行状态,及时发现和解决性能问题,从而提高系统的稳定性和可靠性。在实际工作中,应根据具体需求选择合适的监控工具,并结合自动化脚本实现持续监控和告警。