• Swoole 中使用 PDO 连接池、Redis 连接池、Mysqli 连接池


    连接池使用说明

    • 所有连接池的实现均基于 ConnectionPool 原始连接池;
    • 连接池的底层原理是基于 Channel 的自动调度;
    • 开发者需要自己保证归还的连接是可重用的;
    • 若连接不可重用,需要调用 $pool->put(null); 归还一个空连接;
    • 归还空连接后,原始连接池会重新创建连接以保证连接池的数量一致。

    PDO 连接池

    <?php
    declare(strict_types=1);
    
    use SwooleCoroutine;
    use SwooleDatabasePDOConfig;
    use SwooleDatabasePDOPool;
    use SwooleRuntime;
    
    Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
    $s = microtime(true);
    const N = 1024;
    
    Coroutine
    un(function () {
        $config = (new PDOConfig)
            ->withHost('127.0.0.1')
            ->withPort(3306)
            // ->withUnixSocket('/tmp/mysql.sock')
            ->withDbName('test')
            ->withCharset('utf8mb4')
            ->withUsername('root')
            ->withPassword('root');
        // 创建连接池对象,默认创建64个连接
        $pool = new PDOPool($config);
        
        for ($n = N; $n--;) {
            Coroutine::create(function () use ($pool) {
                // 获取连接
                $pdo = $pool->get();
                $statement = $pdo->prepare('SELECT ? + ?');
                if (!$statement) {
                    throw new RuntimeException('Prepare failed');
                }
                $a = mt_rand(1, 100);
                $b = mt_rand(1, 100);
                $result = $statement->execute([$a, $b]);
                if (!$result) {
                    throw new RuntimeException('Execute failed');
                }
                $result = $statement->fetchAll();
                if ($a + $b !== (int)$result[0][0]) {
                    throw new RuntimeException('Bad result');
                }
                // 回收连接
                $pool->put($pdo);
            });
        }
    });
    
    $s = microtime(true) - $s;
    echo 'Use ' . $s . 's for ' . N . ' queries' . PHP_EOL;
    

    Redis 连接池

    <?php
    declare(strict_types=1);
    
    use SwooleCoroutine;
    use SwooleDatabaseRedisConfig;
    use SwooleDatabaseRedisPool;
    use SwooleRuntime;
    
    Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
    $s = microtime(true);
    const N = 1024;
    
    Coroutine
    un(function () {
        $config = (new RedisConfig)
            ->withHost('127.0.0.1')
            ->withPort(6379)
            ->withAuth('')
            ->withDbIndex(0)
            ->withTimeout(1);
        // 创建连接池对象,默认创建64个连接
        $pool = new RedisPool($config);
        
        for ($n = N; $n--;) {
            Coroutine::create(function () use ($pool) {
                // 获取连接
                $redis = $pool->get();
                $result = $redis->set('foo', 'bar');
                if (!$result) {
                    throw new RuntimeException('Set failed');
                }
                $result = $redis->get('foo');
                if ($result !== 'bar') {
                    throw new RuntimeException('Get failed');
                }
                // 回收连接
                $pool->put($redis);
            });
        }
    });
    
    $s = microtime(true) - $s;
    echo 'Use ' . $s . 's for ' . (N * 2) . ' queries' . PHP_EOL;
    

    Mysqli 连接池

    <?php
    declare(strict_types=1);
    
    use SwooleCoroutine;
    use SwooleDatabaseMysqliConfig;
    use SwooleDatabaseMysqliPool;
    use SwooleRuntime;
    
    Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
    $s = microtime(true);
    const N = 1024;
    
    Coroutine
    un(function () {
        $config = (new MysqliConfig)
            ->withHost('127.0.0.1')
            ->withPort(3306)
            // ->withUnixSocket('/tmp/mysql.sock')
            ->withDbName('test')
            ->withCharset('utf8mb4')
            ->withUsername('root')
            ->withPassword('root');
        // 创建连接池对象,默认创建64个连接
        $pool = new MysqliPool($config);
        for ($n = N; $n--;) {
            Coroutine::create(function () use ($pool) {
                // 获取连接
                $mysqli = $pool->get();
                $statement = $mysqli->prepare('SELECT ? + ?');
                if (!$statement) {
                    throw new RuntimeException('Prepare failed');
                }
                $a = mt_rand(1, 100);
                $b = mt_rand(1, 100);
                if (!$statement->bind_param('dd', $a, $b)) {
                    throw new RuntimeException('Bind param failed');
                }
                if (!$statement->execute()) {
                    throw new RuntimeException('Execute failed');
                }
                if (!$statement->bind_result($result)) {
                    throw new RuntimeException('Bind result failed');
                }
                if (!$statement->fetch()) {
                    throw new RuntimeException('Fetch failed');
                }
                if ($a + $b !== (int)$result) {
                    throw new RuntimeException('Bad result');
                }
                while ($statement->fetch()) {
                    continue;
                }
                // 回收连接
                $pool->put($mysqli);
            });
        }
    });
    
    $s = microtime(true) - $s;
    echo 'Use ' . $s . 's for ' . N . ' queries' . PHP_EOL;
    
  • 相关阅读:
    为民服务贴——提供学习交流的其他比较好的平台
    【转】Web服务软件工厂
    【转】在 SQL Server 2005 中使用表值函数来实现空间数据库
    回家过年(春联)
    ArcGIS Server9.2学习开发(2)——安装配置篇
    烦困人间 游戏生活
    ArcGIS Server9.2学习开发(6)——使用Navigation、ZoomLevel和ScaleBar控件
    【转】激活 ActiveX 控件
    用Eclipse写java
    无题
  • 原文地址:https://www.cnblogs.com/danhuang/p/13289255.html
Copyright © 2020-2023  润新知