open-smf/connection-pool 是一个基于Swoole的通用连接池,常被用作数据库连接池。
依赖
依赖版本PHP>=7.0.0
Swoole>=4.2.9Recommend 4.2.13+
安装
通过Composer安装。
composer require "open-smf/connection-pool:~1.0"
使用
更多示例。可用的连接器
连接器说明CoroutineMySQLConnectorSwooleCoroutineMySQL
的实例CoroutinePostgreSQLConnectorSwooleCoroutinePostgreSQL
的实例,编译Swoole
时需要添加参数--enable-coroutine-postgresql
CoroutineRedisConnectorSwooleCoroutineRedis
的实例PhpRedisConnectorRedis
的实例,需要安装redisYourConnectorYourConnector
必须实现接口ConnectorInterface
,任何对象均可作为连接实例
程序猿的生活:【粉丝福利】30G-PHP进阶资料,拿到你也能30K,免费领取基本用法
use SmfConnectionPoolConnectionPool;use SmfConnectionPoolConnectorsCoroutineMySQLConnector;use SwooleCoroutineMySQL;go(function () {// MySQL连接数区间:[10, 30]$pool = new ConnectionPool(['minActive' => 10,'maxActive' => 30,'maxWaitTime' => 5,'maxIdleTime' => 20,'idleCheckInterval' => 10,],new CoroutineMySQLConnector, // 指明连接器实例,这里使用协程MySQL连接器,这样就可以创建一个协程MySQL的数据库连接池['host' => '127.0.0.1','port' => '3306','user' => 'root','password' => 'xy123456','database' => 'mysql','timeout'=> 10,'charset'=> 'utf8mb4','strict_type' => true,'fetch_mode' => true,]);echo "初始化连接池...n";$pool->init();defer(function () use ($pool) {echo "关闭连接池...n";$pool->close();});echo "从连接池中借出连接...n";/**@var MySQL $connection */$connection = $pool->borrow();// 执行查询语句$status = $connection->query('SHOW STATUS LIKE "Threads_connected"');echo "用完连接后,尽快归还...n";$pool->return($connection);var_dump($status);});
在Swoole Server中的用法
use SmfConnectionPoolConnectionPool;use SmfConnectionPoolConnectionPoolTrait;use SmfConnectionPoolConnectorsCoroutineMySQLConnector;use SmfConnectionPoolConnectorsPhpRedisConnector;use SwooleCoroutineMySQL;use SwooleHttpRequest;use SwooleHttpResponse;use SwooleHttpServer;class HttpServer{use ConnectionPoolTrait;protected $swoole;public function __construct(string $host, int $port){$this->swoole = new Server($host, $port);$this->setDefault();$this->bindWorkerEvents();$this->bindHttpEvent();}protected function setDefault(){$this->swoole->set(['daemonize' => false,'dispatch_mode' => 1,'max_request' => 8000,'open_tcp_nodelay'=> true,'reload_async'=> true,'max_wait_time' => 60,'enable_reuse_port'=> true,'enable_coroutine'=> true,'http_compression'=> false,'enable_static_handler' => false,'buffer_output_size' => 4 * 1024 * 1024,'worker_num' => 4, // 每个Worker持有一个独立的连接池]);}protected function bindHttpEvent(){$this->swoole->on('Request', function (Request $request, Response $response) {$pool1 = $this->getConnectionPool('mysql');/**@var MySQL $mysql */$mysql = $pool1->borrow();$status = $mysql->query('SHOW STATUS LIKE "Threads_connected"');// 用完连接后,尽快归还$pool1->return($mysql);$pool2 = $this->getConnectionPool('redis');/**@var Redis $redis */$redis = $pool2->borrow();$clients = $redis->info('Clients');// 用完连接后,尽快归还$pool2->return($redis);$json = ['status' => $status,'clients' => $clients,];// Other logic// ...$response->header('Content-Type', 'application/json');$response->end(json_encode($json));});}protected function bindWorkerEvents(){$createPools = function () {// 所有的MySQL连接数区间:[4 workers * 2 = 8, 4 workers * 10 = 40]$pool1 = new ConnectionPool(['minActive' => 2,'maxActive' => 10,],new CoroutineMySQLConnector,['host' => '127.0.0.1','port' => '3306','user' => 'root','password' => 'xy123456','database' => 'mysql','timeout'=> 10,'charset'=> 'utf8mb4','strict_type' => true,'fetch_mode' => true,]);$pool1->init();$this->addConnectionPool('mysql', $pool1);// 所有Redis连接数区间:[4 workers * 5 = 20, 4 workers * 20 = 80]$pool2 = new ConnectionPool(['minActive' => 5,'maxActive' => 20,],new PhpRedisConnector,['host'=> '127.0.0.1','port'=> '6379','database' => 0,'password' => null,]);$pool2->init();$this->addConnectionPool('redis', $pool2);};$closePools = function () {$this->closeConnectionPools();};// Worker启动时创建MySQL和Redis连接池$this->swoole->on('WorkerStart', $createPools);// Worker正常退出或错误退出时,关闭连接池,释放连接$this->swoole->on('WorkerStop', $closePools);$this->swoole->on('WorkerError', $closePools);}public function start(){$this->swoole->start();}}// 启用协程Runtime来让PhpRedis扩展一键协程化SwooleRuntime::enableCoroutine(true);$server = new HttpServer('0.0.0.0', 5200);$server->start();
本人已用于生产环境,表现稳定
贡献
Github,欢迎 Star & PR。原文来自思否/a/1190