26、TURN 服务器测试:使用 turnutils_uclient 工具测试 TURN 服务器性能和带宽

聊到 WebRTC 的 TURN 服务器,很多人的第一反应就是「这玩意儿是保底的,能用就行」。嗯,我以前也这么想。直到有一次线上会议,用户反馈视频卡成幻灯片,排查了半天才发现是 TURN 服务器带宽扛不住了。从那以后,我养成了一个习惯——上线前必须用 turnutils_uclient 跑一轮压力测试。

说白了,TURN 服务器就是你的媒体流中继。它扛不住,你的用户就掉线。今天我们就来聊聊怎么用 turnutils_uclient 这个工具,把 TURN 服务器的性能和带宽测个明明白白。

为什么需要测试 TURN 服务器?

你可能觉得,TURN 服务器不就是转发数据包吗?能有多复杂?

其实不然。TURN 服务器要处理的是实时音视频流,对延迟、丢包、吞吐量都有严格要求。我见过不少项目,TURN 服务器配置看着没问题,但一上量就崩。原因无非这几点:

  • 带宽瓶颈:服务器出口带宽不够,多路并发直接打满
  • CPU 过载:加解密和转发消耗过高,导致丢包
  • 连接数限制:系统参数没调优,大量 UDP 连接被内核丢弃
  • 网络抖动:服务器所在机房到用户链路的稳定性差

所以,测试不是可选项,是必选项。

turnutils_uclient 是什么?

turnutils_uclient 是 coturn 项目自带的客户端测试工具。它模拟多个 WebRTC 客户端,向 TURN 服务器发送媒体流,然后统计延迟、丢包、吞吐量等指标。

我个人觉得,这工具最大的好处是——它真的在发 RTP/RTCP 包,而不是简单的 ping。测出来的数据,基本能反映真实场景下的表现。

安装与准备

首先,你得有 coturn 环境。如果你已经部署了 TURN 服务器,那客户端工具通常也在同一套源码里。

# 从源码编译 coturn(包含 uclient)
git clone https://github.com/coturn/coturn.git
cd coturn
./configure
make
sudo make install

# 验证工具是否安装成功
turnutils_uclient -h

如果看到帮助信息,说明安装成功。注意,turnutils_uclient 默认编译在 bin/ 目录下,你可能需要指定路径或加入环境变量。

注意: 编译前确保系统安装了 libevent、openssl 等依赖。我在 CentOS 上遇到过缺少 libevent-devel 导致编译失败的情况,提前装好能省不少时间。

基础测试:单路连通性

先跑一个最简单的测试,确认客户端能和 TURN 服务器正常通信。

turnutils_uclient \
  -t -T \
  -p 3478 \
  -u testuser \
  -w testpass \
  -l 100 \
  192.168.1.100

参数说明:

  • -t:使用 TCP 协议(默认是 UDP)
  • -T:启用 TURN 模式(而不是 STUN)
  • -p 3478:TURN 服务器端口
  • -u / -w:认证用户名和密码
  • -l 100:测试时长 100 秒
  • 192.168.1.100:TURN 服务器 IP

如果输出中看到 Allocation successRelay address,说明连接成功。这时候 TURN 服务器已经为客户端分配了中继地址。

小技巧: 第一次测试建议用 TCP,因为 UDP 容易被防火墙拦截。确认连通后,再切回 UDP 做性能测试。

性能测试:多路并发与带宽压测

单路通了,接下来就是上强度。我会模拟 10 个、50 个、甚至 100 个并发客户端,看看服务器能扛到什么程度。

# 模拟 50 路并发,每路发送 1Mbps 的流量
turnutils_uclient \
  -t \
  -p 3478 \
  -u testuser \
  -w testpass \
  -l 60 \
  -m 50 \
  -B 1000 \
  -L 1000 \
  -c 10 \
  192.168.1.100

新增参数:

  • -m 50:并发客户端数量(模拟 50 个用户)
  • -B 1000:每个客户端的发送带宽(Kbps),这里 1000 就是 1Mbps
  • -L 1000:每个客户端的接收带宽(Kbps)
  • -c 10:每个客户端创建 10 个 channel(模拟多路媒体流)

跑起来之后,你会看到类似这样的输出:

Total send: 51200 packets, 65536000 bytes
Total recv: 50980 packets, 65254400 bytes
Packet loss: 0.43%
Average delay: 12.3 ms
Max delay: 45.7 ms

重点关注几个指标:

  • Packet loss:丢包率,超过 1% 就要警惕
  • Average delay:平均延迟,理想值在 50ms 以内
  • Max delay:最大延迟,如果超过 200ms,用户体验会明显变差
  • Total send / recv:发送和接收的总数据量,差值就是丢包

带宽测试:找到服务器的极限

我曾经帮一个客户排查问题,他们的 TURN 服务器配置了 1Gbps 的网卡,但实际只能跑 200Mbps。原因是什么?是 CPU 瓶颈。加解密操作把 CPU 吃满了,网卡根本跑不满。

所以,带宽测试要分两步走:

第一步:逐步增加并发数

从 10 路开始,每次增加 10 路,观察丢包率和延迟的变化。当丢包率突然飙升或延迟翻倍时,基本就到极限了。

# 10 路
turnutils_uclient -m 10 -B 1000 -L 1000 -l 30 ...

# 20 路
turnutils_uclient -m 20 -B 1000 -L 1000 -l 30 ...

# 30 路
turnutils_uclient -m 30 -B 1000 -L 1000 -l 30 ...

第二步:固定并发数,增加单路带宽

比如固定 20 路并发,把 -B 从 1000 逐步提升到 2000、5000,看看单路带宽上限。

经验值参考:
并发数 单路带宽 总带宽 丢包率 结论
10 1 Mbps 10 Mbps 0.1% 正常
50 1 Mbps 50 Mbps 0.5% 可接受
100 1 Mbps 100 Mbps 2.3% 过载
50 2 Mbps 100 Mbps 1.8% 过载

你看,同样是 100Mbps 的总带宽,50 路 2Mbps 比 100 路 1Mbps 的丢包率还高。这说明单路带宽越大,CPU 加解密压力也越大。所以测试时,两种场景都要覆盖。

测试结果分析:一张图看懂

下面这张图,是我根据多次测试经验总结的 TURN 服务器性能分析流程。你可以对照着看自己的测试结果。

TURN 服务器性能测试分析流程 开始测试 步骤1:单路连通性测试 连通? 检查网络/认证 步骤2:多路并发性能测试 丢包<1%? 优化CPU/带宽 测试通过 ✅

常见问题与避坑指南

问题1:测试时丢包率很高,但服务器 CPU 和带宽都没跑满

我曾经遇到过这种情况,排查了很久才发现是网卡中断亲和性没设置好。多队列网卡如果中断都绑定在同一个 CPU 核心上,其他核心闲着,但处理网络中断的那个核心已经满载了。解决方案是设置 irqbalance 或手动绑定中断到不同核心。

问题2:UDP 测试不通,但 TCP 正常

大概率是防火墙或 NAT 设备拦截了 UDP 包。检查一下服务器的 iptables 规则,确保 UDP 端口(3478 和 TURN 分配的 relay 端口范围)是放行的。另外,有些云厂商的安全组默认只开放 TCP,UDP 需要单独配置。

问题3:测试结果不稳定,每次跑都不一样

嗯,这很常见。网络环境本身就有波动。我的做法是:每个场景跑 3 次,取平均值。如果某次结果明显偏离,就再跑一次看看。另外,测试期间尽量让服务器独享资源,别和其他服务混跑。

我的个人习惯: 测试前先用 topiftop 看一下服务器当前的负载和带宽占用,确保测试环境干净。测试过程中也开着 htop 观察 CPU 和内存变化,能帮你快速定位瓶颈。

总结

turnutils_uclient 是个好工具,但用好它需要一点经验。记住几个关键点:

  • 先测单路连通性,再上并发
  • 丢包率超过 1% 就要排查原因
  • 带宽和 CPU 都可能成为瓶颈,要分开测试
  • 测试结果受网络环境影响,多跑几次取平均值

最后说一句,TURN 服务器的性能测试不是一次性工作。业务量增长、服务器迁移、网络架构调整后,都应该重新跑一轮。别等到用户投诉了才想起来测,那时候就晚了。


公众号:蓝海资料掘金营,微信deep3321