SIP测试-04-信令与媒体全链路压测的设计方法

做到语音压测这一步时,往往已经不满足于:

  • 只测注册
  • 只测纯信令
  • 只看 FreeSWITCH 自己的承压能力

他们真正想知道的是:

  • 一通真实电话从发起到挂断,全链路到底能不能稳定走完
  • 信令、媒体、机器人服务、配置服务、识别服务一起参与时,哪一层最先退化
  • FreeSWITCH、AIBus、识别服务、对话系统、通话记录回写这些节点,谁才是真正的主瓶颈

这时候测试就进入了真正困难的阶段:
你不再是在测一个节点,而是在测一条会互相拖拽的语音业务链路。

所以这篇文章不想把“全链路压测”写成一句大口号。
更想讲的是:

信令与媒体全链路压测到底该怎么设计,才能让结果既接近真实,又能在出问题时快速拆回去定位。

一、全链路压测最大的难点,不是压,而是链路太容易糊

一旦进入全链路,至少会同时包含这些层次:

  • SIP 注册
  • 呼叫发起与路由
  • FreeSWITCH 桥接
  • 媒体建立与维持
  • 机器人或服务端 SIP 接听
  • 配置查询
  • 语音识别
  • 对话请求
  • 通话结束与结果回写

问题就在这里。

如果你一上来就把这些层次全部绑在一起做高压,很容易出现这种局面:

  • 屏幕上失败变多了
  • 但没人能说清到底是注册先失败、媒体先异常,还是识别服务先拖慢
  • 现场每个人都在看自己熟悉的一层
  • 最后结论只能写成“全链路不稳定”

这类结论信息量太低。
因为它既不能指导优化,也不能指导下一轮压测收敛。

二、更推荐的一套分层设计:从单点到全链路,而不是一步到位

做全链路压测时,通常会强制把验证过程拆成 5 层。

1. 注册层

先回答:

  • 账号和鉴权是否稳定
  • 注册速率拉高以后是否先出异常

2. 纯信令层

先回答:

  • 呼叫建立链路是否走通
  • 路由、拨号计划、桥接逻辑是否正确

3. 信令 + 媒体层

再回答:

  • 建立通话后媒体是否真正建立
  • 音频播放、RTP 端口和通话时长是否稳定

4. 信令 + 媒体 + 机器人接听层

再回答:

  • 被叫服务侧是否能稳定接起电话
  • 仅接听不调用复杂服务时,链路是否依然稳定

5. 完整业务链路层

最后才回答:

  • 配置查询、识别、对话、结果回写这些环节都接入后,谁最先成为瓶颈

这种拆法的价值在于:

  • 每一层都能产出独立结论
  • 一旦全链路失败,可以快速回退到上一层复核
  • 不会把所有问题都解释成“系统整体不行”

三、设计全链路压测时,最先要画的不是命令,而是一张链路图

真到项目里,通常可以先画一张非常朴素但够用的链路图。

例如:

1
2
3
4
5
6
7
SIPp 主叫
-> FreeSWITCH
-> AIBus / 机器人接听
-> 配置服务
-> 语音识别服务
-> 对话服务
-> 通话记录回写

然后会给每一跳补 3 个字段:

  • 这一步的输入是什么
  • 这一步的成功信号是什么
  • 这一步失败时最先能看到什么现象

这样做以后,整个全链路测试才真正开始“可观测”。

四、更常用的一套准备清单

全链路压测之前,通常会把准备项收成下面这些:

准备项 目的
主叫 / 被叫账号池 保证注册和呼叫数据充足
注册脚本、主叫脚本、被叫脚本 保证信令层独立可控
RTP 媒体文件 验证媒体层
机器人服务或 AIBus 配置 保证被叫服务能稳定接听
配置服务、识别服务、对话服务、回写服务压测版本 保证全链路可跑
独立压测机与监控面板 避免工具侧和观察面失真

这一步不是形式主义。
因为全链路压测里,很多失败根本不是性能问题,而是前置准备不完整。

五、更看重的一套观测面

全链路压测不能只看一类日志。
通常至少要同时看下面 5 组信息。

1. SIPp 执行面

看:

  • 注册和呼叫成功率
  • 失败码分布
  • 当前 CPS、并发通话数

2. FreeSWITCH 面

看:

  • 会话数
  • 桥接成功情况
  • CPU / 内存 / 连接占用

3. 媒体面

看:

  • 媒体是否真正建立
  • 通话时长是否符合预期
  • 是否出现单通、无声、早挂断

4. 业务服务面

看:

  • 配置查询响应
  • 语音识别耗时
  • 对话接口耗时
  • 通话记录写入成功率

5. 时间窗口对齐面

看:

  • 哪一层最先开始抖
  • 是前面拖慢后面,还是后面拖慢前面

这最后一条特别关键。
因为全链路问题最怕的就是只看最终状态,不看变化顺序。

六、执行时更常用的一套节奏

全链路压测如果一步到位,基本注定难排。
更常用的节奏是逐段升压。

例如:

阶段 目标 动作 停留时间
阶段 1 跑通最小链路 单账号、单通话 10 分钟
阶段 2 小并发验证 少量 CPS,确认各层稳定 15 分钟
阶段 3 中并发观察 提升到目标前半段 20 分钟
阶段 4 目标压测 接近真实目标流量 20 分钟
阶段 5 长稳压 观察链路是否慢性退化 30 分钟以上

每个阶段结束后,我都会要求现场先回答 3 个问题:

  1. 当前哪一层最先出现异常
  2. 这个异常是主因,还是伴生现象
  3. 有没有必要继续下一阶段

如果这 3 个问题答不清,通常不会继续升压。

七、我在全链路压测里最常见的几个误区

1. 纯信令稳定,就默认全链路也应该稳定

这是非常典型的误判。
纯信令稳定只能说明:

  • 注册
  • 路由
  • 桥接前半段

问题不大。

但一旦加上媒体和业务服务,系统的占用模型就完全变了。

2. 只看 FreeSWITCH,不看后面的服务

全链路里,很多时候 FreeSWITCH 后面也会变差,但它不一定是最早变差的那一层。

3. 一上来就带完整媒体和完整服务

这样做当然“真实”,但真实到你根本没法排。
更好的方式是先把机器人接听跑通,再逐步把配置、识别、对话、回写接进来。

八、真实案例型段落:一次“全链路看起来像电话打不通,实际最先出问题的是服务侧”的排查

场景

一次电话系统全链路压测里,链路大致是:

  • SIPp 主叫发起呼叫
  • FreeSWITCH 转给 AIBus
  • AIBus 查询配置、调识别、调对话、最后回写结果

压测开始后一段时间,现场很快出现异常:

  • 接通率下降
  • 部分通话时长异常拉长
  • 整体成功率变差

执行

当时执行方式已经是完整链路:

  1. 主叫和被叫侧都已准备好
  2. FreeSWITCH 和 AIBus 都发布了压测版本
  3. 配置服务、识别服务、对话服务也都在线
  4. 压测按既定 CPS 拉起

现象

表面上看,第一时间最容易出现的判断是:

  • 电话接不稳了
  • 那大概率还是 SIP 或 FreeSWITCH 有问题

但现场继续观察时发现两个不太对劲的现象:

  • 并不是所有失败都集中在呼叫建立阶段
  • 有些呼叫已经接通,只是后续动作明显变慢

排查

我当时没有继续盯着 SIP 报文查,而是先按链路拆:

  1. 先确认纯信令层是否仍然稳定
  2. 再确认媒体建立是否仍然正常
  3. 然后把目光转到配置、识别和对话服务耗时
  4. 对齐时间窗口,看哪一层最先抬高

这一轮对齐之后,真正最先出现异常的是服务侧响应:

  • 配置查询变慢
  • 识别或对话调用耗时拉长
  • 通话占用时间被迫拉长
  • 最后反过来把前面的会话数和整体成功率一起拖坏

也就是说,链路最后看起来像“电话系统不稳”,但根因更早出现在服务层。

修复

后面的收敛动作不是继续盲目调 SIPp,而是:

  1. 先把业务服务单独压一轮,确认耗时拐点
  2. 降低全链路阶段的并发目标,重新观察前后关系
  3. 优先优化服务侧,再回来复测全链路

这个案例很典型,因为它说明:

全链路压测最怕的不是失败,而是把链路最后的表象误当成第一现场。

九、更希望全链路压测最后输出什么

如果要写结论,不适合只写:

  • 全链路最大支持多少并发

更希望输出下面这些东西:

  • 当前链路在什么强度以内稳定
  • 哪个阶段开始出现风险
  • 最先退化的是信令、媒体还是服务层
  • 当前链路的主瓶颈是什么
  • 下一步是该优化 FreeSWITCH、媒体链路,还是业务服务

这类结论,才真正能指导后面的容量规划和架构优化。

结语

信令与媒体全链路压测最难的地方,从来不是“把电话打出去”,而是把这条链路设计成:

  • 能逐层验证
  • 能逐段升压
  • 能快速回退
  • 能在问题出现时看出是谁先坏

只有做到这一层,全链路压测才不是一次热闹的演示,而是一套真正有决策价值的测试设计。