美文网首页
swoft协程开发公用redis一个链接报错

swoft协程开发公用redis一个链接报错

作者: 金星show | 来源:发表于2019-11-22 11:43 被阅读0次

    错误信息: 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() 
    进行操作。
    

    相关文章

      网友评论

          本文标题:swoft协程开发公用redis一个链接报错

          本文链接:https://www.haomeiwen.com/subject/ehiebctx.html