Fortio负载测试工具基础

https://github.com/fortio/fortio

Fortio,这个工具最初是为 Istio 服务网格设计的负载测试利器,后来在 2018 年独立出来,发展至今。

Fortio 的价值体现在哪里?

  • 精准,例如Fortio 让你设定一个目标 QPS,比如每秒 1000 个请求,它就稳稳地维持在这个水平,这对于模拟真实的业务流量至关重要。
  • 高效。用 Go 语言写成,性能高而且体积小,Docker 镜像不到 6MB,启动快,资源占用少。
  • 易用。你可以用命令行直接操作,也可以通过一个简洁的 Web UI 来配置和查看结果,甚至还能通过 REST API 远程控制。
  • 稳定,经过了多年的实践检验,可靠性高。

Fortio 不仅仅是一个简单的压测工具,它的功能远不止于此。

  • 自带了一个 Web 服务器,可以用来做各种调试和测试,比如回显请求、添加延迟、返回错误码等等。
  • 对 HTTP、HTTPS 以及 gRPC 这些主流协议都支持得非常好。
  • 嵌入了 Grol 脚本语言,这意味着你可以用脚本来定义非常复杂的测试场景,比如逐步增加负载、模拟特定的用户行为模式。
  • 模块化设计非常好,你可以把它作为一个库嵌入到自己的项目里,或者只用它的一部分功能,比如统计组件 stats 或者 HTTP 工具包 http。

Fortio 到底能用来做什么呢?应用场景非常广泛

  • 服务性能评估,比如你想知道你的 API 在高并发下的响应时间是多少?吞吐量能达到多少?错误率有多高?
  • 容量规划,帮助你预测系统在预期负载下的表现,提前做好准备。当系统出现性能瓶颈时,Fortio 也能辅助你进行定位。
  • 混沌工程,比如模拟网络延迟、服务降级等异常场景,来测试系统的健壮性。
  • 自动化测试,可以集成到 CI/CD 流程中,确保每次代码变更后服务质量不受影响。

Fortio 命令行

https://github.com/fortio/fortio

Fortio 的命令行参数非常丰富,提供了极大的灵活性。

  • -qps 参数,用来指定你想要的每秒请求数

  • c 参数控制并发连接数

  • -t 控制测试持续时间

  • -n 控制总请求数

  • -payload 参数来指定请求体的内容,或者从文件加载

  • -uniform 能让请求在时间上均匀分布,避免瞬间产生大量请求,从而模拟真实用户行为

  • -nocatchup 则保证即使服务暂时落后,也能保持在目标 QPS 附近,对于长时间的稳定测试非常有用

Fortio server

Fortio 的服务器功能也很强大,它不仅仅是一个客户端。它内置了一个多功能的 Web 服务器。比如,你可以用它来做一个 Echo Server,把收到的请求原封不动地返回给你,这在调试时非常有用。

Fortio 作为服务器运行时,默认会启动如下端口

Fortio 1.16.0 tcp-echo TCP server listening on [::]:8078
Fortio 1.16.0 udp-echo UDP server listening on [::]:8078
Fortio 1.16.0 grpc 'ping' TCP server listening on [::]:8079
Fortio 1.16.0 https redirector TCP server listening on [::]:8081
Fortio 1.16.0 echo TCP server listening on [::]:8080

运行fortio server如下

docker run -it --rm  -p 8080:8080 public.ecr.aws/v6x6b8s5/fortio:1.16.0 server

你可以通过 URL 参数来控制它的行为

  • delay 参数可以让你模拟请求的延迟,
  • status 参数可以模拟不同的 HTTP 状态码
  • size 参数可以控制返回的响应体大小
  • close 参数可以模拟连接被关闭的情况
  • header 参数可以注入自定义的 Header
  • gzip 参数还能模拟 Gzip 压缩

模拟HTTP 返回码

返回504

http://localhost:8080/echo?status=504

返回约 98% 的正常 200 成功状态,0.5% 的 503 和 1.5% 的 429 模拟 HTTP 错误码。

http://localhost:8080/echo?status=503:0.5,429:1.5

设置延迟的百分比分布

等待 3 秒后返回响应,模拟网络延迟的情况

http://localhost:8080/echo?delay=3

例如 “delay=250us” 或 “delay=1ms:10%,7ms:1%”

http://localhost:8080/echo?delay=1ms:10%,7ms:1%

设置响应头

添加一个自定义 Header X-Custom-Header

$ curl -v  http://localhost:8090/echo?header=X-Custom-Header:CustomValue

< HTTP/1.1 200 OK
< X-Custom-Header: CustomValue
< Date: Fri, 09 May 2025 17:28:24 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact

回显请求

$ curl -d hello http://localhost:8090/debug
Φορτίο version 1.16.0 2021-06-03 23:19 b0c080f6157c7afcb491445eadd64a323c617c84 go1.16.5 echo debug server up for 24m57.5s on b019e6f4bff4 - request from 172.17.0.1:57790

POST /debug HTTP/1.1

headers:

Host: localhost:8090
Accept: */*
Content-Length: 5
Content-Type: application/x-www-form-urlencoded
User-Agent: curl/8.5.0

body:

hello

除了强大的命令行,Fortio 还提供了一个非常直观的 Web UI。这个界面最大的好处就是可视化。测试过程中,你能实时看到 QPS、平均延迟、P99 延迟、错误率这些关键指标的变化。测试结束后,它会生成漂亮的图表,包括延迟分布的直方图和累积百分比曲线,让你一眼就能看出性能瓶颈在哪里。

Fortio负载测试工具基础_第1张图片

更棒的是,你可以保存多次测试的结果,然后在 UI 上进行对比分析,看看不同配置下的性能差异。所有的数据都可以导出为 JSON 格式,方便你做更深入的分析。而且,通过 Web UI 也能触发新的测试任务。

Fortio负载测试工具基础_第2张图片

对于需要自动化集成的场景,Fortio 提供了完善的 REST API。所有的 API 返回都是 JSON 格式,很容易被脚本或其他程序解析和处理,实现完全的自动化测试流程。

  • 通过 /fortio/rest/run 端点来远程启动一个测试任务
  • 通过 /fortio/rest/stop 来停止它
  • 用 /fortio/rest/status 查看当前运行的任务状态
  • 用 /fortio/rest/dns 端点查询 DNS 解析结果

Fortio 的高级特性

  • 支持传统的 HTTP 协议
  • 支持 gRPC 协议的负载测试
  • 支持 TLS 加密
  • Grol 脚本语言扩展
  • 还内置了代理功能,可以作为 TCP、UDP、HTTP 或 HTTPS 的代理
  • FortioT 组件可以帮你生成 OpenTelemetry 格式的 Trace 数据

想要用 Fortio 得到最佳的性能测试结果,有哪些最佳实践呢?

  • 合理设置并发连接数 c 非常重要。一般来说,连接数应该大于你的核心数,如果系统延迟较高,可能需要更多的连接数才能充分利用带宽。

  • 使用 uniform 参数,这样请求会在时间上均匀分布,避免产生突发流量,更接近真实场景。

  • 对于长时间的测试,建议加上 nocatchup 参数,保持 QPS 的稳定性。

  • 如果你的系统延迟很低,比如毫秒级,可能需要调整直方图的分辨率 r,比如用 0.0001 秒代替默认的 1 毫秒,这样能更精细地捕捉到延迟变化。

  • 当需要测试非常大的并发连接数时,比如几千甚至上万,最好加上 sequential warmup 参数,让连接逐步建立,避免一次性涌入导致服务器过载。

你可能感兴趣的:(测试工具)