简介:面向Linux运维与性能测试初学者,这份离线安装包解决内网或受限环境下无法通过yum在线获取压测工具的问题。包内以stress-1.0.4源码为主体,含configure、install-sh等构建脚本与说明文档,并附带gcc-g++等共11个rpm依赖包,可先离线补齐编译环境再完成编译安装,同时收录sar相关命令资料,便于压测时同步观察CPU、内存与I/O负载变化。资源共43个文件,涵盖rpm依赖、源码与自动构建脚本、readme及info说明文档等类型,压缩包约46.66MB,需自行解压后按说明逐步执行,适合搭建本地压测实验环境或验证服务器稳定性时参考。目前已有2598人学习下载,可作为CentOS下离线部署压力测试工具的一份可复用实践材料。
1. 离线机房里的 linux 压力测试:stress 为什么值得先装
很多团队把 linux 压力测试理解成跑个分,真正进了离线机房才发现,stress 装不上比压不出数据更常见。stress 是一个很小的压测工具,用几个 worker 就能把 CPU、内存、IO 拉起来,适合在无外网的 CentOS 机器上做上机前自检、故障复现和容量摸底。它不替代业务压测,但胜在依赖少、参数直白、离线可落地。这份资源围绕 CentOS 离线安装展开,把 rpm 依赖闭环和源码编译兜底两条路线拆开,适合手里只有一台跳板机和一堆 rpm 包的运维、测试和开发。先别急着--cpu 128,把安装链路走通才是第一步。
2. 离线装 stress 的 rpm 路线:依赖闭环与三个版本核对点
离线安装最怕“包拷过去了,装不上”。rpm 路线优先,因为它不引入编译工具链,目标机少装几十个开发包,后续卸载也干净。但 rpm 不是把单个stress-*.rpm丢进去就完事,stress 依赖系统 glibc、libm 等基础库,包本身还区分架构和系统大版本。我一般先在联网机上把依赖树拉全,再到离线机做--test预演,最后用ldd和stress --version两道检查收口。这一章按“判断目标机 → 联网机下载 → 离线机安装验证”走一遍,命令可以直接抄,但版本和架构要换成你目标机的实际情况。
2.1 先判断该用 rpm 还是源码:看目标机的 glibc 与工具链
拿到一台离线 CentOS,不要先问“有没有 stress 包”,先看三件事:系统大版本、CPU 架构、glibc 版本。stress 的 rpm 包如果来自更高 glibc 的系统,装上去也会在运行时缺符号;如果目标机连 gcc、make 都没有,源码编译路线就要先补工具链,成本反而更高。下面这组命令不改变系统状态,只是把底账摸清:
cat /etc/centos-release uname -m getconf GNU_LIBC_VERSION command -v gcc || echo "no gcc" command -v make || echo "no make" rpm -q glibc glibc-devel gcc make binutils/etc/centos-release用来看系统大版本,联网机最好和它保持同一大版本;uname -m确认是x86_64还是aarch64,两种架构的 rpm 不能混装;getconf GNU_LIBC_VERSION输出 glibc 版本,后面用rpm -qpR对依赖时用得上。command -v只判断命令是否存在,不会触发安装。rpm -q一次查多个包,缺的会显示package ... is not installed,这行输出就是源码路线要不要补工具链的依据。
判断逻辑不复杂:目标机有额外软件源、能拿到同大版本同架构的 stress rpm,就走 rpm 路线;目标机是裁剪过的系统,rpm 依赖对不上,但有 gcc、make、glibc-devel,就走源码编译;两样都没有,先补离线工具链,或者换一台同版本的联网机做包。不要在本机直接yum install stress碰运气,离线环境里 yum 源大概率不可用,报错信息还会把方向带偏。
注意:
uname -m和 rpm 包名里的架构必须一致,x86_64机器不要装i686包,混装基础库的代价比装不上还大。
2.2 在联网同版本机器上下载 stress 及依赖
下载依赖的机器很关键:同发行版、同大版本、同架构,最好连 glibc 版本也接近。常见做法是找一台能访问软件源的机器,装yum-utils,用yumdownloader --resolve把 stress 和它依赖的 rpm 一起拉到目录里。如果依赖树比较深,repotrack更省心,它会把整棵依赖树都拉下来,包会多,但离线机不容易缺件。
sudo yum install -y yum-utils mkdir -p /tmp/stress-offline sudo yumdownloader --resolve --destdir=/tmp/stress-offline stress # 依赖树较深时,用 repotrack 拉全量依赖 sudo repotrack -p /tmp/stress-offline stress ls -lh /tmp/stress-offlineyum install -y yum-utils是为了拿到yumdownloader和repotrack这两个命令;--resolve表示解析 stress 的依赖并把依赖 rpm 一并下载;--destdir指定输出目录,不要下到默认当前目录;repotrack -p的-p是指定下载路径,它会递归拉依赖,适合离线机缺包多的场景。ls -lh只是确认目录里有哪些包,不要靠文件名猜依赖是否齐全,后面还要用rpm -qpR对。
stress 这个包不一定在基础源里,常见做法是先启用额外软件源再下载。联网机上执行yum info stress能看到包信息就说明源里有;看不到就先解决源的问题,不要从不明来源随手拿一个 rpm。下载完做一次校验和打包,拷到离线机之前核对 sha256,避免传输过程中包损坏:
sha256sum /tmp/stress-offline/*.rpm > /tmp/stress-offline/SHA256SUMS tar -czf stress-offline.tar.gz -C /tmp/stress-offline . sha256sum stress-offline.tar.gzsha256sum把每个 rpm 的校验值写进SHA256SUMS,离线机上可以再跑一次sha256sum -c SHA256SUMS对照;tar -czf把整个目录打成一个包,-C先切到目录再打包,避免包内路径多一层。最后一行输出压缩包的校验值,拷贝后比对一次,能排除大部分“包拷坏了”的低级问题。
2.3 离线机安装与验证:rpm -Uvh 和 ldd 两道检查
离线机上先解包,再用rpm -Uvh --test做预演。--test只检查依赖和冲突,不真正写入系统,这一步能把大部分依赖问题提前暴露出来。预演通过后再实际安装,安装时把同批 rpm 一起给 rpm,让它自己处理同批依赖关系;如果报依赖顺序问题,再用本地 yum 兜底。
mkdir -p /opt/offline/stress tar -xzf stress-offline.tar.gz -C /opt/offline/stress cd /opt/offline/stress sha256sum -c SHA256SUMS sudo rpm -Uvh --test *.rpm sudo rpm -Uvh *.rpmmkdir -p创建固定目录,后面排查问题时路径清楚;tar -xzf解压;sha256sum -c按校验文件逐个核对;rpm -Uvh --test的-U是升级安装,-v输出过程,-h显示进度,--test只测试不落盘。预演通过后去掉--test再执行一次。不要把--nodeps当成万能钥匙,依赖没装全时强行装上去,运行时大概率报error while loading shared libraries,排查成本更高。
如果rpm -Uvh报依赖,先别急着换包,用rpm -qpR看 stress 到底要什么,再用rpm -q看目标机有什么:
rpm -qpR /opt/offline/stress/stress-*.rpm rpm -q glibc libm libgccrpm -qpR查的是“这个 rpm 包要求哪些能力”,输出里常见libc.so.6、libm.so.6以及带版本号的GLIBC_2.x符号;rpm -q查目标机已安装的包版本。两边对不上,就回联网机换同大版本的包,而不是在离线机上硬凑。安装完成后做两道验证:
command -v stress stress --version ldd "$(command -v stress)" rpm -qi stresscommand -v stress确认命令在 PATH 里;stress --version能正常输出版本号,说明动态库加载没问题;ldd看 stress 依赖的动态库有没有not found,有的话就是库缺失或路径不对;rpm -qi stress看包信息,确认装的是预期架构和版本。到这一步,rpm 路线才算闭环。它的边界也很清楚:包干净、安装快,但依赖版本卡得死,目标机和联网机的大版本、架构、glibc 任何一项对不上,都可能白忙一场。
3. 源码编译兜底:从 gcc 工具链到 make install 的离线闭环
rpm 包找不到匹配版本,或者目标机是裁剪过的 CentOS,源码编译就是兜底路线。它的好处是能指定安装前缀、不污染系统包、遇到依赖问题时能看到config.log的具体报错;坏处是离线环境里 gcc、make、glibc-devel 本身也要提前准备,工具链缺一个,configure就过不去。我一般把源码路线当成“有工具链的机器”的备选,不把它当成万能方案。这一章先把工具链盘清楚,再走configure、make、make install,最后处理 PATH 和动态库路径。
3.1 离线工具链盘点:gcc、make、glibc-devel 缺一不可
stress 是 C 程序,编译至少需要 gcc、make、glibc-devel、binutils。gcc提供编译器,make读 Makefile,glibc-devel提供头文件和链接时需要的开发库,binutils提供ld、as这些底层工具。先查目标机有没有:
rpm -q gcc gcc-c++ make glibc-devel binutils command -v gcc make ld gcc --version | head -n1 make --version | head -n1rpm -q一次列出多个包,缺哪个会直接显示;command -v确认命令路径;gcc --version和make --version只取第一行,避免输出太长。gcc-c++对 stress 不是必需,但如果工具链包是一组一起下的,留着也不影响。真正不能缺的是glibc-devel,没有它,configure常见报错是C compiler cannot create executables,看config.log会指向缺头文件或缺crt1.o。
离线机缺工具链时,在联网同版本机器上下载依赖树:
mkdir -p /tmp/build-toolchain sudo yumdownloader --resolve --destdir=/tmp/build-toolchain gcc make glibc-devel binutils tar -czf build-toolchain.tar.gz -C /tmp/build-toolchain .--resolve会把 gcc、make、glibc-devel、binutils 依赖的包一起拉下来,包括cpp、libgcc、kernel-headers这类间接依赖。tar -czf打包后拷到离线机。安装时仍然先--test预演,再实际安装:
mkdir -p /opt/offline/toolchain tar -xzf build-toolchain.tar.gz -C /opt/offline/toolchain cd /opt/offline/toolchain sudo rpm -Uvh --test *.rpm sudo rpm -Uvh *.rpm工具链包数量可能比 stress 本身多得多,这是源码路线在离线环境里的真实成本。预演通过后再装,装完重新执行gcc --version和make --version,确认命令可用。如果目标机已经有完整工具链,这一步可以跳过,直接进源码编译。
3.2 源码包解压、configure 与 make 的参数
源码包从可信来源获取,拷到离线机后先校验再解压。下面用通配符匹配stress-*.tar.gz,不写死版本号,实际文件名以你拿到的包为准:
mkdir -p /opt/offline/src cd /opt/offline/src sha256sum stress-*.tar.gz tar -xzf stress-*.tar.gz cd stress-*/ ./configure --prefix=/usr/local/stress make -j"$(nproc)" sudo make installsha256sum先核对源码包完整性;tar -xzf解压;cd stress-*/进入解压后的源码目录。./configure --prefix=/usr/local/stress把安装前缀指到独立目录,避免覆盖系统自带的命令,也方便后面卸载;make -j"$(nproc)"用当前核数并行编译,nproc输出核数;sudo make install把编译产物装到前缀目录下的bin、man等位置。如果configure报错,先看config.log最后几十行,定位是缺编译器、缺头文件还是链接失败:
tail -n 40 config.logtail -n 40只看最后 40 行,config.log里会记录 configure 实际执行的编译命令和错误输出。常见原因是glibc-devel没装、gcc 不完整、make不可用。不要看到configure失败就直接换源码包,先把日志读明白。
3.3 安装到独立前缀与动态库路径处理
装到/usr/local/stress后,命令不在默认 PATH 里,直接敲stress会提示找不到。常见做法是写一个/etc/profile.d脚本,让登录 shell 自动加上路径:
/usr/local/stress/bin/stress --version echo 'export PATH=/usr/local/stress/bin:$PATH' | sudo tee /etc/profile.d/stress.sh source /etc/profile.d/stress.sh command -v stress第一行用绝对路径验证编译产物能跑;tee把 PATH 配置写到/etc/profile.d/stress.sh,这个目录下的脚本会被登录 shell 读取;source让当前会话立即生效;command -v stress确认现在解析到的是/usr/local/stress/bin/stress。如果stress --version报动态库找不到,先看ldd /usr/local/stress/bin/stress的输出,确认是哪个库缺失。stress 一般只依赖系统基础库,源码编译通常不需要额外改ld.so.conf;如果你自己编了第三方库,才需要处理LD_LIBRARY_PATH或ldconfig,不要一上来就改全局动态库配置。
源码路线的卸载也简单:回到源码目录执行sudo make uninstall,或者直接删掉/usr/local/stress和/etc/profile.d/stress.sh。它的边界是:目标机必须有可用的编译工具链,且内核、cgroup、容器配额允许你压出负载;如果目标机连 gcc 都装不上,或者压测跑在受限容器里,编译得再顺利也看不到真实压力。
4. 压测参数怎么设:CPU、内存、IO 三类场景的跑法与观测
装好 stress 只是拿到工具,参数设错会出现两种极端:一种是压不出负载,看着 CPU 不高、IO 不动,误以为机器很闲;另一种是把机器压死,SSH 断连、OOM killer 出场、磁盘写满。stress 的模型不复杂,每个--cpu启动一个循环计算的 worker,每个--vm启动一个分配内存的 worker,每个--io调用sync(),每个--hdd写临时文件。先把总览跑一遍,再按 CPU、内存、IO 分开调参,最后用vmstat、pidstat、iostat把观测补齐。
stress --cpu 2 --io 1 --vm 1 --vm-bytes 256M --hdd 1 --hdd-bytes 256M --timeout 60s --verbose这一行是混合压测示例:2 个 CPU worker、1 个 io worker、1 个内存 worker 每个分配 256M、1 个 hdd worker 写 256M,持续 60 秒。--timeout是后悔药,到点自动收;--verbose会打印 dispatching 信息,方便确认 worker 有没有起来。混合压测适合做冒烟,不适合定位单项瓶颈,真要分析 CPU、内存、IO,还是分开跑。
4.1 CPU 压测:--cpu 与 --timeout 的配比
CPU 压测最容易翻车的是“把核压满,SSH 进不来”。--cpu N的 N 是 worker 数量,不是百分比;机器有 8 核,--cpu 8就是 8 个 worker 一起跑,系统进程和 SSH 抢不到核,远程操作会明显卡顿。我一般保留 1 个核给系统,压测其余核,并且一定带--timeout:
N=$(nproc) W=$((N - 1)) [ "$W" -lt 1 ] && W=1 stress --cpu "$W" --timeout 300s --verbosenproc取当前可用核数,W=$((N - 1))留一个核,[ "$W" -lt 1 ] && W=1防止单核机器算出 0;--cpu "$W"启动对应数量的 worker;--timeout 300s跑 5 分钟自动结束。如果只想短时间看峰值,把 300s 改成 60s。--backoff可以让 worker 启动时错开,避免瞬间 fork 太多把系统卡住,常见写法是--backoff 100000,单位是微秒。
CPU 压测看三个地方:top里的%Cpu(s)用户态是否接近预期、pidstat里每个 stress 进程的%CPU是否均匀、vmstat 1的r列是否接近 worker 数。如果--cpu 4跑起来只有 1 个核忙,先看容器 CPU quota 和 cgroup 限制,再看 stress 进程是不是被taskset绑到了单核。不要只看top的总利用率,多核机器上总利用率会被平均,单核打满也可能只显示 12%。
4.2 内存压测:--vm、--vm-bytes、--vm-keep 的边界
内存压测的参数要按“每个 worker”算,不是总量。--vm 2 --vm-bytes 256M是 2 个 worker,每个 256M,总分配约 512M;写成--vm-bytes 1G就是每个 worker 1G,2 个 worker 就是 2G。--vm-keep表示保持内存映射不释放,压力更接近“常驻内存”;不加它会循环分配和释放,压力模式不同。第一次跑建议加--vm-keep并控制总量:
# 每个 vm worker 分配 256M,启动 2 个,保持不释放,持续 2 分钟 stress --vm 2 --vm-bytes 256M --vm-keep --timeout 120s --verbose--vm 2是两个内存 worker;--vm-bytes 256M是每个 worker 的分配量;--vm-keep保持映射;--timeout 120s控制持续时间。总量估算为vm * vm-bytes,再留出系统、page cache 和 SSH 的余量,常见做法是不超过可用内存的 50% 到 70%。如果机器上还有业务进程,比例还要往下压。
内存压测期间看free -m的 available、vmstat 1的si/so、dmesg -T | tail -n 30有没有 OOM 记录。si/so持续非零说明开始换页,压力已经打到内存边界;dmesg里出现Out of memory: Killed process说明 OOM killer 已经动手,可能杀的是 stress,也可能杀别的进程。被 OOM 杀掉不是“压测成功”,而是参数越界,降低--vm-bytes或减少--vm数量,不要靠--vm-keep硬顶。
4.3 IO 压测:--io 与 --hdd 不是一回事
--io和--hdd经常被混用,但压力点不同。--io N启动 N 个 worker 调用sync(),把脏页刷盘,压力偏内核回写和块设备队列;--hdd N启动 N 个 worker 创建、写入、删除临时文件,压力偏文件系统和磁盘写。只跑--io不一定能把磁盘写满,只跑--hdd也不等于测了 fsync 路径,两个要按目标分开用。
# sync 压力:4 个 io worker,持续 60 秒 stress --io 4 --timeout 60s --verbose # 文件写入压力:2 个 hdd worker,每个写 512M,指定临时目录 mkdir -p /data/stress-tmp TMPDIR=/data/stress-tmp stress --hdd 2 --hdd-bytes 512M --timeout 120s --verbose--io 4是 4 个 sync worker;--hdd 2是 2 个写文件 worker;--hdd-bytes 512M是每个 worker 写 512M,不是总写入量;TMPDIR=/data/stress-tmp把临时文件目录指到独立数据盘,避免默认写到/tmp把根分区写满。跑完检查临时目录有没有残留
本文还有配套的精品资源,点击获取