简介:面向CentOS Linux服务器运维与性能测试场景,这套离线资源包解决无外网环境下压力测试工具链的部署难题,适配需要在内网机房、隔离网络或离线交付环境中工作的系统管理员、运维工程师及性能测试人员,可快速搭建压测环境。压缩包内共43个文件,整体大小约46.66MB,以11个rpm二进制安装包为核心组件,辅以configure配置脚本、install-sh安装脚本、m4宏定义文件、texi格式说明文档等编译配套材料,readme与changelog记录版本迭代信息,c源码文件支持按需定制。资源集成stress-1.0.4压力测试工具及sar命令所需依赖组件,可在完全离线条件下批量部署,实现对CPU、内存、磁盘I/O及系统负载等多维度持续施压,配合sar命令可同步采集压测过程中的性能指标,便于后续分析。目前已有2587人学习下载。适合需要在内网或隔离环境中统筹压测工具链的读者;包内目录结构清晰,可依据需求选择对应组件安装,直接开展压测实践与结果分析,省去逐项排查在线依赖与版本匹配的步骤。
1. 离线安装 stress:先搞清楚它为什么让你卡在最前面
你在新装好的 CentOS 服务器上敲下yum -y install stress,几秒后收到一行No package stress available。这台机器在内网,没有外网源,默认仓库里翻遍了也没有 stress;它属于 EPEL 扩展仓库,而内网机器往往连 epel 的域名都解析不了。这个场景在服务器运维里再常见不过:要做压测,先得把这个小工具装上。本文只解决一件事——在 CentOS 离线环境下,把 stress 的 rpm 包从有网的准备机带进内网,按 rpm 依赖或本地 yum 源两种方式装好,然后正确地对 CPU、内存和磁盘做压力验证。适合机房运维、性能测试工程师,以及正在搭离线软件包仓库的同事参考。
2. 离线安装前的准备:rpm 还是本地 yum 源,按场景选
2.1 先理解 stress 的 rpm 依赖关系,决定要带几个包
很多人第一次离线装 stress 时,以为要在外网机器上把整个 epel 仓库打包拷进去,其实不用。stress 是个很轻的工具,安装包本身只有几十 KB,编译时链接了 glibc 的libc.so.6,所以它最终真正依赖的只有 CentOS 系统自带的 glibc。也就是说,你只要拿到 stress 本体 rpm,多数情况下直接rpm -ivh就能成功。真正让离线安装翻车的,从来不是依赖数量太多,而是你拿错了架构或拿错了 el 版本。
不过“多数情况下能直接装”不等于可以闭着眼睛拷。稳妥的做法是先在准备机上把依赖关系打印出来看一遍,再决定要带哪几个包。准备机和目标机必须保持同一个大版本,比如都是 CentOS 7,否则后面会遇到 el 版本冲突的问题。
# 在准备机上执行,先确保 epel 仓库可用 yum install -y epel-release yum-utils yum deplist stress | grep -E "dependency:|provider:"yum deplist的输出大致是dependency: libc.so.6()(64bit),provider: glibc-2.17-xxx.el7.x86_64。这说明 stress 需要 64 位 glibc 提供libc.so.6,而 CentOS 7 最小化安装默认就带 glibc 2.17,目标机不用额外处理。真正要看的是 provider 那行里的 glibc 版本:如果准备机比目标机新很多,或者你把 el8 的 stress 包带到了 CentOS 7 上,安装时就会报GLIBC_2.14 not found一类的符号缺失。先执行一次rpm -q glibc对一下,能省掉后面大量排查时间。
2.2 用 yumdownloader 在准备机上把依赖一次带齐
确定依赖之后,下一步是把需要的 rpm 文件从准备机上拉下来。常见做法是用yumdownloader --resolve,它会自动把 stress 本体以及所有缺失依赖一起下载到当前目录。这个命令来自 yum-utils 包,所以第一步先把它装好。
mkdir -p /data/stress-rpms cd /data/stress-rpms yumdownloader --resolve stress ls -lh *.rpm--resolve的含义是“下载时同时解析依赖并一并拉取”,目标是让这个目录在内网机器上变成一个自洽的安装集合。如果你只想要 stress 本体,可以不加--resolve,但考虑到内网机器缺包时补货成本极高,我一般会连依赖一起带。下载完成之后,把目录里的 rpm 全部拷进 U 盘或内网文件服务器,再复制到目标机。拷完不要急着装,先做一步校验:sha256sum *.rpm与准备机上的输出对比一下。离线环境里最常见的低级事故,就是 U 盘拷贝中 rpm 损坏,导致安装时报“rpm 包校验失败”或装完一跑就段错误。
2.3 多台机器批量装:用 createrepo 做本地 yum 源,而不是手工 rpm
如果你只是给一台机器装,手工rpm -ivh最直接;如果要推五台十台,我建议改用本地 yum 源。这里的逻辑是:yum 只认仓库不认目录,rpm 文件即使躺在磁盘上,yum 也不会自动感知它。createrepo 会给这个目录生成 repodata 元数据,再配一个baseurl=file://的 repo 文件,内网机器就能像使用外网源一样,让 yum 自己解析依赖关系并安装。
# CentOS 7 上安装 createrepo,CentOS 8 用 dnf install -y createrepo_c yum install -y createrepo createrepo /data/stress-rpms cat > /etc/yum.repos.d/local-stress.repo << 'EOF' [local-stress] name=Local Stress RPMS baseurl=file:///data/stress-rpms enabled=1 gpgcheck=0 EOF yum clean all yum install -y stress这里baseurl=file:///data/stress-rpms指向 2.2 中准备好的目录,gpgcheck=0是因为离线包的来源固定,且你很难把 rpm 签名对应的公钥也一起带进来。如果公司安全规范要求验签,就把准备机上的公钥导出带到内网,并把这个值改为1。重点提醒:createrepo之后目录里会多出一个repodata/子目录,拷贝时要整目录复制,只拷 rpm 文件的话 yum 依然识别不了。
3. 手工 rpm 离线安装:从依赖查找到安装成功的完整过程
3.1 目标机先自查:架构与 glibc 版本,两条缺一不可
拿到 rpm 包之后别急着装,先在目标机上执行三句自查命令。很多离线安装失败,不是包本身的问题,而是目标机的基础环境和准备机不一致。
uname -m rpm -q glibc ldd --version | head -n1uname -m输出x86_64说明是 64 位系统,stress 的 rpm 包必须也是 x86_64 架构;如果输出i686或i386,你得去准备机上找 32 位版本的包。rpm -q glibc确认系统里 glibc 是否完整,最小化安装的 CentOS 都会带,但如果你做过精简裁剪,这里可能会发现 glibc 缺失。ldd --version第一行是 glibc 具体版本号,比如2.17,把它和 stress rpm 包要求的最低版本做对比。这几个命令的输出记下来,后面几乎所有依赖排查都要回来看它们。
3.2 拷贝 rpm 并安装:rpm -ivh 与 rpm -Uvh 的差别
把 rpm 文件复制到目标机的/data/stress-rpms目录后,执行安装命令。首选rpm -ivh,因为它是“安装”语义,对全新系统最直观;如果系统里已经存在 stress,它会明确提示package stress-XXX is already installed,这时再用-Uvh做升级。
rpm -ivh /data/stress-rpms/stress-*.rpm-i是 install,-v是显示详细输出,-h是打印进度条,连起来足够看到每个 rpm 的安装过程。如果目录里有多个依赖 rpm,可以直接用通配符一次装完,rpm 会在同一个事务里检查所有包的依赖关系,缺哪个会一次性列出来。看到error: Failed dependencies:时不要慌,它列出的每一项都是当前系统缺失的库或符号。最常出现的libc.so.6()(64bit) is needed,基本可以判定你拿错了架构,回到 3.1 再核对一遍。如果依赖缺失列表中出现了libstdc++.so.6这类 C++ 运行库,说明目标机没有装 gcc 的运行时环境,去准备机把libstdc++的 rpm 一并下载带回来即可。
3.3 安装后用哪三个命令验证才算真正成功
安装命令返回成功不代表能用,尤其是离线拷包场景。我验证 stress 安装是否真正成功,固定用下面三个命令,而不是只看一眼 rpm 输出。
which stress rpm -q stress stress --versionwhich stress确认二进制文件落在 PATH 里,一般会在/usr/bin/stress。rpm -q stress的输出如果是一串stress-1.0.4-16.el7.x86_64这样的版本号,说明它已经写入 rpmdb,后续卸载可以用rpm -e stress管理。stress --version是真正执行它,能跑出版本号说明动态库链接正常,这一步最能暴露“rpm 装上了但运行时缺符号”的问题。注意:如果执行stress --version时系统无法打开共享库文件,回到 3.1 对比 glibc 版本,不要盲目重装。
4. 装完别急着跑:用 stress 压 CPU、内存的正确与验证方法
4.1 stress 常用参数:-c、-m、-d、-i、-t 到底什么意思
stress 的命令行参数很朴素,但每条都有明确分工。压测前先背熟这张表,后面所有脚本都围着它转。
| 参数 | 全名 | 作用 | 常用值 |
|---|---|---|---|
-c N | --cpu N | 产生 N 个进程反复计算平方根,占满 N 个逻辑 CPU | 小于等于逻辑核数 |
-m N | --vm N | 产生 N 个进程不断分配并释放内存 | 由内存总量决定 |
-d N | --hdd N | 产生 N 个进程反复写入并删除临时文件 | 1~4 |
-i N | --io N | 产生 N 个进程反复调用 sync() | 1~2 |
-t N | --timeout N | 持续 N 秒后自动退出 | 压测时长 |
--vm-bytes B | 每个 vm 进程分配的内存字节数 | 不设默认 256MB | 512M / 1G |
--vm-hang N | 分配后挂起 N 秒再释放 | 模拟内存驻留场景 | 10~60 |
--hdd-bytes B | 磁盘进程单次写入字节数 | 用大值才看得出磁盘水位 | 1G |
很多人误以为-c 1只占“半核”,其实 sqrt 运算是纯 CPU 计算,进程几乎不睡眠,调度器把它塞进一个逻辑核就能把该核跑满。在超线程机器上负载读数会有些波动,不用太纠结,看/proc/loadavg的第一列即可。-m 1默认分配 256MB 内存,多个 vm 进程叠起来会迅速耗尽内存,压测脚本里最容易把机器搞挂的就是它,所以单独压内存时务必配合--vm-bytes。
4.2 最小压测命令:4 个 CPU 进程跑 60 秒
先跑一条最小命令,验证 stress 能拉高负载。这台机器如果是 4 逻辑核,用-c 4让它产生 4 个进程,-t 60让它 60 秒后自动退出。
stress -c 4 -t 60 watch -n 1 cat /proc/loadavgwatch -n 1每秒刷新一次/proc/loadavg,你会看到第一个数字在 5 秒内迅速爬到 4.0 附近。注意,它不会超过 4,因为 stress 的 CPU 进程数由-c显式控制,不是按机器核数自动扩展的。如果负载卡在很低的数值上,先查 cgroup 的 CPU 限额:cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us配合cpu.cfs_period_us计算一下当前容器或控制组允许使用的 CPU 配额,配额不足时 stress 也会被限流。
4.3 压内存与磁盘:为什么 --vm-bytes 不设会“白压”
只写-m 2的压测效果,在一台 64G 内存的服务器上几乎看不到水位:两个进程各分配 256MB,总占用才 512MB。所以压内存的标准写法是显式指定--vm-bytes,让单进程分配量直接压到内存总量的几分之一。
stress -m 2 --vm-bytes 512M -t 60 free -h压磁盘时同理,-d 1默认每个进程每次写 1GB 数据再删除,在一台 SSD 机器上可能不到几秒就完成一轮,磁盘 util 看不出持续压力。用--hdd-bytes 1G配合-d 1时,iostat -x 1里的%util才会稳定在较高水平。注意:stress 的磁盘压测会在当前目录或/tmp下创建临时文件,跑完自动删除。如果目标目录写入权限不全,磁盘压测会直接报错退出,先cd /tmp或指定一个有写权限的工作目录。
4.4 结束压测的三种方式
压测时长失控是运维事故的高发点,这里给你三种收尾手段。第一种是正规做法:所有压测命令都带-t,时间到了 stress 自动退出,退出码为 0。第二种是手动中断:前台运行时按Ctrl+C,stress 收到 SIGINT 会清理临时文件后退出。第三种是强制终止:进程已经失控、Ctrl+C 不管用的时候,执行pkill -x stress。
-x表示精确匹配进程名,只杀 stress,不会误伤名字包含 stress 的其他程序。需要特别注意的是,SIGKILL强杀之后,部分 hdd 临时文件可能来不及清理,压测结束后检查一下/tmp下有没有stress.*.前缀的残留文件,有就手动删掉。这个细节不处理,下次跑同一台机器的磁盘压测时,残留文件累计起来会把磁盘空间吃满。
5. 离线安装 stress 的避坑记录:四条翻车现场与处理办法
5.1 No package stress available:epel-release 没装,别急着怪离线
现象:在目标机上执行yum install -y stress,结果报No package stress available,于是以为离线环境装不了。
原因:CentOS 官方 base 仓库里没有 stress,它存放在 EPEL(Extra Packages for Enterprise Linux)仓库里。目标机没有安装 epel-release,yum 根本不知道有这个包存在,和离线无关。
解决:在准备机上下载epel-release-latest-7.noarch.rpm(CentOS 8 对应 epel-release-latest-8),拷到目标机用rpm -ivh装掉,再执行yum install -y stress。如果目标机连 epel 域名也访问不了,那就直接跳过 yum,用第二章的方法把 stress 本体 rpm 拷进去手工安装,这是离线场景最常见也最可靠的路径。
5.2 提示缺少 libc.so.6()(64bit):八成是你拿错了架构包
现象:rpm -ivh stress-*.rpm时,一条error: Failed dependencies: libc.so.6()(64bit) is needed by stress-...直接拦住安装。
原因:错误信息里的(64bit)是关键。它说明当前 rpm 包是 64 位系统上的版本,你的机器系统架构不匹配。最常见的情况是把 i686(32 位)的 stress 包拷到了 x86_64 机器上,或者是反过来。不要一看到“依赖缺失”就去准备机下载一堆 glibc,先敲uname -m看看架构,再核对 rpm 包名里是否带x86_64。
解决:去准备机上重新下载对应架构的 rpm。判断方法很简单:uname -m是x86_64,就只认文件名里带x86_64的包;uname -m是i686,就找i686的包。架构对齐之后,这条报错基本不会再出现。
5.3 el7 的包硬装到 CentOS 8,反过来也不行
现象:CentOS 8 机器上安装 CentOS 7 的 stress rpm,报错信息像package stress-1.0.5-1.el7.x86_64 is intended for a different operating system,或者装完之后一执行就提示GLIBC_2.28 not found。
原因:el7 和 el8 的 rpm 包编译时链接的 glibc 版本基线不同。el7 的包在 CentOS 8 上装不上,el8 的包在 CentOS 7 上会因为系统 glibc 版本过低而运行失败。这些都是“拿错源”导致的,不是 stress 本身有问题。
解决:准备机上做yumdownloader时就要指定清楚目标系统。如果目标机是 CentOS 7.9,就在 CentOS 7.9 的机器上下包;目标机是 CentOS 8.5,就在 CentOS 8.5 的环境上下包。我一般会在目录名上直接标注 el 版本,比如stress-rpms-el7/、stress-rpms-el8/,避免拷错。
5.4 手工拷了 rpm 包,yum localinstall 却总是报找不到
现象:把 rpm 文件放在目标机的/data目录后,执行yum localinstall /data/stress-*.rpm,提示依赖无法解析或根本找不到本地文件。
原因:yum localinstall的依赖解析仍然依赖已配置的 yum 仓库。如果 stress 的依赖包不在当前系统里,而系统又没有可用仓库,它就解不了依赖;另外,通配符在某些版本里还会把整套 repodata 缺失也当错误抛出来。
解决:如果你依赖齐全,直接用rpm -ivh /data/stress-*.rpm最省事,不用给 yum 参与的机会。如果你希望 yum 来解析依赖,就不要用localinstall,而是像 2.3 节那样createrepo出本地源,再yum install -y stress。这两条路选一条走到头,别混着来。
5.5 本地源配好了,yum install 还是说找不到包
现象:repo 文件写好,baseurl=file:///data/stress-rpms也确认无误,但yum install stress仍然报No package stress available。
原因:yum 有缓存机制。仓库元数据第一次生成后,yum 会把 repomd.xml 缓存下来,后续访问不再重新读取磁盘目录;如果 createrepo 是在拷贝之后才执行的,或者目录内容有过变化,旧缓存就会失效。
解决:执行yum clean all清掉缓存,再跑yum makecache重建,最后yum repolist确认local-stress出现在仓库列表里。还有一个经常踩中的细节:repo 文件如果是从别处复制的,检查enabled=1是不是被改成了0,以及文件有没有放在/etc/yum.repos.d/目录下并以后缀.repo结尾。
6. 把离线包做成可复用的部署目录:脚本化后下次不再重复踩坑
离线安装做到第三次,我就开始厌倦重复敲命令了。现在我的习惯是维护一个固定的离线部署目录,里面除了 rpm 文件,还有一份校验文件和一段部署脚本。这个目录无论换到哪台内网机器,一条命令装完,跑一个 5 秒的冒烟测试,确认能用再离开。
#!/bin/bash # deploy_stress_offline.sh # 用法: bash deploy_stress_offline.sh /path/to/rpms set -euo pipefail RPMS_DIR="${1:-/opt/stress-rpms}" EXPECTED_ARCH="x86_64" if [ "$(uname -m)" != "$EXPECTED_ARCH" ]; then echo "架构不匹配,当前 $(uname -m),需要 $EXPECTED_ARCH" exit 1 fi rpm -q stress >/dev/null 2>&1 && { echo "stress 已安装: $(rpm -q stress)" exit 0 } ls "$RPMS_DIR"/*.rpm >/dev/null 2>&1 || { echo "目录 $RPMS_DIR 里没有 rpm 文件" exit 1 } rpm -ivh "$RPMS_DIR"/*.rpm stress --version stress -c 1 -t 5脚本里set -euo pipefail的作用是:任何一条命令失败就立即退出,避免在依赖缺失的情况下继续往下跑,最后留下一个半装状态。rpm -q stress先做幂等检查,已经装过的机器直接跳过,不用重复装。安装之后紧接着执行stress --version和stress -c 1 -t 5冒烟测试,前者验证动态库链接正常,后者验证 CPU 进程真的能拉起来。冒烟测试退出码为非 0 时,脚本会因为set -e直接中断,不会让你误以为装成功了。
再补一条我踩过的问题:不要在同一个目录里混放多个 el 版本或架构不同的 rpm。rpm -ivh "$RPMS_DIR"/*.rpm会把目录里所有包都装一遍,混放时可能同时装进两个版本,后面的包覆盖前面的,排查起来比直接报错还麻烦。我的习惯是每个小版本一个子目录,目录名带 el 标识,拷贝时整目录搬运。
校验这一步也放在部署目录里:准备机上生成sha256sum *.rpm > CHECKSUMS,把 CHECKSUMS 文件一起拷进 U 盘,目标机上执行sha256sum -c CHECKSUMS确认所有包完整。有次我图省事跳过校验,拷贝的 rpm 在 U 盘里损坏了,装完一跑stress --version就报错,折腾到最后发现是包的问题。从那以后,我的离线部署目录里永远放一份 CHECKSUMS 文件。这套方法不只适用于 stress,你换成其他离线 rpm 包同样能用,希望帮到你。
本文还有配套的精品资源,点击获取