第2章 压测环境搭建:硬件、软件、网络配置

搭建压测环境这件事,听起来就是配几台机器、装个软件对吧?但说实话,我踩过的坑有一大半都出在环境搭建阶段。

你想想看,PKI SDK压测跟普通Web压测不一样。证书签发、CRL查询、OCSP响应,这些操作背后有大量密码学运算。硬件选不对,网络拓扑画不好,最后你测出来的数据根本没法参考。

这一节,我把自己的经验拆开来讲。硬件、软件、网络、OS配置,每个点都带点血泪史。

2.1 硬件选型:别让机器成为瓶颈

我先说结论:压测环境里的服务器,不是越贵越好,而是够用、可控、可复现。

  • PKI服务端:建议用物理机,至少4核8线程、16GB内存、SSD硬盘。我早期用虚拟机做过,结果发现CPU steal time对RSA密钥生成影响特别大,完全测不准。
  • 压测客户端:至少也要4核8线程。如果是模拟上千并发,建议把客户端和服务端放在不同物理机上,避免CPU争抢。
  • 网络:千兆以太网是底线。我用过百兆环境,结果网络延迟成了瓶颈,RTT从0.3ms飙到3ms,根本看不出PKI SDK本身的性能。

我曾经犯过一个低级错误:把客户端和服务端放在同一台机器上做压测,结果CPU打满后,服务端进程响应时间直接翻倍。那周的报告被技术总监批了一顿……从那以后我坚持“压测客户端必须独立部署”。

建议硬件配置参考
角色 CPU核数 内存 硬盘 网络
PKI服务端(签发/CA) ≥8核 ≥32GB NVMe SSD 千兆
压测客户端 ≥4核 ≥16GB SATA SSD 千兆
监控节点(可选) 2核 4GB 普通 百兆即可

2.2 软件栈:选对版本,省一半时间

PKI SDK压测,软件环境主要有三块:操作系统、PKI SDK本身、压测工具。

2.2.1 操作系统

  • Linux(推荐CentOS 7+ 或 Ubuntu 20.04+)。我个人习惯用CentOS 7,因为它内核参数调整起来比较直接。Ubuntu也行,但要注意某些内核参数默认值不同。
  • 内核参数:必须调整net.core.somaxconn、net.ipv4.tcp_tw_reuse、fs.file-max。我见过有人没调somaxconn,结果并发一高就出现“Connection refused”,还以为是SDK的bug。

一个实用的初始化脚本片段:

# 优化TCP连接
echo 65535 > /proc/sys/net/core/somaxconn
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1024000 > /proc/sys/fs/file-max
# 关闭numad(避免CPU亲和性干扰)
systemctl stop numad
systemctl disable numad

2.2.2 PKI SDK版本

使用你最终要上线的同一版本,别拿开发版压测。我记得有一次压测用的是最新beta版,结果性能比正式版高一倍,大家正高兴呢,后来发现beta版里有个算法优化忘了回退……白忙活两周。

2.2.3 压测工具

  • JMeter + 自定义Sampler(需要写少量Java代码调用SDK的API)。优点是报告直观。
  • wrk + Lua脚本:适合纯HTTP/HTTPS接口,但PKI SDK很多操作是内部API调用,不是HTTP,所以JMeter更常见。
  • Go自研客户端:如果你们团队有Go基础,写个简单的并发goroutine调度器也行。我干过这事,写了两天,调试花了两周……不推荐新手。

2.3 网络拓扑:画清楚,别想当然

为什么单独讲网络拓扑?因为PKI压测尤其依赖网络稳定性。你想想,CA签名请求要传证书请求文件,OCSP响应要查数据库,网络抖动会影响每一次往返时间。

压测环境网络拓扑 压测客户端 千兆交换机 PKI服务端 CA数据库 监控节点 图中实线为数据流,虚线为监控流。所有链路均接入同一千兆交换机,避免跨网段。

上面这张拓扑图,是我个人最推荐的“最小可信环境”。注意几点:

  • 压测客户端和服务端之间不要隔防火墙(如果被测场景需要防火墙,那就单独测试防火墙影响)。
  • CA数据库最好独立一台机器,PKI服务端和数据库装一起的话,I/O竞争会让你分不清性能瓶颈在SDK还是数据库。
  • 监控节点(比如Prometheus + Grafana)单独部署,别装在被测机器上,否则监控也会抢CPU。

2.4 操作系统配置要点:隐藏的坑

硬件和软件都到位了,但OS不配好,压测结果照样没法看。我列几个关键点:

核心参数总结:

  • ulimit -n 1024000:文件句柄数限制。不调的话,并发连接数到1000左右就会报"Too many open files"。
  • net.ipv4.tcp_fin_timeout = 30:缩短TIME_WAIT,防止端口耗尽。我曾经在默认参数下压了10分钟,端口全部被占满,连ssh都进不去。
  • net.core.netdev_max_backlog = 10000:提升网卡队列长度,防止突发流量丢失数据包。
  • 关闭irqbalance服务:绑定中断到指定CPU核,减少上下文切换。嗯,这一步在低核数机器上尤其重要。

一个小技巧:压测之前先运行taskset -c 0-3把服务端进程绑定到前4个核,客户端进程绑定到后4个核。这样可以避免双方抢L2缓存,我实测过至少能提升8%的吞吐量。

2.5 验证环境:别一上来就跑全量

环境搭好后,不要急着跑完整压测脚本。先做两个“冒烟测试”:

  1. 单用户测试:发一个证书请求,看SDK能否正常返回。确认返回时间在合理范围(比如RSA2048签名通常在2~5ms)。
  2. 小并发测试:用10个并发线程跑30秒,观察CPU、内存、网络IO是否平稳。如果有异常抖动,先排查环境问题。

我记得有一次冒烟测试发现响应时间波动巨大,查了两天才发现是因为服务器开启了CPU节能模式(intel_pstate),导致频率忽高忽低。后来强制设为performance模式,结果立刻就稳定了。

避坑指南:千万不要在生产环境的备用机上直接开压测。我同事干过一次,结果压测流量把备用机的某条链路打满了,影响了生产业务。压测环境必须物理隔离或者VLAN隔离。

2.6 本章小结

模块 关键操作 常见坑
硬件 服务端≥8核,客户端独立部署 虚拟机CPU steal time干扰
软件 内核参数调整、同版本SDK 忘调somaxconn导致连接拒绝
网络拓扑 千兆交换机直连,数据库分离 防火墙未关导致延迟异常
OS配置 ulimit、tcp参数、CPU绑定 CPU节能模式影响性能稳定性
环境验证 单用户+小并发冒烟测试 跳过验证直接全量压测,数据无效