错误信息: XXXX client has already been bound to another coroutine
使用协程客户端时出现以下错误信息:
redis client has already been bound to another coroutine.
这表示在两个协程内使用了同一个客户端。请修改PHP代码,避免出现此情况。
错误实例:
$redis = new Co\Redis;
go(function () use ($redis) {
$redis->get("key");
});
go(function () use ($redis) {
$redis->get("key");
});
例子中两个协程同时使用$redis->get
进行IO操作,会引起混乱。底层在第二个协程调用$redis->get时会抛出上述致命错误。
解决方案:
使用Swoole\Coroutine\Channel或SplQueue
实现连接池,管理协程客户端资源。一个客户端对象仅用于一个协程,操作完毕后,再释放给其他协程使用。
报错实例代码:
private function removeCache ($companyId) {
$redis = Redis::connection('redis.clusters-pool');//redis池获取一个链接
$redis->del(CacheKey::getCheckListKey($companyId, ChecklistSkuList::DEFAULT_LIST));//当前执行完命令,资源回收
$redis->del(CacheKey::getCheckListKey($companyId, ChecklistSkuList::RECENTLY_LIST));//这个redis可能被别的协程占用,报错。
$redis->del(CacheKey::getSkuStatusKey($companyId));
}
正确写法:
将redis连接池单例引入:
/**
* @Inject()
* @var Pool
*/
protected $redis;
代码里通过:
$this->redis->del()
进行操作。
网友评论