代码
#!/bin/bash
# 服务器压力测试交互式脚本
# 支持:CPU压力测试、内存压力测试、磁盘I/O测试、网络测试、综合压力测试
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 检查必要工具
check_tools() {
local missing_tools=()
echo -e "${CYAN}检查必要的工具...${NC}"
# 检查是否安装stress
if ! command -v stress &> /dev/null; then
missing_tools+=("stress")
fi
# 检查是否安装sysbench
if ! command -v sysbench &> /dev/null; then
missing_tools+=("sysbench")
fi
# 检查是否安装iperf3
if ! command -v iperf3 &> /dev/null; then
missing_tools+=("iperf3")
fi
# 检查是否安装fio
if ! command -v fio &> /dev/null; then
missing_tools+=("fio")
fi
# 检查是否安装htop
if ! command -v htop &> /dev/null; then
missing_tools+=("htop")
fi
# 检查是否安装nload
if ! command -v nload &> /dev/null; then
missing_tools+=("nload")
fi
if [ ${#missing_tools[@]} -gt 0 ]; then
echo -e "${YELLOW}以下工具未安装: ${missing_tools[*]}${NC}"
read -p "是否要安装这些工具?(y/n): " install_choice
if [[ $install_choice == "y" || $install_choice == "Y" ]]; then
install_missing_tools "${missing_tools[@]}"
else
echo -e "${YELLOW}部分功能可能无法使用${NC}"
fi
else
echo -e "${GREEN}所有必要工具已安装${NC}"
fi
}
# 安装缺失的工具
install_missing_tools() {
local tools=("$@")
echo -e "${CYAN}开始安装工具...${NC}"
# 检测包管理器
if command -v apt &> /dev/null; then
sudo apt update
sudo apt install -y "${tools[@]}"
elif command -v yum &> /dev/null; then
sudo yum install -y epel-release
sudo yum install -y "${tools[@]}"
elif command -v dnf &> /dev/null; then
sudo dnf install -y epel-release
sudo dnf install -y "${tools[@]}"
else
echo -e "${RED}无法确定包管理器,请手动安装缺失的工具${NC}"
echo "需要安装: ${tools[*]}"
return 1
fi
echo -e "${GREEN}工具安装完成${NC}"
}
# 显示系统信息
show_system_info() {
echo -e "\n${CYAN}========== 系统信息 ==========${NC}"
# CPU信息
echo -e "${GREEN}CPU信息:${NC}"
echo -e " 型号: $(lscpu | grep "Model name" | cut -d':' -f2 | xargs)"
echo -e " 核心数: $(nproc)"
echo -e " 线程数: $(lscpu | grep "^CPU(s):" | awk '{print $2}')"
# 内存信息
echo -e "${GREEN}内存信息:${NC}"
free -h | awk 'NR==1{print " "$0} NR==2{print " "$0}'
# 磁盘信息
echo -e "${GREEN}磁盘信息:${NC}"
df -h / | awk 'NR==1{print " "$0} NR==2{print " "$0}'
# 系统负载
echo -e "${GREEN}系统负载:${NC}"
uptime | awk -F'load average:' '{print " "$2}'
}
# CPU压力测试
cpu_stress_test() {
echo -e "\n${CYAN}========== CPU压力测试 ==========${NC}"
read -p "请输入CPU核心数(默认全部): " cpu_cores
if [ -z "$cpu_cores" ]; then
cpu_cores=$(nproc)
fi
read -p "请输入测试时间(秒,默认60): " duration
if [ -z "$duration" ]; then
duration=60
fi
read -p "请输入负载类型 (1:计算 2:浮点 3:混合,默认3): " load_type
case $load_type in
1) stress_args="--cpu $cpu_cores --cpu-method matrixprod" ;;
2) stress_args="--cpu $cpu_cores --cpu-method fft" ;;
*) stress_args="--cpu $cpu_cores" ;;
esac
echo -e "${YELLOW}开始CPU压力测试,持续 ${duration} 秒...${NC}"
echo -e "使用核心数: ${cpu_cores}"
# 显示测试前CPU信息
echo -e "\n${GREEN}测试前CPU使用率:${NC}"
mpstat 1 1 | tail -2
# 开始压力测试
stress $stress_args --timeout ${duration}s &
stress_pid=$!
# 监控CPU使用率
echo -e "\n${GREEN}测试中监控(每秒刷新):${NC}"
for ((i=1; i<=duration; i++)); do
if ps -p $stress_pid > /dev/null; then
echo -ne "\r测试进行中: ${i}/${duration}秒 - CPU使用率: "
top -bn1 | grep "Cpu(s)" | awk '{printf "%.1f%%", $2}'
sleep 1
else
break
fi
done
wait $stress_pid
echo -e "\n${GREEN}CPU压力测试完成${NC}"
}
# 内存压力测试
memory_stress_test() {
echo -e "\n${CYAN}========== 内存压力测试 ==========${NC}"
# 获取可用内存
total_mem=$(free -m | awk '/^Mem:/{print $2}')
available_mem=$(free -m | awk '/^Mem:/{print $7}')
echo -e "总内存: ${total_mem}MB"
echo -e "可用内存: ${available_mem}MB"
read -p "请输入要测试的内存大小(MB,默认可用内存的80%): " mem_size
if [ -z "$mem_size" ]; then
mem_size=$((available_mem * 80 / 100))
fi
if [ $mem_size -gt $available_mem ]; then
echo -e "${RED}警告: 请求的内存超过可用内存,将使用可用内存的90%${NC}"
mem_size=$((available_mem * 90 / 100))
fi
read -p "请输入测试时间(秒,默认30): " duration
if [ -z "$duration" ]; then
duration=30
fi
echo -e "${YELLOW}开始内存压力测试...${NC}"
echo -e "测试内存: ${mem_size}MB"
echo -e "持续时间: ${duration}秒"
# 显示测试前内存信息
echo -e "\n${GREEN}测试前内存使用:${NC}"
free -m
# 开始内存压力测试
stress --vm 1 --vm-bytes ${mem_size}M --vm-keep --timeout ${duration}s &
stress_pid=$!
# 监控内存使用
echo -e "\n${GREEN}测试中内存监控:${NC}"
for ((i=1; i<=duration; i+=5)); do
if ps -p $stress_pid > /dev/null; then
echo -e "时间: ${i}秒"
free -m | grep "^Mem:"
sleep 5
else
break
fi
done
wait $stress_pid
echo -e "\n${GREEN}内存压力测试完成${NC}"
echo -e "${GREEN}测试后内存使用:${NC}"
free -m
}
# 磁盘I/O测试
disk_io_test() {
echo -e "\n${CYAN}========== 磁盘I/O测试 ==========${NC}"
echo -e "${GREEN}可用磁盘:${NC}"
df -h | grep -v tmpfs
read -p "请输入测试目录路径(默认/tmp): " test_dir
if [ -z "$test_dir" ]; then
test_dir="/tmp"
fi
if [ ! -d "$test_dir" ]; then
echo -e "${RED}目录不存在,使用/tmp${NC}"
test_dir="/tmp"
fi
# 创建测试文件路径
test_file="${test_dir}/io_test_${RANDOM}.dat"
echo -e "\n请选择测试类型:"
echo "1) 顺序读写测试"
echo "2) 随机读写测试"
echo "3) 混合读写测试"
read -p "请选择 (默认1): " test_type
read -p "请输入文件大小(默认1GB): " file_size
if [ -z "$file_size" ]; then
file_size="1G"
fi
read -p "请输入测试时间(秒,默认30): " duration
if [ -z "$duration" ]; then
duration=30
fi
echo -e "${YELLOW}开始磁盘I/O测试...${NC}"
case $test_type in
2)
# 随机读写
fio_cmd="--name=random_test --filename=${test_file} --size=${file_size} --readwrite=randrw --rwmixread=50 --bs=4k --direct=1 --numjobs=1 --time_based --runtime=${duration} --group_reporting"
;;
3)
# 混合读写
fio_cmd="--name=mixed_test --filename=${test_file} --size=${file_size} --readwrite=rw --rwmixread=70 --bs=16k --direct=1 --numjobs=4 --time_based --runtime=${duration} --group_reporting"
;;
*)
# 顺序读写
fio_cmd="--name=seq_test --filename=${test_file} --size=${file_size} --readwrite=readwrite --bs=1M --direct=1 --numjobs=1 --time_based --runtime=${duration} --group_reporting"
;;
esac
# 执行fio测试
echo -e "${GREEN}执行命令: fio ${fio_cmd}${NC}"
fio $fio_cmd
# 清理测试文件
if [ -f "$test_file" ]; then
rm -f "$test_file"
fi
echo -e "\n${GREEN}磁盘I/O测试完成${NC}"
}
# 网络测试
network_test() {
echo -e "\n${CYAN}========== 网络测试 ==========${NC}"
echo -e "1) 带宽测试(需要iperf3服务器)"
echo -e "2) 延迟和丢包测试"
echo -e "3) 路由跟踪"
echo -e "4) 网速监控"
read -p "请选择测试类型(默认2): " net_test_type
case $net_test_type in
1)
read -p "请输入iperf3服务器地址: " server_addr
if [ -z "$server_addr" ]; then
echo -e "${RED}需要服务器地址${NC}"
return
fi
read -p "请输入测试时间(秒,默认10): " duration
if [ -z "$duration" ]; then
duration=10
fi
echo -e "${YELLOW}开始带宽测试到 ${server_addr}...${NC}"
iperf3 -c $server_addr -t $duration
;;
3)
read -p "请输入目标地址(默认8.8.8.8): " target_addr
if [ -z "$target_addr" ]; then
target_addr="8.8.8.8"
fi
echo -e "${YELLOW}开始路由跟踪到 ${target_addr}...${NC}"
traceroute -n $target_addr
;;
4)
echo -e "${YELLOW}开始网速监控(按q退出)...${NC}"
nload
;;
*)
read -p "请输入测试地址(默认8.8.8.8): " ping_addr
if [ -z "$ping_addr" ]; then
ping_addr="8.8.8.8"
fi
read -p "请输入测试次数(默认10): " ping_count
if [ -z "$ping_count" ]; then
ping_count=10
fi
echo -e "${YELLOW}开始ping测试 ${ping_addr}...${NC}"
ping -c $ping_count $ping_addr
echo -e "\n${YELLOW}开始mtr测试 ${ping_addr}...${NC}"
if command -v mtr &> /dev/null; then
mtr -n -r -c 10 $ping_addr
else
echo -e "${YELLOW}mtr未安装,使用traceroute替代${NC}"
traceroute -n $ping_addr
fi
;;
esac
}
# 系统监控仪表板
system_monitor() {
echo -e "\n${CYAN}========== 系统监控仪表板 ==========${NC}"
echo -e "监控中... 按 Ctrl+C 退出"
echo -e "${PURPLE}------------------------------------------------${NC}"
while true; do
clear
# CPU信息
echo -e "${GREEN}====== CPU信息 ======${NC}"
echo -e "负载: $(uptime | awk -F'load average:' '{print $2}')"
echo -e "使用率: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}')%"
# 内存信息
echo -e "\n${GREEN}====== 内存信息 ======${NC}"
free -h | awk 'NR==1{print $0} NR==2{printf "Mem: %s/%s (%.1f%%)\n", $3, $2, $3/$2*100}'
# 磁盘信息
echo -e "\n${GREEN}====== 磁盘信息 ======${NC}"
df -h / | awk 'NR==2{printf "%s: %s/%s (%.1f%%)\n", $1, $3, $2, $5}'
# 网络连接
echo -e "\n${GREEN}====== 网络连接 ======${NC}"
echo -e "TCP连接数: $(netstat -tun | grep 'tcp' | wc -l)"
echo -e "ESTABLISHED连接: $(netstat -tun | grep 'ESTABLISHED' | wc -l)"
# 进程信息
echo -e "\n${GREEN}====== 进程信息 ======${NC}"
echo -e "总进程数: $(ps aux | wc -l)"
echo -e "CPU使用前5:"
ps aux --sort=-%cpu | head -6 | tail -5 | awk '{printf " %s (%.1f%%)\n", $11, $3}'
echo -e "\n${PURPLE}------------------------------------------------${NC}"
echo -e "刷新间隔: 5秒 | 按 Ctrl+C 退出"
sleep 5
done
}
# 综合压力测试
comprehensive_test() {
echo -e "\n${CYAN}========== 综合压力测试 ==========${NC}"
echo -e "${RED}警告: 这将同时测试CPU、内存和磁盘I/O${NC}"
echo -e "${RED}可能会对系统性能造成显著影响${NC}"
read -p "是否继续?(y/n): " confirm
if [[ $confirm != "y" && $confirm != "Y" ]]; then
return
fi
read -p "请输入测试时间(秒,默认60): " duration
if [ -z "$duration" ]; then
duration=60
fi
# 获取系统信息
cpu_cores=$(nproc)
total_mem=$(free -m | awk '/^Mem:/{print $2}')
test_mem=$((total_mem * 50 / 100)) # 使用50%的内存
echo -e "\n${YELLOW}开始综合压力测试...${NC}"
echo -e "CPU核心: ${cpu_cores}"
echo -e "测试内存: ${test_mem}MB"
echo -e "持续时间: ${duration}秒"
# 创建测试目录
test_dir="/tmp/stress_test_${RANDOM}"
mkdir -p $test_dir
test_file="${test_dir}/test.dat"
# 开始综合测试
echo -e "\n${GREEN}启动所有压力测试组件...${NC}"
# CPU压力测试
stress --cpu $cpu_cores --timeout ${duration}s &
cpu_pid=$!
# 内存压力测试
stress --vm 2 --vm-bytes ${test_mem}M --timeout ${duration}s &
mem_pid=$!
# 磁盘I/O测试
fio --name=comprehensive_io --filename=${test_file} --size=500M --readwrite=randrw --rwmixread=50 --bs=4k --direct=1 --numjobs=2 --time_based --runtime=${duration} --group_reporting --output=/tmp/fio_results.txt &
fio_pid=$!
# 监控
echo -e "\n${GREEN}综合测试监控(每5秒刷新):${NC}"
for ((i=1; i<=duration; i+=5)); do
if [ $i -lt $duration ]; then
echo -e "\n${CYAN}=== 测试进度: ${i}/${duration}秒 ===${NC}"
# CPU监控
echo -e "${GREEN}CPU使用率:${NC}"
mpstat 1 1 | tail -2 | awk '{print " " $0}'
# 内存监控
echo -e "${GREEN}内存使用:${NC}"
free -m | grep "^Mem:" | awk '{printf " %s/%sMB (%.1f%%)\n", $3, $2, $3/$2*100}'
# 磁盘监控
echo -e "${GREEN}磁盘I/O:${NC}"
iostat -dx 1 1 | grep -A1 "Device" | tail -n +2
sleep 5
fi
done
# 等待测试结束
echo -e "\n${YELLOW}等待测试结束...${NC}"
wait $cpu_pid $mem_pid $fio_pid
# 清理
rm -rf $test_dir
rm -f /tmp/fio_results.txt
echo -e "\n${GREEN}综合压力测试完成${NC}"
show_system_info
}
# 生成测试报告
generate_report() {
echo -e "\n${CYAN}========== 生成测试报告 ==========${NC}"
report_file="/tmp/stress_test_report_$(date +%Y%m%d_%H%M%S).txt"
{
echo "服务器压力测试报告"
echo "生成时间: $(date)"
echo "========================================"
echo ""
echo "1. 系统信息"
echo "----------------------------------------"
echo "主机名: $(hostname)"
echo "操作系统: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
echo "内核版本: $(uname -r)"
echo "CPU型号: $(lscpu | grep "Model name" | cut -d':' -f2 | xargs)"
echo "CPU核心数: $(nproc)"
echo "总内存: $(free -h | grep "^Mem:" | awk '{print $2}')"
echo "可用内存: $(free -h | grep "^Mem:" | awk '{print $7}')"
echo "磁盘空间: $(df -h / | awk 'NR==2{print $4 " / " $2}')"
echo ""
echo "2. 当前系统状态"
echo "----------------------------------------"
echo "系统负载: $(uptime | awk -F'load average:' '{print $2}')"
echo "运行时间: $(uptime -p)"
echo ""
echo "CPU使用率:"
mpstat 1 1 | tail -3
echo ""
echo "内存使用:"
free -h
echo ""
echo "磁盘使用:"
df -h /
echo ""
echo "3. 测试建议"
echo "----------------------------------------"
echo "- CPU测试建议: 使用 $(nproc) 个核心进行测试"
echo "- 内存测试建议: 不超过 $(free -m | grep "^Mem:" | awk '{printf "%dMB", $7*0.8}')"
echo "- 磁盘测试建议: 在 /tmp 目录进行测试"
echo "- 网络测试建议: 测试到 8.8.8.8 的延迟"
} > "$report_file"
echo -e "${GREEN}报告已生成: ${report_file}${NC}"
echo -e "${YELLOW}报告内容预览:${NC}"
head -30 "$report_file"
}
# 显示主菜单
show_menu() {
clear
echo -e "${PURPLE}========================================${NC}"
echo -e "${CYAN} 服务器压力测试工具 v2.0${NC}"
echo -e "${PURPLE}========================================${NC}"
echo -e "${GREEN}1. 显示系统信息${NC}"
echo -e "${GREEN}2. CPU压力测试${NC}"
echo -e "${GREEN}3. 内存压力测试${NC}"
echo -e "${GREEN}4. 磁盘I/O测试${NC}"
echo -e "${GREEN}5. 网络测试${NC}"
echo -e "${GREEN}6. 综合压力测试${NC}"
echo -e "${GREEN}7. 系统监控仪表板${NC}"
echo -e "${GREEN}8. 生成测试报告${NC}"
echo -e "${GREEN}9. 检查/安装必要工具${NC}"
echo -e "${RED}0. 退出${NC}"
echo -e "${PURPLE}========================================${NC}"
}
# 主函数
main() {
# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
echo -e "${YELLOW}提示: 某些测试可能需要root权限${NC}"
fi
# 检查必要工具
check_tools
while true; do
show_menu
read -p "请选择操作 (0-9): " choice
case $choice in
1) show_system_info ;;
2) cpu_stress_test ;;
3) memory_stress_test ;;
4) disk_io_test ;;
5) network_test ;;
6) comprehensive_test ;;
7) system_monitor ;;
8) generate_report ;;
9) check_tools ;;
0)
echo -e "${CYAN}感谢使用,再见!${NC}"
exit 0
;;
*)
echo -e "${RED}无效选择,请重新输入${NC}"
sleep 1
;;
esac
echo -e "\n${YELLOW}按回车键继续...${NC}"
read
done
}
# 捕获Ctrl+C
trap 'echo -e "\n${RED}检测到中断信号,退出...${NC}"; exit 1' SIGINT
# 运行主函数
main使用说明
1. 保存脚本
将上述脚本保存为 stress-test.sh:
chmod +x stress-test.sh2. 功能特点
全面检测: 自动检查并安装必要的测试工具
多种测试:
- CPU压力测试(支持多种负载类型)
- 内存压力测试(智能计算可用内存)
- 磁盘I/O测试(顺序/随机/混合读写)
- 网络测试(带宽/延迟/路由/监控)
- 综合压力测试(同时测试多个组件)
- 实时监控: 系统监控仪表板
- 报告生成: 自动生成测试报告
- 安全保护: 防止过度使用资源
本文共10972个字符,其中有 1407 个汉字,平均阅读时长 ≈ 43分钟
