压测 swoole_websocket_server 性能

匿名 (未验证) 提交于 2019-12-02 23:38:02

这是关于 Swoole 入门学习的第十篇文章:压测 swoole_websocket_server 性能。

收到读者提问 “使用 Swoole 开发的群聊功能,想知道并发情况,也就是想压测下 QPS,一直未找到方法 ...”

对 swoole_http_server 压测,咱们可以使用 Apache 的 ab 命令。

对 swoole_websocket_server 压测,使用 ab 命令是不能压测的,我从网上一直也没找到合适的方法,看官方提供的代码 benchmark/async.php 中,使用的异步模块 swoole\http\client 方法进行压测的,但在 Swoole 4.3 版本就移除了异步模块,让使用 Coroutine 协程模块。

在本地我用 Coroutine 协程实现了一下, 测的差不多的时候,一直不确定是否正确,就在 segmentfault 发了个提问,没想到韩老师回答了,'如果的如果'老师也回答了,非常感谢两位老师的答案,然后整理出文章分享给大家。

Mac 上安装的 Parallels Desktop 虚拟机

系统:Ubuntu 16.04.3 LTS

内存:

  • 数量:1
  • 核数:2

CPU:

  • 数量:1
  • 大小:2G
<?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 入门学习的同学,有点帮助。

本文欢迎转发,转发请注明作者和出处,谢谢!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!