Skip to content

压力测试

压测结果受到哪些因素影响?

  • 压力机到服务器的网络延迟 (建议内网或本机压测)
  • 压力机到服务器的带宽 (建议内网或本机压测)
  • 是否开启 HTTP keep-alive (建议开启)
  • 并发数是否足够 (外网压测要尽量开启更大的并发)
  • 服务端进程数是否合理 (helloworld 业务进程数建议与 cpu 数相同,数据库业务进程数建议为 cpu 的四倍及以上)
  • 业务自身性能 (例如是否使用了外网数据库)

HTTP keep-alive 是什么?

HTTP Keep-Alive 机制是一种用于在单个 TCP 连接上发送多个 HTTP 请求和响应的技术,它对于性能测试结果影响很大,关闭 keep-alive 后 QPS 可能成倍下降。 目前浏览器都是默认开启 keep-alive 的,也就是浏览器访问某一个 http 地址后会将连接暂时保留不关闭,下一次请求时复用这个连接,用来提高性能。 压测时建议开启 keep-alive。

压测时如何开启 HTTP keep-alive?

如果是用的 ab 程序压测需要加 - k 参数,例如 ab -n100000 -c200 -k http://127.0.0.1:8787/ 。 apipost 需要在返回头中返回 gzip 头才能开启 keep-alive (apipost 的 bug,参考下面)。 其它压测程序一般会默认开启。

为什么通过外网压测 QPS 很低?

外网延迟很大导致 QPS 很低,是正常现象。例如压测 baidu 页面 QPS 可能只有几十。 建议内网或者本机压测,排除网络延迟影响。 如果一定要在外网压测,可以通过增加并发数来增加吞吐量 (需保证带宽充足)。

为什么经过 nginx 代理后性能下降?

nginx 运行需要消耗系统资源。同时,nginx 和 webman 之间的通讯也需要消耗一定的资源。 然而,系统的资源是有限的,webman 无法获取到所有的系统资源,因此,整个系统的性能可能会有所下降是正常现象。 为了尽可能减少 nginx 代理带来的性能影响,可以考虑关闭 nginx 日志 ( access_log off; ), 开启 nginx 到 webman 之间的 keep-alive,参考 nginx 代理

另外 https 和 http 相比会损耗更多资源,因为 https 需要进行 SSL/TLS 握手,数据加密解密,包的尺寸变大占用更多带宽,这些会导致性能下降。 压测如果用的是短链接 (不开启 HTTP keep-alive),每次请求都需要额外的 SSL/TLS 握手通讯,性能会大幅降低。建议压测 https 开启 HTTP keep-alive。

如何知道系统已经达到性能极限?

一般来说 CPU 达到 100% 时说明系统性能已经达到极限。如果 CPU 还有空闲说明还没达到极限,这时候可以适当增加并发提高 QPS。 如果增加并发无法提高 QPS 则可能是 webman 进程数不够,请适当增加 webman 进程。如果仍然无法提高考虑带宽是否足够。

为什么我压测结果是 webman 性能低于 go 的 gin 框架?

techempower 压测显示 webman 不管在纯文本、数据库查询、数据库更新等所有指标都高于 gin 近一倍左右。 如果你的结果不一样,可能是因为你在 webman 中使用了 ORM 带来了较大的性能损失,可尝试 webman + 原生 PDO 与 gin + 原生 SQL 比较。

webman 中使用 ORM 性能会损失多少?

以下是一组压测数据

环境 服务器阿里云 4 核 4G,本地 MySQL 数据库,从 10 万条记录中随机查询一条数据 json 返回,本机压测。

如果使用原生 PDO webman QPS 为 1.78 万

如果使用 laravel 的 Db::table () webman QPS 降到 0.94 万 QPS

如果使用 laravel 的 Model webmanQPS 降到 0.72 万 QPS

thinkORM 结果类似,区别不大。

提示 虽然使用 ORM 性能会有所下降,但是对于 99% 的业务来说性能已经严重溢出,如果你刚好是那 1% 也可以通过增加 cpu 或者服务器轻松解决。 我们应该在开发效率、可维护性、性能等多个指标中找到一个平衡点,而不是一味追求性能。

为什么用 apipost 压测 QPS 很低?

apipost 的压力测试模块有 bug,如果服务端不返回 gzip 头则无法保持 keep-alive,导致性能大幅下降。 解决办法返回时将数据压缩并添加 gzip 头,例如

php
<?php
namespace app\controller;
class IndexController
{
    public function index()
    {
        return response(gzencode('hello webman'))->withHeader('Content-Encoding', 'gzip');
    }
}

除此之外,apipost 一些情况下无法打出满意的压力,这表现为同样的并发,使用 apipost 要比 ab 低 50% 左右的 QPS。 压测建议用 ab、wrk 或其它专业的压测软件而不是 apipost。

设置合适的进程数

webman 默认开启 cpu*4 的进程数。实际上无网路 IO 的 helloworld 业务压测进程数开成与 cpu 核数一致性能最优,因为可以减少进程切换开销。 如果是带数据库、redis 等阻塞 IO 业务,进程数可设置为 cpu 的 3-8 倍,因为这时需要更多的进程提高并发,而进程切换开销相对与阻塞 IO 则基本可以忽略。

压力测试一些参考范围

云服务器 4 核 4G 16 进程 本机 / 内网压测

-开启 keep-alive未开启 keep-alive
hello world8-16 万 QPS1-3 万 QPS
数据库单查询1-2 万 QPS1 万 QPS

第三方 techempower 压测数据

压测命令示例

ab

# 100000请求 200并发 开启keep-alive
ab -n100000 -c200 -k http://127.0.0.1:8787/

# 100000请求 200并发 未开启keep-alive
ab -n100000 -c200 http://127.0.0.1:8787/

wrk

# 200 并发压测10秒 开启keep-alive(默认)
wrk -c 200 -d 10s http://example.com

基于 MIT 许可发布