压测workerman时如何提高QPS

lbl

看到techempower对workerman测试Plaintext,QPS可以达到1,975,455 ;本地实测仅277880。一个百万级,一个十万级,相差太大了。肯定测试方法有问题,大家能否给点建议?
【测试环境】
操作系统:Ubuntu 22.04.1 LTS Kernel: 5.15.0-43-generic x86_64
CPU:4核
Info: quad core model: Intel Core i5-7500 bits: 64 type: MCP
smt: <unsupported> arch: Kaby Lake rev: 9 cache: L1: 256 KiB L2: 1024 KiB
L3: 6 MiB
Speed (MHz): avg: 3706 high: 3723 min/max: 800/3800 cores: 1: 3723
2: 3721 3: 3696 4: 3687 bogomips: 27199
Flags: avx avx2 ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx

Mem: 7806.2/15765.4 MiB (49.5%)

Storage: 465.76 GiB (38.2% used)
【测试代码】

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';

// 创建一个Worker监听2345端口,使用http协议通讯
$http_worker = new Worker("http://0.0.0.0:2345");

// 启动4个进程对外提供服务
$http_worker->count = 4;

// 接收到浏览器发送的数据时回复hello world给浏览器
$http_worker->onMessage = function(TcpConnection $connection, Request $request)
{
    // 向浏览器发送hello world
    $connection->send('hello world');
};

// 运行worker
Worker::runAll();

【测试方法】

php start.php start

Workerman[start.php] start in DEBUG mode
------------------------------------------- WORKERMAN -------------------------------------------
Workerman version:4.0.42          PHP version:8.1.4           Event-Loop:\Workerman\Events\Event
-------------------------------------------- WORKERS --------------------------------------------
proto   user            worker          listen                 processes    status           
tcp     whois           none            http://0.0.0.0:2345    4             [OK]            
-------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
./wrk  -t4 -c256 -d15s http://127.0.0.1:2345
Running 15s test @ http://127.0.0.1:2345
  4 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.31ms    1.83ms  27.90ms   88.25%
    Req/Sec    69.95k     6.95k  113.29k    73.29%
  4187626 requests in 15.07s, 527.16MB read
Requests/sec: 277880.53
Transfer/sec:     34.98MB
1144 3 0
3个回答

2548a

cpu 硬盘就不是一个级别的.

  • lbl 2022-08-11

    测试了libreactor和workerman,QPS都在二十万后就提高不了。

nitron

TechEmpower的机器DELL R440是XEON Gold 5120处理器至少14核28线程,内存32G,万兆网络,而且客户端,服务器,数据库分在3台不同的机器上

你这个7代I5,4核4线程,16内存,客户端服务器同一个机器,而且..还是运行在DEBUG模式下

PS: plaintext这种测试,确实核心越多越牛逼,他线程数是你的7倍,QPS是你的7倍也很正常

  • lbl 2022-08-11

    谢谢,经你提醒我才发现我是在调试模式下测。不过,今天这同一机器上使用php start.php start -d测试非调试模式,QPS相差不大。
    现在发现 Event-Loop使用Event或Select没什么区别。感觉是event没起作用。

  • nitron 2022-08-11

    说了啊,"hello world"这种测试就是看核心数.不涉及IO,Event和Select没区别

  • lbl 2022-08-11

    我看CPU负载和使用率都没过半。这是不是说明CPU的算力还没有饱和吧?

  • walkor 2022-08-11

    hello world 这种压测,增加cpu不一定能提高QPS,因为瓶颈在linux网络内核了。你用8核对比4核压测出来QPS不会有明显增加。这种情况需要使用多队列网卡或者其他手段提升网络性能才可以提高QPS。

  • chaz6chez 2022-08-11

    kernel bypass【手动狗头】

  • walkor 2022-08-11

    另外 Plaintext压测 使用了pipeline,可以大幅度提高性能,但是一般我们用不到pipeline。
    非pipeline的helloworld QPS看json的压测结果,DELL R440是XEON Gold 5120处理器14核28线程,内存32G,万兆网络带宽,workerman大概110万QPS,极限可达到130万QPS。

  • chaz6chez 2022-08-11

    就eBPF而言,PHP想玩的骚一点,可以用FFI调用C库libbpf,自己实现一套;
    如果不是极客精神的话,其实大可不必在意这个点,了解了解就ok了

  • lbl 2022-08-12

    @walkor,@chaz6chez 谢谢两位的回答,这让我有个新的发现,不过这块知识对我而言比较陌生,今天从简单的配置网卡多队列来实验,虽然配置成功了,但是发现CPU中断不是很均衡。

    # 网卡多队列情况
    ethtool -l eth0 |grep Combined
    Combined:   2
    Combined:   2
    # CPU情况
    %Cpu0  :  0.0 us, 21.3 sy,  2.0 ni,  0.0 id,  0.0 wa,  1.7 hi, 75.1 si,  0.0 st
    %Cpu1  :  0.3 us, 73.7 sy, 20.1 ni,  5.6 id,  0.0 wa,  0.3 hi,  0.0 si,  0.0 st

    然后编译运行libreacotor,也发现虽然启用了多核,但调度失衡,仅一核在工作。现有的知识量,真不够我去探索这个问题,需要再继续学习才能去探究了。

  • chaz6chez 2022-08-12

    @lbl 就这一部分来说,其实挺有意思的,我建议你可以去稍微了解一下DPDK,现在很多做kernel bypass的应用程序通常来说会选择DPDK,但是DPDK也有其优劣势;我说的eBPF主要是去利用XDP指令去处理,他也有自身的优劣势以及当前发展的局限性,这部分目前来说可以去研究玩玩看,PHP FFI的特性结合libbpf是可以去尝试玩玩XDP指令的,不过前提是得有一定的C语言基础。

胡桃

wrk单进程测得出来个鸡毛,你得开新wrk进程直到CPU吃满为止分析数据之和。

  • lbl 2022-08-13

    wrk单服务器百万级并发压测没有问题。千万级涉及的知识就比较深奥了。以下是32核服务器测试数据。
    ···shell
    ./wrk -t32 -c5000 -d15s http://192.168.0.66:8080/plaintext
    Running 15s test @ http://192.168.0.66:8080/plaintext
    32 threads and 5000 connections
    Thread Stats Avg Stdev Max +/- Stdev
    Latency 4.63ms 6.72ms 206.06ms 90.66%
    Req/Sec 40.88k 20.07k 82.50k 61.82%
    19443282 requests in 15.10s, 2.44GB read
    Requests/sec: 1287926.27
    Transfer/sec: 165.82MB

年代过于久远,无法发表回答
🔝