第一章:测试环境搭建——硬件选型、操作系统调优与网络配置
大家好,我是你们的老朋友。今天咱们聊聊交易网关压力测试的第一步——环境搭建。说实话,我见过太多团队,一上来就猛怼压测工具,结果跑出来的数据根本没法看。为什么?因为底层环境没打好。你想想看,地基不稳,楼盖得再高也是危房。
这一章,我会从硬件选型、操作系统调优、网络配置三个维度,把我在实战中踩过的坑、总结的经验,一股脑儿倒给你们。
1.1 硬件选型建议
硬件选型这事儿,说白了就是「钱要花在刀刃上」。交易网关对硬件的要求,跟普通Web服务完全不一样。我个人的习惯是:CPU要快,内存要大,网卡要狠。
CPU:主频优先,核心数其次
交易网关是典型的延迟敏感型应用。你想想,一笔订单从客户端发出到网关确认,中间经过的CPU指令越少越好。高频CPU能显著降低单笔交易的延迟。我在项目中遇到过,同样的代码,从2.5GHz换到3.8GHz的CPU,P99延迟直接降了30%。
- 推荐型号:Intel Xeon Gold 6xxx系列(高频版)或AMD EPYC 7xx3系列(高频版)
- 核心数:16-32核足够,别盲目堆核。核心太多反而会导致NUMA跨节点访问,增加延迟。
- 缓存:L3缓存越大越好,建议≥30MB。缓存命中率高,能减少内存访问次数。
内存:大容量 + 低延迟
交易网关的内存主要用来缓存订单状态、会话信息。我建议至少64GB起步,如果做全量日志缓存,128GB也不嫌多。内存频率也很关键,DDR5-4800比DDR4-3200在内存密集型操作上快不少。
- 推荐配置:128GB DDR5-4800 ECC内存
- 注意:ECC内存必须上,交易数据容不得半点错误。
网卡:万兆起步,多队列必备
网卡是交易网关的「咽喉」。我见过有人用千兆网卡跑压测,结果网卡先成了瓶颈。万兆网卡是底线,25Gbps或40Gbps更佳。网卡多队列功能必须支持,否则CPU单核处理中断会累死。
- 推荐型号:Mellanox ConnectX-5/6(25Gbps/100Gbps)或Intel E810(25Gbps/100Gbps)
- 关键特性:RSS(接收端缩放)、多队列、硬件卸载(如TCP分段卸载)
核心原则:硬件选型时,先算好你的峰值吞吐量。比如目标10万笔/秒,每笔交易平均1KB数据,那网卡带宽至少需要10万×1KB×8 = 800Mbps,再加上协议开销,万兆网卡是底线。
1.2 操作系统调优(Linux内核参数)
操作系统调优,说白了就是让Linux内核更「听话」。默认的内核参数是为通用场景设计的,对交易网关这种低延迟、高吞吐的应用来说,很多参数需要调整。嗯,这里要注意,调优不是乱调,每改一个参数都要知道为什么。
网络栈调优
交易网关的网络I/O非常密集,网络栈的调优是重中之重。我习惯从这几个参数入手:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| net.core.rmem_max | 16777216 | 接收缓冲区最大值,防止丢包 |
| net.core.wmem_max | 16777216 | 发送缓冲区最大值 |
| net.ipv4.tcp_rmem | 4096 87380 16777216 | TCP接收缓冲区(最小、默认、最大) |
| net.ipv4.tcp_wmem | 4096 65536 16777216 | TCP发送缓冲区 |
| net.core.netdev_budget | 600 | 网卡中断处理预算,提高吞吐 |
| net.ipv4.tcp_fastopen | 3 | 启用TCP快速打开,减少握手延迟 |
小技巧:我曾经在压测时发现丢包率很高,查了半天发现是rmem_max设得太小。改成16MB后,丢包率直接降为0。记住,交易网关的缓冲区不能省。
内存与调度调优
交易网关对内存延迟和CPU调度非常敏感。我建议关闭NUMA balancing,避免内存页在节点间迁移带来的延迟。同时,将进程绑定到特定CPU核心,减少上下文切换。
# 关闭NUMA balancing
echo 0 > /proc/sys/kernel/numa_balancing
# 设置vm.swappiness为0,避免交换
echo 0 > /proc/sys/vm/swappiness
# 设置进程的CPU亲和性(以PID 1234为例)
taskset -cp 0-3 1234
# 设置中断亲和性,将网卡中断绑定到特定核心
echo 2 > /proc/irq/<irq_number>/smp_affinity
警告:关闭NUMA balancing后,如果内存分配不均匀,可能导致跨节点访问。建议在启动交易网关时,使用numactl绑定内存节点和CPU节点。
1.3 网络配置(网卡多队列、RPS/RFS)
网络配置是压测环境搭建中最容易被忽视的一环。很多人以为插上网线就能跑,结果压测时单核CPU飙到100%,其他核心在「看戏」。为什么会这样?因为网卡中断默认只发到一个核心上。
网卡多队列
网卡多队列(RSS,Receive Side Scaling)能让网卡把接收到的数据包分散到多个CPU核心处理。说白了,就是让多个核心「一起干活」,而不是一个核心累死。
我建议每个队列绑定一个CPU核心。比如你有16个核心,网卡支持8个队列,那就绑定8个核心。剩下的核心留给应用处理逻辑。
# 查看网卡支持的队列数
ethtool -l eth0
# 设置队列数为8
ethtool -L eth0 combined 8
# 查看当前队列的中断号
cat /proc/interrupts | grep eth0
# 将每个中断绑定到不同核心(以中断号130-137为例)
echo 1 > /proc/irq/130/smp_affinity
echo 2 > /proc/irq/131/smp_affinity
echo 4 > /proc/irq/132/smp_affinity
echo 8 > /proc/irq/133/smp_affinity
echo 10 > /proc/irq/134/smp_affinity
echo 20 > /proc/irq/135/smp_affinity
echo 40 > /proc/irq/136/smp_affinity
echo 80 > /proc/irq/137/smp_affinity
经验之谈:我在一个项目中,网卡只有4个队列,但服务器有32核。结果压测时,4个核心忙死,其他28个核心闲死。后来换了支持16队列的网卡,吞吐量直接翻倍。所以,队列数一定要匹配核心数。
RPS/RFS:软件层面的多队列
如果网卡不支持硬件多队列,或者队列数不够,可以用RPS(Receive Packet Steering)和RFS(Receive Flow Steering)在软件层面实现类似效果。RPS负责把数据包分发到不同核心,RFS则保证同一个流的数据包始终由同一个核心处理,避免缓存失效。
# 启用RPS,将eth0的队列0分发到核心0-7
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus
# 启用RFS,设置流表大小
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
避坑指南:我曾经在压测时发现,RPS虽然能分散中断,但会导致CPU缓存频繁失效,性能反而下降。后来我改用硬件多队列+RFS的组合,效果好了很多。所以,硬件多队列优先,RPS/RFS只是备选方案。
知识体系总览
下面这张图,是我自己画的测试环境搭建知识体系。你可以把它当作一个「检查清单」,每做完一项就打个勾。
好了,这一章的内容就到这里。环境搭建是压测的「地基」,地基打好了,后面的压测才能跑出真实数据。下一章,我们会聊压测工具的选择和脚本编写,到时候见。