まず、接続プールが使用される理由と、接続プールが解決できる問題を理解する必要があります。
接続プールの主な役割
1.データサーバーとの3つのTCPハンドシェイクを確立し、接続を閉じて4回振るオーバーヘッドを減らし、クライアントとmysqlサーバーの負荷を減らし、リクエストの応答時間を短縮します
。2.データベースへの同時接続数を減らします。アプリケーションサーバーが多すぎるために発生するデータベースの接続が多すぎる
問題を解決する場合1
、データベース接続プールはworkermanで最も効率的な方法ではありません。PHPはシングルプロセスおよびシングルスレッドであるため、PHPを使用してデータベース接続プールを実装するには、必ず別のプロセスを使用する必要があります。その場合、プロセス間通信が必要になるため、mysqlと直接通信するプロセスが接続プールになります。 mysqlの通信により、アプリケーション側の負荷が増加します。
問題1を解決する最も効率的な方法は、各ビジネスプロセス(workermanによって提供されるDBクラスなど)に対して単一のデータベースインスタンスを確立して長いデータベース接続を実装し、各プロセスのすべてのリクエストが独自の長いデータベース接続を使用するようにすることです。プロセスのライフサイクルは、TCPハンドシェイクと切断ウェーブのオーバーヘッドのみであり、アプリケーションはmysqlと直接通信します。接続プールの中央にあるプロセス間のIPC通信の中間プールはありません。パフォーマンスは最高であり、誰もいません。
質問2の場合は、
最初にアプリケーションサーバーの数を確認します。各サーバーには、mysqlへの複数の同時接続があります。アプリケーションサーバーが10、サーバーごとに50プロセス、プロセスごとに1データベース接続しかない場合、mysqlサーバーへの同時接続は10 * 50 = 500(アクティブな接続ではない)であり、mysqlへの同時接続は500です。これは簡単です。問題2を解決するために、接続プールを使用する必要はありません。
アプリケーションサーバーが1000台ある場合は接続プールが必要ですが、この接続プールはローカルアプリケーションサーバーで実行されている接続プールにすることはできません。 10個の接続を開くと、データベース接続の数が簡単にいっぱいになります。したがって、この問題を解決するために、現在のサーバー上のいくつかのタスクプロセスによって実装された接続プールを開くことは期待しないでください。
1000台のアプリケーションサーバーのクラスターでは、接続プーリングを実装するために各サーバーでいくつかのプロセスを実行することも信頼できません。問題2を実際に解決できる方法は、独立したデータベース接続プールサーバーまたはクラスターを確立して、すべてのデータベースリンクをグローバルに管理することです。
要約すると、
PHPのmysql接続プールが質問1に対してのみ実装されている場合、データベースシングルトンは、いわゆる接続プールよりも単純で効率的なアプローチです。
問題2を達成する場合は、ビジネスにも一定の規模が必要です。workermanを使用して個別の接続プールクラスターを作成する場合、いくつかのタスクプロセスを確立する簡単な方法を以下に示します。各プロセスはデータベース接続を作成します。タスクプロセスはsqlリクエストをmysqlサーバーに送信し、mysqlサーバーが戻った後、タスクプロセスは結果をsqlイニシエーターに送信します。
接続プールのコードは次のようになります。複数のサーバーで構成される接続プールのクラスターの場合、workermanの前にlvs を追加することをお勧めします// task worker,使用Text协议
$task_worker = new Worker('Text://0.0.0.0:1234');
$task_worker->count = 64;
$task_worker->name = 'MysqlTask';
$task_worker->onMessage = function($connection, $sql)
{
// 执行sql.... 得到结果,这里省略....
$sql_result = your_mysql_query($sql);
// 发送结果
$connection->send(json_encode($sql_result));
};use \Workerman\Connection\AsyncTcpConnection;
// 与远程连接池服务建立异步链接,ip为远程连接池服务的ip,如果是集群就是lvs的ip
$sql_connection = new AsyncTcpConnection('Text://ip:1234');
// 发送sql
$sql_connection->send("SELECT ... FROM .....");
// 异步获得sql结果
$sql_connection->onMessage = function($sql_connection, $sql_result)
{
// 这里只是打印结果
var_dump(json_decode($task_result));
};
// 执行异步链接
$sql_connection->connect();