如果我正常运行订阅 没有转发 到队列 就不会出现内存泄漏 如果我转发到队列就会出现内存泄漏为啥呢
class Subscribe extends Worker
{
static $taskName = 'subscribe';
static $apiConfig;
static $queue;
public function __construct($socket_name = '', array $context_option = array())
{
parent::__construct($socket_name, $context_option);
}
public function on_start($worker)
{
global $db_config;
Db::setConfig($db_config);
global $redis_config;
self::$queue = new Client($redis_config['queue']['host'],$redis_config['queue']['options']);
Utils::echoLogs(self::$taskName.' 启动成功');
// 作为客户端链接WS
self::subscribe($list);
}
public function on_stop($worker)
{
Utils::echoLogs(self::$taskName.' 已停止');
}
public function subscribe($data)
{
$con = new AsyncTcpConnection(self::$apiConfig['spot_ws']);
$con->transport = 'ssl';
$con->websocketPingInterval = 55;
$con->onMessage = function ($con, $data) {
// 正常接收Data数据是长期稳定
// 但是如果我将消息数据组装成新的数组 newData 转发到队列就会出现内存泄漏
self::$queue->send('data_queue', $newData);
};
$con->onError = function ($con, $err_code, $err_msg) {
};
$con->onClose = function ($con) {
$con->reConnect(1);
};
$con->connect();
}
public function run()
{
$this->onWorkerStart = array($this, 'on_start');
$this->onWorkerStop = array($this, 'on_stop');
parent::run();
}
}
Worker[2584] process terminated with ERROR: E_ERROR "Allowed memory size of 536870912 bytes exhausted (tried to allocate 69632 bytes) in /mnt/wss/vendor/workerman/workerman/Connection/TcpConnection.php on line 582"
你是不是压测时出现的?
不是,我开发测试 执行之后 几分钟之后就出现泄漏啦
Workerman\RedisQueue\Client 是异步的,消息会先在本地内存里存储,然后一条一条发给Redis服务端。如果产生消息的速度大于redis接收速度(或者redis连不上等),消息就会挤压,占用内存就越来越大。这个其实也不叫内存泄漏。
你可以用同步方式发给redis,这样就不占内存了,参考 https://www.workerman.net/doc/workerman/components/workerman-redis-queue.html#%E5%9C%A8%E9%9D%9Eworkerman%E7%8E%AF%E5%A2%83%E5%90%91%E9%98%9F%E5%88%97%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF
如果是webman项目,直接用 Redis队列同步投递接口
谢谢老大,我现在就是用这个方法,正在测试。