基于easyswoole实现的redis连接池

/**
 * Class MysqlPoolService   mysql连接池
 * @package App\Service
 */
class MysqlPoolService
{
    use Singleton;
    protected $config;
    protected $pool;
    protected $min = 5;
    protected $defaultSize = 100;
    protected $max = 1000;
    protected $timeout = 0.1;
    protected static $links = [];

    /**
     * MysqlPoolService constructor.
     * @throws Exception
     */
    protected function __construct()
    {
        $this->config = Config::getInstance()->getConf('MYSQL-POOL');
        if (empty($this->pool)) {
            $this->defaultSize = $this->config['master']['pool_max_size'];
            $this->min         = $this->config['master']['pool_size'];
            $this->timeout     = $this->config['master']['pool_get_timeout'];
            $this->pool        = new Channel($this->max);
            for ($i = 0; $i < $this->min; $i++) {
                $this->add($this->getMysql());
            }
            \EasySwoole\Component\Timer::getInstance()->loop(5 * 60 * 1000, function (){
                // todo 回收过多的老进程
                $this->recycle();
            });
        }
    }

    /**
     * @return MySQL
     * @throws Exception
     */
    protected function getMysql(): MySQL
    {
        if(count(self::$links) > $this->max){
            throw new Exception('mysql connects too many!');
        }
        $mysql = new MySQL();
        $config = $this->config['master'];
        $config['time'] = microtime(true);
        $rs = $mysql->connect($config);
        if($rs == false){
            throw new Exception('mysql connect error!');
        }
        self::$links[$mysql->sock] = $mysql;
        return $mysql;
    }

    /**
     * 回收闲置连接
     */
    protected function recycle()
    {
        while (count(self::$links) > $this->defaultSize){
            /**
             * @var MySQL $mysql
             */
            $mysql = $this->pool->pop($this->timeout);
            if($mysql){
                $sock = $mysql->sock;
                defer(function()use($mysql){
                    if(!empty($mysql) && $mysql->connected){
                        $mysql->close();
//                        echo "recycle-mysql\n";
                    }
                });
                unset(self::$links[$sock]);
            }
        }
    }

    /**
     * 入池
     * @param MySQL $mysql
     */
    protected function add(MySQL $mysql)
    {
        $this->pool->push($mysql,$this->timeout);
    }

    /**
     * 获取连接
     *
     * @return MySQL
     * @throws Exception
     */
    public function get(): MySQL
    {
        $length = $this->pool->length();

        // 追加到默认值
        if($length <= $this->min){
            $this->add($this->getMysql());
        }
        /**
         * @var MySQL $mysql
         */
        $mysql = $this->pool->pop($this->timeout);

        // 超时无法获取连接,追加连接
        if(empty($mysql)){
            $mysql = $this->getMysql();
            $this->add($mysql);
        }

        // 连接断开,加入新连接
        if (empty($mysql->connected)) {
            $mysql = $this->getMysql();
        }

        // 处理结束之后,回收连接
        defer(function () use ($mysql) {
            $this->add($mysql);
        });

        return $mysql;
    }
}

大概按自己的思路处理了,希望大佬指出不足,以加以完善。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值