workerman queue 内存使用率持续增高,直到服务器宕机。
刚开始的时候,单个进程2.43M,然后就一直增高59.04M,直到服务器宕机。
我的服务端没有产生任何的消息列队。就空跑。
reload 后:
过一小段时间后:
// ######## 消息队列消费者 ########
$consumer = new Worker();
$consumer->name = 'ImJobConsumer';
// 消费的队列的id
$consumer->queueId = $QUEUE_ID;
// 慢任务,消费者的进程数可以开多一些
$consumer->count = 16;
/**
* 进程启动阻塞式的从队列中读取数据并处理
*/
$consumer->onWorkerStart = function($consumer)
{
// 获得队列资源
$consumer->queue = msg_get_queue($consumer->queueId);
\Workerman\Lib\Timer::add(0.5, function() use ($consumer){
if(extension_loaded('sysvmsg'))
{
// 循环取数据
while(1)
{
$desiredmsgtype = 1;
$msgtype = 0;
$message = '';
$maxsize = 65535;
// 从队列中获取消息 @see http://php.net/manual/zh/function.msg-receive.php
@msg_receive($consumer->queue , $desiredmsgtype , $msgtype , $maxsize , $message, true, MSG_IPC_NOWAIT);
if(!$message)
{
return;
}
// 假设消息数据为json,格式类似{"class":"class_name", "method":"method_name", "args":[]}
$message = json_decode($message, true);
// 格式如果是正确的,则尝试执行对应的类方法
if(isset($message['class']) && isset($message['method']) && isset($message['args']))
{
// 要调用的类名,加上Consumer命名空间
$class_name = "\\Consumer\\".$message['class'];
// 要调用的方法名
$method = $message['method'];
// 调用参数,是个数组
$args = (array)$message['args'];
// 类存在则尝试执行
if(class_exists($class_name))
{
$class = new $class_name;
$callback = array($class, $method);
if(is_callable($callback))
{
call_user_func_array($callback, $args);
}
else
{
echo "$class_name::$method not exist\n";
}
}
else
{
echo "$class_name not exist\n";
}
}
else
{
echo "unknow message\n";
}
}
}
});
};
以守护进程的方式启动,然后不断的查看 status,会以肉眼可见的速度增长。
Workerman version:4.1.8
PHP version:8.1.7
Distributor ID: Ubuntu
Description: Ubuntu 20.04.4 LTS
Release: 20.04
Codename: focal
我是在消费列队信息的时候,调用Phalcon的Task.
$app = Bootstrap::handle()->app();
由于不断给变量赋值,并没有释放内存。
现在为:
$consumer->onWorkerStart = function($consumer)
{
// 获得队列资源
$consumer->queue = msg_get_queue($consumer->queueId);
$app = Bootstrap::handle()->app();
\Workerman\Lib\Timer::add(0.5, function() use ($consumer,$app){
if(extension_loaded('sysvmsg')) {
$desiredmsgtype = 1;
$msgtype = 0;
$message = '';
$maxsize = 65535;
@msg_receive(
$consumer->queue ,
$desiredmsgtype ,
$msgtype ,
$maxsize ,
$message,
true,
MSG_IPC_NOWAIT
);
在onWorkerStart里每0.5s跑个while(1)我是没想到的
有问题吗???
即使去掉while(1) {}:
use \Workerman\Lib\Timer;
// 在 onWorkerStart 回调函数中启动一个定时器
public function onWorkerStart($worker) {
// 每 0.5 秒执行一次任务
Timer::add(0.5, function() {
// 在这里执行您的任务
// ...
});
}
问题依然存在
牛P哈哈