微信号:ToFeelings

介绍:技术的深度和广度只能靠自己努力去发掘,谁也不能替你学习,在这里希望你能有所收获.

压测 swoole_websocket_server 性能

2019-06-09 17:29 訢亮

第 86 篇文章

这是关于 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

Server 代码

 
           
  1. <?php


  2. class Server

  3. {

  4. private $serv;

  5. public function __construct() {

  6. $this->serv = new Swoole\WebSocket\Server("0.0.0.0", 9501);

  7. $this->serv->set([

  8. 'task_worker_num' => 10,

  9. 'enable_coroutine' => true,

  10. 'task_enable_coroutine' => true

  11. ]);

  12. $this->serv->on('open', function ($serv, $request) {});

  13. $this->serv->on('message', function ($serv, $frame) {

  14. $serv->task($frame->data);

  15. });

  16. $this->serv->on('task', function ($serv, $task) {

  17. foreach ($serv->connections as $fd) {

  18. $connectionInfo = $serv->connection_info($fd);

  19. if (isset($connectionInfo['websocket_status']) && intval($connectionInfo['websocket_status']) == 3) {

  20. $serv->push($fd, $task->data);

  21. }

  22. }

  23. });

  24. $this->serv->on('finish', function ($serv, $task_id, $data) {});

  25. $this->serv->on('close', function ($serv, $fd) {});

  26. $this->serv->start();

  27. }

  28. }


  29. $server = new Server();

压测脚本

 
           
  1. class Test

  2. {

  3. protected $concurrency; //并发量

  4. protected $request; //请求量

  5. protected $requested = 0;

  6. protected $start_time;


  7. function __construct()

  8. {

  9. $this->concurrency = 100;

  10. $this->request = 10000;

  11. }


  12. protected function webSocket()

  13. {

  14. go(function () {

  15. for ($c = 1; $c <= $this->concurrency; $c++ ) {

  16. $cli = new \Swoole\Coroutine\Http\Client('127.0.0.1', 9501);

  17. $cli->set(['websocket_mask' => false]);

  18. $ret = $cli->upgrade('/');

  19. if ($ret) {

  20. $i = $this->request / $this->concurrency;

  21. while ($i >= 1) {

  22. $this->push($cli);

  23. $cli->recv();

  24. $i--;

  25. }

  26. }

  27. }

  28. $this->finish();

  29. });

  30. }


  31. protected function push($cli)

  32. {

  33. $ret = $cli->push('Hello World');

  34. if ($ret === true) {

  35. $this->requested ++ ;

  36. }

  37. }


  38. protected function finish()

  39. {

  40. $cost_time = round(microtime(true) - $this->start_time, 4);

  41. echo "Concurrency:".$this->concurrency.PHP_EOL;

  42. echo "Request num:".$this->request.PHP_EOL;

  43. echo "Success num:".$this->requested.PHP_EOL;

  44. echo "Total time:".$cost_time.PHP_EOL;

  45. echo "Request per second:" . intval($this->request / $cost_time).PHP_EOL;

  46. }


  47. public function run()

  48. {

  49. $this->start_time = microtime(true);

  50. $this->webSocket();

  51. }

  52. }


  53. $test = new Test();

  54. $test->run();

压测结果

 
           
  1. 1 次:

  2. Concurrency:100

  3. Request num:10000

  4. Success num:10000

  5. Total time:0.846

  6. Request per second:11820


  7. 2 次:

  8. Concurrency:100

  9. Request num:10000

  10. Success num:10000

  11. Total time:0.9097

  12. Request per second:10992


  13. 3 次:

  14. Concurrency:100

  15. Request num:10000

  16. Success num:10000

  17. Total time:0.903

  18. Request per second:11074

以上是压测结果,供参考。

小结

通过这个压测结果,表明 Swoole 的执行效率是杠杠的!

当然还有一些参数是可以调优的,比如:worker_num、max_request、task_worker_num 等。

在真实的业务场景中,肯定会有逻辑处理,也会使用到 MySQL、Redis。

那么问题来了,前两篇文章已经分享了,Swoole Redis 连接池Swoole MySQL 连接池,感兴趣的同学,可以使用上两种连接池,然后再进行压测。

不知不觉,Swoole 入门文章已经写了 10 篇了,非常感谢大家的捧场,真心希望能够对 Swoole 入门学习的同学,有点帮助。

推荐阅读

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

 
IT小圈儿 更多文章 Swoole Task 的应用 Swoole Timer 的应用 我眼中的 RPC 领导力 之 《情境领导》 系统的讲解 - PHP 接口签名验证
猜您喜欢 第一发!闲聊Spark一点新闻 除了人工智能工程师,还有一种工程师或许更抢手 FreeSWITCH视频会议 时钟向量在一致性问题中的应用 2018 OPPO开发者大会:打通技术各个脉络,全方位构建智能化服务生态