php-msf
php-msf copied to clipboard
Mi.php context = null
/**
* 通过对象池生成对象
*
* @param array $args
* @return \stdClass|mixed
*/
public function getObject(...$args)
{
//请求间隔久时,这里会出现this->context = null的情况。Miner过来的getObject(Mysql::class,...)
return $this->context->getObjectPool()->get(...$args);
}
这个问题还能复现吗?
这个问题不但能复现, 而且是百分百复现, 请求间隔久没试过, 但是频繁访问下绝对会出现, 假设有控制器A和控制器B, 两个控制器Index方法都有数据库连接操作, 连续请求控制器A多次, 然后立刻请求控制器B多次, 交替一次或者多次之后就会出现call member method getObjectPool on null, 经过大量调试排查问题应该是出在控制器销毁对象那里, 分析原因可能是因为之前的请求尚未处理完成, 从查看monitor可以看到worker下coroutine数量不为0, 但是实际上这些coroutine在某个时间点已经执行完毕, 没有回收, 或者回收不完全, 总之这些coroutine一直存在, 新的请求进来之后被错乱的对象销毁机制销毁掉了context属性, 最终导致Miner的go方法调用失败报错, 目前的解决方案是移除controller控制器destroy方法中销毁对象的几行代码, 然后在Scheduler类的检测coroutine超时的方法中检测task->getRoutine是否为null, 如果为null, 强行调用task的destroy方法, 目前观察内存没有暴涨, 也没有再出现过context突然变成null的问题.