欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

压测 swoole_websocket_server 性能

程序员文章站 2022-04-08 14:44:54
概述 这是关于 Swoole 入门学习的第十篇文章:压测 swoole_websocket_server 性能。 "第九篇:Swoole Redis 连接池的实现" "第八篇:Swoole MySQL 连接池的实现" "第七篇:Swoole RPC 的实现" "第六篇:Swoole 整合成一个小框架 ......

概述

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

内存:

压测 swoole_websocket_server 性能

  • 数量:1
  • 核数:2

cpu:

压测 swoole_websocket_server 性能

  • 数量:1
  • 大小:2g

server 代码

<?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 入门学习的同学,有点帮助。

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