Gateway的请问sendToUid是否有性能问题?

frontlon

在压力测试环境中,发现 Gateway::sendToUid($uid,$msg); 执行时间有些可怕,最多的超过6秒了。
机器环境:Gateway和Worker分离。

测试代码:

.....
$t1 = microtime(true);
Gateway::sendToUid('teacher_827181', $msgstr);
$t2 = microtime(true);
echo "\n\n发老师耗时" . round($t2-$t1,3) . "秒\n\n";
.....

请问此问题该如何解决?

3368 3 0
3个回答

walkor

首先压测时要根据手册优化后linux内核,并安装event扩展,否则系统通讯性能会有很大影响。

Gateway::sendToUid 和 Gateway::sendToClient不同,Gateway::sendToUid是向所有gateway进程发送一条发送指令,Gateway::sendToClient是向对应的那一个client_id发送指令。Gateway::sendToUid性能要比Gateway::sendToClient差很多。但是在GatewayWorker中环境里Gateway::sendToUid 接口都是异步非阻塞的,系统负载正常的情况下不会耗时这么长时间。

另外看下是不是用了GatewayClient,如果是GatewayClient,通讯过程是阻塞的,而且要与register连接,然后与所有gateway连接通讯,耗时要长一些,但是这个是GatewayClient的问题,不是GatewayWorker问题。

最后并不是任何压力程序都能运行飞快,当系统因压测负载很高时,可能平时不耗时的操作都非常慢,原因很简单,系统处理不过来了,当有复杂业务或者业务本身性能很差时会更明显。

  • frontlon 2018-04-12

    另外请问,如果我给100个uid发消息的话,
    我把100个uid写入数组后传入Gateway::sendToUid发送,
    请问这种是请求100次gateway还是请求1次gateway?

  • frontlon 2018-04-12

    谢谢walkor大哥的指导。
    请问GatewayClient如何查看?我用的是这个方法,请问是GatewayClient吗?

    public static function sendToUid($uid, $message)
    {
        $gateway_data         = GatewayProtocol::$empty;
        $gateway_data['cmd']  = GatewayProtocol::CMD_SEND_TO_UID;
        $gateway_data['body'] = $message;
        if (!is_array($uid)) {
            $uid = array($uid);
        }
        $gateway_data['ext_data'] = json_encode($uid);
        self::sendToAllGateway($gateway_data);
  • walkor 2018-04-12

    我把100个uid写入数组后传入Gateway::sendToUid发送是每个gateway请求一次

  • walkor 2018-04-12

    http://doc2.workerman.net/326149 这里有gatewayClient的信息

  • frontlon 2018-04-12

    @1:了解了。那就是说,我发送100个Uid和1个Uid相比,除了发送量不同外,执行的业务逻辑都是一个是吧?

maq

我看了一下 Lib\Gateway.php 的代码,在 sendToAllGateway() 这里,【如果有businessWorker实例,说明运行在workerman环境中,通过businessWorker中的长连接发送数据】这个分支,代码很简单,而且都是异步操作,我觉得就算系统性能再差,也不至于拖到 6 秒之久。(如果是因为系统未优化,那也应该是在连接环节出问题,不会因此在发送环节卡住)

但如果走的是【运行在其它环境中,通过注册中心得到gateway地址】这一支的话,里面涉及到跟 register 通信,那个是同步通信,就比较说得通了。

  • frontlon 2018-04-12

    对的,我们是4台服务器。两台gateway,两台worker,register在一台gateway中。

maq

检查一下你的 BusinessWorker 启动代码,是不是改写了 onWorkerStart。如果原配的 onWorkerStart 没有执行到的话,就会误导到【运行在其它环境中……】这个分支。

GatewayWorker 文档说 onWorkerStart 可以定制(http://www.workerman.net/gatewaydoc/gateway-worker-development/business-worker.html),我估计这是个误导,正确的做法似乎应该是定义 Events::onWorkerStart 才对。

  • 暂无评论
年代过于久远,无法发表回答
🔝