第三章 测试环境搭建:硬件环境准备、软件环境配置、网络拓扑与带宽规划

说实话,很多PIS系统的性能问题,根源不在代码,而在环境。我见过太多团队,辛辛苦苦写完脚本,结果一跑就崩——最后发现是测试环境搭得不对。这一章,我就带你一步步把环境搭扎实。

3.1 硬件环境准备

硬件是地基。地基不稳,上面再漂亮的楼也是白搭。我个人习惯,先画一张硬件拓扑图,再按图索骥去采购或调配机器。

3.1.1 服务器选型建议

PIS系统通常包含三个核心节点:中心服务器、车站服务器、终端设备。测试环境至少要覆盖这三层。

节点类型 CPU 内存 磁盘 网卡
中心服务器 16核以上 64GB+ SSD 1TB(RAID10) 万兆双口
车站服务器 8核 32GB SSD 512GB 千兆双口
终端模拟机 4核 16GB 普通SATA 千兆
注意: 我曾经在一个项目中,用虚拟机跑中心服务器,结果压测到2000并发时宿主机直接OOM。后来我学乖了——核心节点必须用物理机,或者至少保证宿主机资源独占。

3.1.2 硬件资源隔离

为什么要强调隔离?你想想看,如果压测工具和被测服务跑在同一台机器上,CPU争抢、内存互挤,测试结果能准吗?

  • 压测机独立:至少准备2台压测机,一台跑主压测脚本,一台跑监控采集
  • 数据库独立:数据库服务器不要和业务服务器混用,IO争抢会让你怀疑人生
  • 网络隔离:测试网络和生产网络物理隔离,避免误操作影响线上
我的小技巧: 在硬件到位后,先用 stress 工具跑一轮CPU和内存压力测试,确认硬件没有暗病。我遇到过一台新服务器,内存条插槽接触不良,跑大并发时随机蓝屏,排查了整整两天。

3.2 软件环境配置

硬件搞定,接下来就是软件。这里我按操作系统、数据库、中间件三个维度来讲。

3.2.1 操作系统调优

我建议统一使用 CentOS 7.9 或 Rocky Linux 8.x。为什么?因为PIS系统的中间件大多对RHEL系支持最好。

装完系统后,有几项必须调:

# 1. 关闭防火墙和SELinux(测试环境,别给自己添堵)
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

# 2. 调整文件描述符限制
echo '* soft nofile 655350' >> /etc/security/limits.conf
echo '* hard nofile 655350' >> /etc/security/limits.conf

# 3. 调整内核参数(重点)
cat >> /etc/sysctl.conf << EOF
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
vm.swappiness = 10
EOF
sysctl -p

核心要点: net.core.somaxconn 这个参数,默认128,对于PIS系统来说太小了。车站服务器同时接入上百块终端屏,连接队列一满,新连接直接丢包。我建议至少设到65535。

3.2.2 数据库配置

PIS系统常用的数据库是MySQL 8.0或PostgreSQL 14+。我个人更倾向PostgreSQL,因为它的流复制和并行查询在PIS场景下表现更好。

以PostgreSQL为例,关键配置项:

参数 推荐值 说明
shared_buffers 物理内存的25% 别贪多,超过40%反而会引发内核交换
work_mem 64MB 排序和哈希操作的内存,太大容易OOM
max_connections 500 PIS系统连接数不会太高,但预留余量
wal_buffers 64MB 写日志缓冲区,太小会导致频繁刷盘
避坑指南: 我曾经在压测前忘了调 max_connections,默认100。压测脚本一启动,数据库直接拒绝连接。嗯,那场面,监控面板上一片飘红。从那以后,我每次搭环境第一件事就是检查数据库连接数上限。

3.2.3 中间件配置

PIS系统常用的中间件包括Nginx(反向代理)、Redis(缓存)、RabbitMQ(消息队列)。

Nginx配置要点:

worker_processes auto;
events {
    worker_connections 65535;
    use epoll;
    multi_accept on;
}
http {
    keepalive_timeout 65;
    keepalive_requests 1000;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
}

Redis配置要点:

# 关闭持久化(测试环境,追求性能)
save ""
# 设置最大内存
maxmemory 8gb
maxmemory-policy allkeys-lru
我的经验: Redis的 maxmemory-policy 一定要设。不设的话,内存满了直接报错,PIS系统的实时数据写入就会中断。我建议用 allkeys-lru,对PIS这种缓存场景最合适。

3.3 网络拓扑与带宽规划

网络是PIS系统的生命线。车站到中心、中心到终端,任何一环断了,乘客看到的屏幕就是黑的。

3.3.1 典型网络拓扑

我画一个最简化的三层拓扑:

+----------------+       +----------------+       +----------------+
|  压测客户端     |       |  中心服务器     |       |  数据库服务器   |
| (192.168.1.0/24)|       | (10.0.1.0/24)  |       | (10.0.2.0/24)  |
+-------+--------+       +-------+--------+       +-------+--------+
        |                        |                        |
        |  千兆/万兆              |  万兆                  |  万兆
        |                        |                        |
+-------+------------------------+------------------------+--------+
|                        核心交换机                                  |
|                     (支持VLAN、QoS)                               |
+------------------------------------------------------------------+
        |                        |                        |
        |  千兆                  |  千兆                  |  千兆
+-------+--------+       +-------+--------+       +-------+--------+
|  车站服务器1    |       |  车站服务器2    |       |  终端模拟集群   |
| (172.16.1.0/24)|       | (172.16.2.0/24)|       | (192.168.2.0/24)|
+----------------+       +----------------+       +----------------+

3.3.2 带宽计算模型

带宽怎么算?我有个公式:

单终端带宽 = 视频流码率 + 控制信令带宽 + 心跳带宽
总带宽 = 单终端带宽 × 终端数量 × 冗余系数(通常1.5~2倍)

举个例子:

  • 视频流:1080p H.264,码率4Mbps
  • 控制信令:0.5Mbps
  • 心跳:0.1Mbps
  • 单终端合计:4.6Mbps
  • 1000个终端:4.6Gbps
  • 加冗余(1.5倍):6.9Gbps → 建议万兆链路

注意: 这个计算是理论峰值。实际测试中,视频流会有波动,控制信令有突发。我建议在压测时用 iperf3 打满带宽,验证交换机背板带宽是否够用。有一次我发现,交换机标称万兆,但实际小包转发率只有线速的60%,一压就丢包。

3.3.3 网络延迟与抖动

PIS系统对延迟敏感吗?说实话,视频流可以容忍几百毫秒的延迟,但控制信令不行。车站到中心的控制指令,延迟超过200ms,乘客就能感觉到屏幕切换卡顿。

测试环境建议:

  • 中心到车站:延迟 < 10ms(同城)或 < 50ms(异地)
  • 中心到终端:延迟 < 100ms
  • 抖动(Jitter):< 20ms
避坑指南: 我曾经在异地测试时,忽略了网络抖动。结果压测数据看起来正常,但实际播放视频时频繁卡顿。后来用 mtr 一查,中间有一跳丢包率5%。嗯,从那以后,我每次搭环境都会先跑一轮网络质量测试。

3.4 环境验证清单

环境搭完,别急着跑脚本。先做一轮验证:

  1. 硬件验证stress --cpu 8 --io 4 --vm 2 --vm-bytes 2G --timeout 60s 跑一轮
  2. 网络验证iperf3 -c 服务器IP -t 30 -P 4 测带宽;ping -c 100 服务器IP 测延迟和丢包
  3. 数据库验证pgbench -i -s 100 初始化数据,pgbench -c 50 -T 60 跑压力
  4. 中间件验证:用 redis-benchmark -h 服务器IP -p 6379 -c 50 -n 10000 测Redis
我的习惯: 验证结果记录到一个表格里,每次环境变更后重新跑一遍。这样出了问题,能快速定位是环境变了还是代码变了。省心。

好了,环境搭好,验证通过,下一步就可以开始设计测试场景了。记住一句话:环境搭得越扎实,后面踩的坑越少。