这是关于 Swoole 入门学习的第十篇文章:压测 swoole_websocket_server 性能。php
收到读者提问 “使用 Swoole 开发的群聊功能,想知道并发状况,也就是想压测下 QPS,一直未找到方法 ...”html
对 swoole_http_server 压测,我们可使用 Apache 的 ab 命令。c++
对 swoole_websocket_server 压测,使用 ab 命令是不能压测的,我从网上一直也没找到合适的方法,看官方提供的代码 benchmark/async.php
中,使用的异步模块 swoole\http\client
方法进行压测的,但在 Swoole 4.3 版本就移除了异步模块,让使用 Coroutine
协程模块。web
在本地我用 Coroutine
协程实现了一下, 测的差很少的时候,一直不肯定是否正确,就在 segmentfault 发了个提问,没想到韩老师回答了,'若是的若是'老师也回答了,很是感谢两位老师的答案,而后整理出文章分享给你们。segmentfault
Mac 上安装的 Parallels Desktop 虚拟机websocket
系统:Ubuntu 16.04.3 LTSswoole
内存:并发
CPU:框架
<?php class Server { private $serv; public function __construct() { $this->serv = new Swoole\WebSocket\Server("0.0.0.0", 9501); $this->serv->set([ 'task_worker_num' => 10, 'enable_coroutine' => true, 'task_enable_coroutine' => true ]); $this->serv->on('open', function ($serv, $request) {}); $this->serv->on('message', function ($serv, $frame) { $serv->task($frame->data); }); $this->serv->on('task', function ($serv, $task) { foreach ($serv->connections as $fd) { $connectionInfo = $serv->connection_info($fd); if (isset($connectionInfo['websocket_status']) && intval($connectionInfo['websocket_status']) == 3) { $serv->push($fd, $task->data); } } }); $this->serv->on('finish', function ($serv, $task_id, $data) {}); $this->serv->on('close', function ($serv, $fd) {}); $this->serv->start(); } } $server = new Server();
class Test { protected $concurrency; //并发量 protected $request; //请求量 protected $requested = 0; protected $start_time; function __construct() { $this->concurrency = 100; $this->request = 10000; } protected function webSocket() { go(function () { for ($c = 1; $c <= $this->concurrency; $c++ ) { $cli = new \Swoole\Coroutine\Http\Client('127.0.0.1', 9501); $cli->set(['websocket_mask' => false]); $ret = $cli->upgrade('/'); if ($ret) { $i = $this->request / $this->concurrency; while ($i >= 1) { $this->push($cli); $cli->recv(); $i--; } } } $this->finish(); }); } protected function push($cli) { $ret = $cli->push('Hello World'); if ($ret === true) { $this->requested ++ ; } } protected function finish() { $cost_time = round(microtime(true) - $this->start_time, 4); echo "Concurrency:".$this->concurrency.PHP_EOL; echo "Request num:".$this->request.PHP_EOL; echo "Success num:".$this->requested.PHP_EOL; echo "Total time:".$cost_time.PHP_EOL; echo "Request per second:" . intval($this->request / $cost_time).PHP_EOL; } public function run() { $this->start_time = microtime(true); $this->webSocket(); } } $test = new Test(); $test->run();
第 1 次: Concurrency:100 Request num:10000 Success num:10000 Total time:0.846 Request per second:11820 第 2 次: Concurrency:100 Request num:10000 Success num:10000 Total time:0.9097 Request per second:10992 第 3 次: Concurrency:100 Request num:10000 Success num:10000 Total time:0.903 Request per second:11074
以上是压测结果,供参考。异步
经过这个压测结果,代表 Swoole 的执行效率是杠杠的!
固然还有一些参数是能够调优的,好比:worker_num、max_request、task_worker_num 等。
在真实的业务场景中,确定会有逻辑处理,也会使用到 MySQL、Redis。
那么问题来了,前两篇文章已经分享了,Swoole Redis 链接池、Swoole MySQL 链接池,感兴趣的同窗,可使用上两种链接池,而后再进行压测。
不知不觉,Swoole 入门文章已经写了 10 篇了,很是感谢你们的捧场,真心但愿可以对 Swoole 入门学习的同窗,有点帮助。
本文欢迎转发,转发请注明做者和出处,谢谢!