摘要:可靠的HTTP代理基准测试,应在同一目标、网络、超时和时间窗口下,同时观察业务成功率、P95/P99延迟、分时可用率和满足SLO的最大并发。平均延迟和服务商公布的IP可用率只能提供线索,不能替代真实业务测试。
不少代理性能测试只有一个动作:连续请求几十次,然后计算平均响应时间。数字看起来很精确,结论却可能完全失真。一次请求很快,不代表高峰期不排队;HTTP状态为200,也不代表返回内容符合预期。
真正有用的测试,应把四项指标放进同一套协议:成功率判断请求有没有完成,延迟判断完成得有多慢,可用率判断长时间运行是否稳定,并发测试则找出前三项开始明显恶化的位置。
为什么四项指标必须放在同一套测试里?
单项指标只能描述局部现象,四项指标的联动变化才足以判断代理性能。
例如,并发从10提高到50后,吞吐量可能仍在上涨,但P95延迟已经翻倍,超时比例也开始抬头。如果只看每秒完成请求数,会把排队积压误判成容量提升。
建议先统一下面的统计口径:
| 指标 | 推荐定义 | 不能混用的口径 | 主要用途 |
|---|---|---|---|
| 成功率 | 通过内容校验的有效响应数 ÷ 总请求数 | TCP连接成功率、HTTP 2xx比例 | 判断任务能否真正完成 |
| 延迟 | 请求发出至完整响应接收的P50、P95、P99 | 只看平均值或服务端处理时间 | 识别长尾与排队 |
| 可用率 | 合格时间窗口数 ÷ 总观察窗口数 | 单批IP可连接比例 | 判断持续运行稳定性 |
| 并发能力 | 满足既定SLO时的最大稳定并发 | 瞬时发出的最大请求数 | 容量规划与套餐选择 |
测试前还要固定目标接口、请求方法、响应体大小、客户端网络、超时、重试策略和运行时段。任一变量改变,都应该建立新测试组,而不是继续追加到原结果中。
成功率应该怎样计算才不失真?
成功率至少要拆成连接成功、HTTP成功和业务成功三层。
代理连接成功,只能说明客户端与代理入口建立了通信。HTTP 2xx说明目标返回了正常状态码,但响应可能是空数据、错误页面或不符合预期的结构。能够支持业务判断的,应该是完成内容校验后的业务成功率。
一条请求建议记录以下字段:
proxy_connect_error:代理鉴权、连接或隧道建立失败。timeout:连接、首字节或总请求超时。http_status:2xx、3xx、4xx、5xx分别计数。content_valid:关键字段、响应长度或校验值是否正确。retry_count:重试次数单独记录,不能用重试后的结果覆盖首请求失败。
原始基准测试应先关闭重试。否则一次请求失败、第二次重试成功,最终会被统计成100%成功,却掩盖额外延迟和请求成本。完成原始测试后,再增加一组带业务重试策略的对照实验。
延迟为什么要看P95和P99?
平均值很容易被少量快请求“美化”,P95和P99更能反映用户实际遇到的长尾。
一组请求中,90%在300毫秒内完成,剩余10%耗时5秒,平均值可能仍不算夸张,但并发任务已经会出现线程占用、队列堆积和整体吞吐下降。
至少记录三档分位数:
- P50反映典型请求的日常水平。
- P95用于设置常规超时和评估主要长尾。
- P99用于观察极端排队、节点波动和恢复时间。
条件允许时,可继续把总延迟拆成代理连接、TLS握手、首字节和响应下载四段。若P50稳定而P99突然升高,通常需要结合并发数、出口切换和目标端状态继续排查,不能直接归因于代理节点。
可用率怎样测才不会被短时结果误导?
可用率应按时间窗口统计,而不是把几分钟内的请求成功比例换个名字。
可以每分钟发起固定数量的健康请求,并把该分钟定义为一个观察窗口。窗口内业务成功率和P95均满足阈值时记为合格,否则记为异常。连续运行数小时后,再计算合格窗口占比。
这种方法能识别两类容易漏掉的问题:一是大部分时间正常、固定时段明显变差;二是整体成功率尚可,但失败集中爆发,导致任务在短时间内大量积压。
服务商的公开数据也要放回这一口径理解。极安代理官网给出的国内代理口径为IP可用率99.9%、平均响应小于0.1秒。这两项可以作为测试参考,但不能直接等同于特定目标的业务成功率和端到端延迟,仍需在相同脚本、地区和时间窗口下复测。
并发能力应该怎样逐级压出来?
并发能力不是“最多能发多少请求”,而是指标仍满足SLO时的最高稳定档位。
可以从1、5、10、20、50等档位逐级增加并发,每档持续运行3至5分钟,并保留预热阶段。只有上一档成功率、P95和错误分布稳定,才进入下一档。
可先使用一组内部验收线作为测试起点,例如:
| 验收项 | 示例起始线 | 超线后的动作 |
|---|---|---|
| 业务成功率 | 不低于99% | 检查错误类型与出口质量 |
| P95总延迟 | 不高于2秒 | 降低并发并检查排队 |
| 超时比例 | 不高于0.5% | 拆分连接与读取超时 |
| 连续异常窗口 | 不超过2个 | 延长观察并核对时段影响 |
这些数值只是压测起点,不是所有业务通用的固定标准。低频监测可以接受更高延迟,实时接口则可能需要更严格的P95;最终阈值应由任务时效、失败成本和目标端容量共同决定。
一套最小基准测试怎样落地?
先用无重试脚本建立原始基线,再逐步加入并发、轮换和恢复策略。
下面的Python示例面向自有或已获授权的测试接口,使用同一个会话发起并发请求,并输出业务成功率、P50和P95。代理地址和鉴权信息通过环境变量传入,避免写进代码仓库。
import os, time, asyncio, aiohttp
URL = os.environ["TEST_URL"]
PROXY = os.environ["HTTP_PROXY"]
N, C = 500, 20
def pct(values, p):
values = sorted(values)
return values[int((len(values) - 1) * p)]
async def once(session, sem):
async with sem:
start = time.perf_counter()
try:
timeout = aiohttp.ClientTimeout(total=10)
async with session.get(URL, proxy=PROXY, timeout=timeout) as r:
body = await r.read()
valid = r.status == 200 and len(body) > 0
return valid, (time.perf_counter() - start) * 1000
except Exception:
return False, None
async def main():
sem = asyncio.Semaphore(C)
async with aiohttp.ClientSession() as session:
rows = await asyncio.gather(*(once(session, sem) for _ in range(N)))
times = [t for ok, t in rows if ok]
print("success_rate:", len(times) / N)
print("p50_ms:", pct(times, 0.50), "p95_ms:", pct(times, 0.95))
asyncio.run(main())正式测试还应把每次请求写入CSV或时序数据库,保留时间戳、并发档位、状态码、错误类型、响应长度和出口标识。汇总表只能用于展示,原始记录才是复盘异常窗口的依据。
测试结果怎样转成上线或采购决定?
不要寻找单一“最高分”,而要找出满足业务SLO且留有容量余量的配置。
如果并发提高后吞吐继续增长,但P95和超时同步上升,说明系统已接近排队区间,生产配置不应贴着最高档运行。较稳妥的做法,是把首次明显恶化前一档作为候选容量,再预留20%至30%的波动空间。
若失败主要来自代理连接,应检查鉴权、入口和节点恢复机制;若代理连接正常而目标持续返回4xx或5xx,则需要单独核对请求策略、目标端状态和合规访问频率。两类问题不能混在一个“代理失败率”里处理。
最终报告应同时保留测试环境、样本量、时间窗口和失败明细。没有这些条件,同一份性能数字几乎无法复现,也不适合直接用于服务商比较。
FAQ
Q:测试HTTP代理时需要开启自动重试吗?
A:原始基准测试不应开启。重试会掩盖首请求失败,并把额外耗时转移到业务层。建议先得到无重试基线,再建立一组带固定重试次数和退避时间的对照结果。
Q:测试多少次请求才有参考价值?
A:没有适用于所有任务的固定数量。短测试可用数百次请求检查脚本和错误分类,正式结果还需要覆盖多个时间窗口。与其瞬间发送数万次,不如保证样本跨越真实运行时段。
Q:P95延迟应该包含失败请求吗?
A:成功请求和失败请求应分开统计。成功请求计算P50、P95和P99,超时则单独记录为超时比例及超时上限。如果把超时请求直接删除却不展示数量,延迟结果会被明显低估。
Q:并发越高,每秒请求数就一定越高吗?
A:不一定。并发提高到某个区间后,连接池、代理入口、目标端或客户端资源都可能形成排队。此时吞吐增长会放缓,P95和超时开始上升,继续加并发只是在增加积压。
Q:服务商公布的IP可用率能代替业务测试吗?
A:不能。IP可用率通常描述代理节点可连接或可转发的比例,业务成功率还受目标接口、请求内容、网络路径、超时和访问频率影响。采购前应使用真实任务做同条件测试。