Gateway异常退出问题及解决方案

0

在项目运行中遇到不定时出现这个问题,目前已解决,问题如下:
 Gateway.php:372


 if ($this->_workerConnections) {
// 调用路由函数,选择一个worker把请求转发给它
/** @var TcpConnection $worker_connection */
$worker_connection = call_user_func($this->router, $this->_workerConnections, $connection, $cmd, $body);
if (false === $worker_connection->send($gateway_data)) {
$msg = "SendBufferToWorker fail. May be the send buffer are overflow. See http://wiki.workerman.net/Error2";
static::log($msg);
return false;
}
}

// 没有可用的 worker此时判断了$this->_workerConnections是否为真,如果为真就去调用了路由函数
 
如果此时reload,用户有多个worker进程,并且自定义了路由,需要把用户路由到特定worker进程
 
那么此时在$this->_workerConnections中很有可能不是全部已启动好的worker


其中可能因为需要worker进程未加载完成,所以并不包含需要的worker进程 


这时就有可能会出现一个致命错误:null调用了不存在的方法send()
 
因此需要修改一下这个判断是否有可用worker的if判断:


if ($this->_workerConnections) {
// 调用路由函数,选择一个worker把请求转发给它
/** @var TcpConnection $worker_connection */
$worker_connection = call_user_func($this->router, $this->_workerConnections, $connection, $cmd, $body);
if (!$worker_connection) {
do {
$worker_connection = call_user_func($this->router, $this->_workerConnections, $connection, $cmd, $body);
} while(!$worker_connection);
}
if (false === $worker_connection->send($gateway_data)) {
$msg = "SendBufferToWorker fail. May be the send buffer are overflow. See http://wiki.workerman.net/Error2";
static::log($msg);
return false;
}
}

// 没有可用的 worker麻烦walkor看看,希望在框架中修复,这样我们就不用侵入去修改框架的代码,造成后续git更新框架的困扰

已邀请:

walkor

赞同来自:

感谢你的建议,


if (!$worker_connection) {
do {
$worker_connection = call_user_func($this->router, $this->_workerConnections, $connection, $cmd, $body);
} while(!$worker_connection);
}

不过这个代码无法解决你说的这个问题。原因是进程执行在这个死循环时,这些参数 $this->router, $this->_workerConnections, $connection, $cmd, $body是不变的,尤其是$this->_workerConnections不会有变化,这会导致gateway进程cpu100%,导致服务永远无法使用。
 
框架能优化的只能是判断下 $worker_connection 是否为空,如果为空就不调用send,并记录一个日志。
 
 

zzz

赞同来自:

谢谢回复,那是否能将发送失败的消息放入一个队列,后续按一定的重试次数重试发送,如果重试成功或者重试失败一定次数就移除消息呢

要回复问题请先登录注册