workerman的内存一直增长,求解决

wangqiang
<?php

namespace Home\Controller;

use Workerman\Worker;
use Think\Controller;
use Workerman\Connection\AsyncTcpConnection;

require_once APP_PATH . 'Workerman/Autoloader.php';

class WorkermanController extends Controller
{
    public $clientGateway = array();

    public $gatewayClients = array();

    public $uidConnections = array();

    public function index()
    {
        if (!IS_CLI) {
            die("access illegal");
        }
        Worker::$daemonize = true;//以守护进程运行
        Worker::$pidFile = APP_PATH . '/workerman.pid';//方便监控WorkerMan进程状态
        Worker::$stdoutFile = APP_PATH . '/stdout.log';//输出日志, 如echo,var_dump等
        Worker::$logFile = APP_PATH . '/workerman.log';//workerman自身相关的日志,包括启动、停止等,不包含任何业务日志
        $worker = new Worker('websocket://0.0.0.0:2345');//此处我使用内网ip
        $worker->name = 'weiChatWorker';
        $worker->onConnect = function ($con) {
            global $uidConnections;
            $uidConnections = $con;
        };

        $worker->onWorkerStart = function ($worker) {

            $con = new AsyncTcpConnection('xxxxxxxxxxxxxxxx');

            // 设置以ssl加密方式访问,使之成为wss
            $con->transport = 'ssl';

            $con->onConnect = function ($con) {
                echo "tcp connect success\n";
            };

            $con->onMessage = function ($con, $data) {
                self::receiveController($data);
            };

            $con->connect();
            echo "Worker starting...\n";
        };

        $worker->onMessage = function ($connection, $data) {
            global $gatewayClients, $clientGateway;
            $postData = json_decode($data);
            $cmd = $postData->cmd;
            $gateway = $postData->bindGateway;
            if ($cmd == "01") {
                $gwArray = explode(",", $gateway);
                //        初始化客户端绑定的网关
                $id = $connection->id;
                $clientGateway = $gwArray;
                foreach ($gwArray as $key) {
                    $temp = $gatewayClients;
                    if ($temp == null) {
                        $temp = array();
                    }
                    array_push($temp, $id);
                    $gatewayClients = $temp;
                }
            }
        };

        $worker->onBufferFull = function ($connection) {
            echo "bufferFull and do not send again\n";
        };
        $worker->onBufferDrain = function ($connection) {
            echo "buffer drain and continue send\n";
        };
        $worker->onWorkerStop = function ($worker) {
            echo "Worker stopping...\n";
        };
        $worker->onError = function ($connection, $code, $msg) {
            self::clearClient($connection);
            echo "error $code $msg\n";
        };

        $worker->onClose = function ($connection) {
            self::clearClient($connection);
            echo "connection closed\n";
        };
        // 运行worker
        Worker::runAll();
    }

    function clearClient($connection)
    {
        global $gatewayClients, $clientGateway, $uidConnections;
        $id = $connection->id;
        $allGateway = $clientGateway;
        foreach ($allGateway as $item) {
//            获取网关的所有client
            $allClient = $gatewayClients;
            unset($gatewayClients);
        }
        unset($clientGateway);
        unset($uidConnections);
    }

    /**
     * 接收OMS消息的处理类
     * @param $data
     */
    function receiveController($data)
    {
        global $gatewayClients, $uidConnections;
        echo $data . "\n";
        $tempData = json_decode($data);
        $cmd = $tempData->cmd;
        if ($cmd == "13") {
//            处理设备告警
//{"cmd":"13","gwID":"4612C9ECDED6","devID":"A1","type":"02","ep":"14","epData":"1","epType":"02","time":"1487061135651","amqpResource":"v1"}
            foreach ($gatewayClients as $cons) {
                $uidConnections->send($data);
            }
        }
    }
}
7455 2 0
2个回答

wangqiang

worker_name exit_status exit_count
weiChatWorker 65280 1
---------------------------------------PROCESS STATUS-------------------------------------------
pid memory listening worker_name connections total_request send_fail throw_exception
32101 55.5M websocket://0.0.0.0:2345 weiChatWorker 2 169810 0 0

  • 暂无评论
walkor

workerman本身非常稳定,没用内存泄漏。目前总结内存占用越来越高一般是以下原因导致的。
1、业务代码问题,比如使用了全局变量数组或者类的某个属性是数组,数组中的元素个数一直在增加,导致内存占用越来越大
2、使用了某些质量有问题的php类库,类库里面同样因为1的问题导致内存不断增长
3、某个扩展bug导致。有些扩展在使用过程中内存会不断增大。(这种情况比较少见)

你的可能是问题1导致的,
客户端全部关闭后 打印下 $gatewayClients, $clientGateway, $uidConnections ,
看看是否有元素未删除导致内存泄漏。或者检查下是否有其它地方使用全局数组,没有及时清理导致内存泄漏。

  • wangqiang 2017-02-15

    total_request 的增长是AsyncTcpConnection链接接受的数据,处理的业务逻辑中没有向全局变量添加元素只是取数据,这边应该不会有内存泄漏。

  • walkor 2017-02-15

    $worker->onConnect 时有向全局数组添加元素吧

年代过于久远,无法发表回答
🔝