第4章 测试环境搭建:操作系统、网络、证书库配置

压测结果靠不靠谱,一半看环境。你想想看,要是测试机本身在跑别的大任务,或者网络频繁丢包,那数据基本就废了。

我个人习惯,先把环境隔离干净。就像切菜前得把砧板擦干净一样——别小看这一步,我见过太多团队最后查问题,发现是测试环境混用了生产证书库。

操作系统选型与优化

PKI 证书 SDK 的压测,首选 Linux。为什么?因为 Linux 的 epoll 机制在处理高并发 TLS 握手时,比 Windows 的 IOCP 稳定太多了。我在项目中遇到过 Windows 下同时建 2000 个连接,CPU 直接飙到 95%,而同样的机器换成 CentOS,CPU 只跑到 45%。

推荐发行版:

  • CentOS 7.9+(兼容性好,毕竟 RHEL 血统)
  • Ubuntu 20.04 LTS(社区活跃,包比较新)
  • 不推荐桌面版,桌面 GUI 会占用中断资源

装完系统,第一步调内核参数。说白了,就是放开文件描述符和 TCP 连接限制。默认 1024 的文件句柄,压 1000 个连接直接就报 Too many open files。

# /etc/sysctl.conf 追加
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
fs.file-max = 1000000

# 生效
sysctl -p

# 用户级别句柄限制
echo 'root soft nofile 1000000' >> /etc/security/limits.conf
echo 'root hard nofile 1000000' >> /etc/security/limits.conf

一个小技巧:记得把压测机和服务器的内核参数都调一遍。我曾遇到过单机压测没问题,但两台机器之间因为 tcp_tw_reuse 没开,导致端口耗尽——那次排查花了我整整一个下午。

网络环境搭建

压测网络必须独立。意思就是压测机和被测服务器在同一个二层网络,中间不要经过路由器 NAT。延迟最好控制在 1ms 以内,不然你测出来的握手时间里有一半是网络开销。

我建议这么搭:

  • 压测机双网卡,一个接管理网络,一个接测试网络
  • 被测服务器同样双网卡,测试网口直连交换机
  • 交换机用“接入层”就行,别用核心交换机——避免其他业务流量干扰
  • 如果只有一个千兆交换机,那压测机千万不能跑其他流量

网络调优方面,我一般关掉防火墙和 SELinux,省得它们偷偷过滤包。

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭 SELinux(临时)
setenforce 0
# 永久禁用:修改 /etc/selinux/config 中 SELINUX=disabled

警告:不要在生产环境的网络链路上做压测。曾经有团队把压测机和生产数据库放在同一个广播域,结果压测流量引发了生产数据库的 TCP 重传风暴,导致线上服务抖动——这锅背不起。

证书库配置

PKI 证书 SDK 通常依赖 OpenSSL 或 NSS。我建议统一用 OpenSSL 1.1.1 系列,因为它是 LTS,并且支持 TLS 1.3。不过要注意:系统自带的 OpenSSL 版本可能比较老,你得手动编译安装。

# 编译 OpenSSL 1.1.1k
wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
tar -xzf openssl-1.1.1k.tar.gz
cd openssl-1.1.1k
./config --prefix=/usr/local/openssl --openssldir=/etc/pki/tls
make -j$(nproc)
make install

# 替换系统链接
mv /usr/bin/openssl /usr/bin/openssl.bak
ln -sf /usr/local/openssl/bin/openssl /usr/bin/openssl
echo "/usr/local/openssl/lib" > /etc/ld.so.conf.d/openssl-1.1.1k.conf
ldconfig

证书库的位置也很关键。SDK 会从 SSL_CERT_DIR 和 SSL_CERT_FILE 读取 CA 证书。如果你没有设置,它会用系统默认路径。但我建议显式指定,因为压测时你可能需要多个 CA 链来回切换。

# 在 /etc/profile.d/ssl.sh 中设置
export SSL_CERT_DIR=/opt/pki_test/certs
export SSL_CERT_FILE=/opt/pki_test/certs/ca-bundle.crt
export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH

# 然后 source /etc/profile.d/ssl.sh

避坑指南:我曾经因为证书库没预加载,导致压测时每次签名都要重新读取磁盘上的证书文件,吞吐量直接下降 3 倍。后来我把所有证书提前 load 到内存里(用 openssl store 或者写一个预加载脚本),问题就解决了。你想想看,证书文件再大也大不过几 MB,预加载一次,整个压测期间都不用磁盘 IO,多香。

还有一个容易忽略的点:时间同步。PKI 证书验证依赖时间戳,如果测试机和服务器时间偏差超过 300 秒,TLS 握手就会失败。

# 使用 chrony 同步
yum install -y chrony
systemctl enable chronyd
systemctl start chronyd
chronyc sources -v   # 确认同步状态

环境测试清单

检查项 命令/方法 预期结果
文件描述符限制 ulimit -n >= 1000000
TCP 端口范围 cat /proc/sys/net/ipv4/ip_local_port_range 1024 65535
网络延迟 ping -c 10 被测IP 平均 < 1ms
OpenSSL 版本 openssl version 1.1.1k
证书目录可读 ls -l $SSL_CERT_DIR/*.pem 所有 .pem 文件存在
时间同步 chronyc tracking System time 偏差 < 10ms

嗯,把这些都跑一遍,环境才算搭好。接下来就可以开始真正的压测脚本了。

核心总结:

  • OS 调优三个重点:文件句柄、TCP 参数、关闭防火墙
  • 网络必须隔离,延迟 < 1ms,带宽 > 1Gbps
  • 证书库要预加载、显式指定路径、时间同步
  • 用清单检查,避免遗漏
测试环境搭建架构图 测试环境搭建架构 压测机 CentOS 7.9 / Ubuntu 20.04 OpenSSL 1.1.1k 句柄限制 > 1000000 被测服务器 PKI 证书 SDK 进程 TLS 1.3 监听端口 防火墙已关闭 隔离网络 千兆交换机直连 延迟 < 1ms 证书库配置 SSL_CERT_DIR / 预加载 / 时间同步 内核参数优化 somaxconn / file-max tcp_tw_reuse 证书预加载 内存缓存 CA 证书 避免每次签名读磁盘 🚧 环境检查清单必须逐项验证