作为系统管理员,我经常遇到这样的场景:新开发的应用程序在测试环境运行良好,但一上线就出现性能问题。这时候老板会问:"测试的时候不是好好的吗?"其实问题往往出在测试环境没有模拟真实的生产负载。
真实的生产环境负载通常是混合型的:既有CPU密集型的计算任务,又有内存消耗型的服务,同时还有频繁的磁盘I/O操作。单独测试CPU或内存很难发现系统在复合压力下的瓶颈点。这就是为什么我们需要stress这样的工具来模拟混合负载。
记得有一次,我们上线了一个新的数据分析服务,在测试环境用简单的CPU压力测试表现良好。但上线后用户反映服务响应缓慢,排查发现是内存分配与CPU计算同时进行时产生了资源争用。如果当初做了混合负载测试,这个问题在测试阶段就能被发现。
在大多数Linux发行版中,安装stress非常简单:
bash复制# CentOS/RHEL
sudo yum install epel-release -y
sudo yum install stress -y
# Ubuntu/Debian
sudo apt update
sudo apt install stress -y
stress的工作原理是通过创建多个工作进程来模拟不同类型的系统负载。每个工作进程可以专注于特定类型的资源消耗:
stress的强大之处在于其灵活的参数组合。以下是几个最常用的参数:
bash复制-c, --cpu N # 产生N个CPU工作者
--cpu-ops N # 每个工作者完成N次计算后停止
-m, --vm N # 产生N个内存工作者
--vm-bytes B # 每个内存工作者分配B字节内存
--vm-keep # 保持内存分配不释放
-i, --io N # 产生N个I/O工作者
-d, --hdd N # 产生N个磁盘工作者
--hdd-bytes B # 每个磁盘工作者使用B字节文件
--timeout T # T秒后自动停止测试
假设我们有一台4核CPU、8GB内存的服务器,准备部署一个Web应用。这个应用的特点是:
我们可以这样设计测试:
bash复制stress --cpu 4 --vm 2 --vm-bytes 2G --io 1 --timeout 600
这个命令会:
仅仅产生负载是不够的,我们还需要实时监控系统表现。我常用的监控组合是:
例如,在另一个终端运行:
bash复制watch -n 1 "uptime; free -m; df -h"
这个命令会每秒刷新一次系统负载、内存使用和磁盘空间情况。
当测试运行时,我们需要特别关注这些指标:
有时候我们需要精确控制资源占用率,比如"让CPU使用率保持在30%"。这需要一些计算:
假设服务器有8核CPU,想要30%的CPU使用率:
对应的命令:
bash复制stress --cpu 3 --timeout 300
内存控制更需要谨慎,因为过度分配可能导致OOM(内存溢出)。安全做法是:
bash复制free -m
例如,系统有8GB内存,可用7GB,想占用50%:
bash复制stress --vm 1 --vm-bytes 3G --vm-keep
当CPU、内存和I/O压力同时存在时,系统表现往往不是简单的叠加。常见现象包括:
通过调整不同资源的压力比例,可以更准确地模拟真实场景。
在进行压力测试前,我通常会做这些准备:
应急终止命令:
bash复制pkill stress
# 或者
killall stress
在多年的压力测试中,我遇到过不少"坑":
问题1:测试导致系统完全无响应
解决:使用--timeout参数设置自动停止,或者通过SSH在另一台机器上执行终止命令
问题2:内存测试被OOM Killer终止
解决:逐步增加内存分配量,找到系统实际可用内存上限
问题3:磁盘测试填满分区
解决:使用--hdd-bytes限制测试文件大小,或在独立分区进行测试
一次完整的压力测试应该包括:
我习惯用这个命令收集基线数据:
bash复制sar -u -r -d -n DEV 1 60 > baseline.log
这个命令会记录60秒内的CPU、内存、磁盘和网络统计。
虽然stress简单易用,但在某些场景下可能需要更专业的工具:
不过对于大多数日常的系统稳定性测试,stress已经足够强大。它的优势在于:
在实际工作中,我通常先用stress进行快速验证,发现问题后再用专业工具深入分析。