zoukankan      html  css  js  c++  java
  • 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;
    
  • 相关阅读:
    教你用纯Java实现一个网页版的Xshell(附源码)
    Learn Terraform--Getting Started--Installing Terraform
    Install Terraform on Windows, Linux and Mac OS
    Installing kubectl
    Creating a Cron Job in K8S
    Patch multi versions of windows via Power shell
    Bash to check SSL cert expired
    K8S dashboard 创建只读账户
    K8S Link
    Kubernetes
  • 原文地址:https://www.cnblogs.com/danhuang/p/13289255.html
Copyright © 2011-2022 走看看