ホームページ  >  記事  >  バックエンド開発  >  C は PHP の MySQL データベース接続プールを実装します

C は PHP の MySQL データベース接続プールを実装します

WBOY
WBOYオリジナル
2016-06-23 13:17:30921ブラウズ

1. はじめに

接続プーリングは JAVA では広く使用されていますが、PHP ではほとんど使用されません。

Mysql を例に挙げると、JAVA で接続プールを使用する理由の 1 つは、接続リソースの作成と解放を繰り返すことによって生じるオーバーヘッドを回避するためです。 PHP では、この部分のオーバーヘッドは C API のパフォーマンスの観点から問題にならないため、すべて直接接続になります。

では、PHP 直接接続にはパフォーマンスの問題がないのに、なぜ MySQL データベース接続プール拡張機能を一度に何度も開発する必要があるのでしょうか?なぜなら、基本的な目的は、データベース接続プール機能ではなく、PHP の TS (Tthread Safe) および NTS (Not Thread Safe) 動作モードを理解することだからです。

2. 原則

接続プールの基本的な考え方は、システムのロード時に接続オブジェクトのデフォルト数を初期化し、それらをメモリに保存することです。クライアントがデータベースにアクセスする必要がある場合、オプションは割り当てです。 、シナリオに従って、作成、待機、および失敗が返されます。使用後、接続はメモリを解放するのではなく、次のリクエストによる再割り当てを待つために接続プールに戻されます。

接続プール内の接続の確立と解放は、接続プール自体によって管理されます。同時に、接続プールは、初期の最小接続数、最大接続数、最大アイドル時間を設定することによって構成できます。 、など。

注: この拡張機能では、最小接続数 (min_connection) と最大接続数 (max_connection) の設定が提供されています

3. 実装のアイデア

1. グローバル配列変数 dbpools を定義します

要素dbpools のタイプは

struct _mysql_node{     MYSQL *mysql;   //连接资源句柄     int is_used;    //标记是否被占用     int result_id;  //记录my_mysql_query的查询结果集} mysql_node;
です

2. 構成ファイルに設定されている min_connection を取得して dbpools を初期化します

3. グローバル変数 db_​​pools_length (現在所有されているリンク)、db_pools_use_length (現在使用されているリンク) を定義し、これら 2 つの値を使用します。リソース割り当てシナリオを決定します

注: グローバル変数は接続プールの実装に使用され、リソース接続はグローバル変数のステータスを変更することによって選択されるため、この拡張機能は共有グローバルの ZTS (Zend Thread Safe) スレッド セーフ モードで実行する必要があります。変数。 (例: IIS または Apache MPM ワーカー モード)

複数のプロセスをサポートする場合は、プロセス間通信を通じてグローバル変数を設定してスレッド プールを実装できます。

実装アイデアマップ:

写真: 1.jpg

4. PHPのスレッドとプロセスの動作モードを理解する (1) マルチプロセス動作モード

PHPのマルチプロセス動作モードは、Apache apxを次のように受け取ります。例。

Apache が起動すると、N 個のサブプロセスがフォークアウトされ、クライアント要求の受け入れと処理を待機します。プロセスは互いに分離されており、グローバル変数に直接アクセスすることはできません (プロセス間通信を通じてアクセスできます)。この利点は、メモリ リークにより一部のプロセスがクラッシュした場合でも、他のプロセスに影響を与えないことで、PHP 環境の長期的な安定性を確保できることです。 PHP は接着剤のようなものなので、実際には libcurl、libmemcache、libzip などの複数のライブラリを統合する API に相当します。すべてのライブラリが正常に動作することを保証するのは困難です。

したがって、PHP の高い信頼性を確保するには、このマルチプロセス モードが第一の選択肢となります。

写真: 2.jpg

(2) マルチスレッド動作モード

PHP のマルチスレッド動作モードは、IIS を例にしています。

このモードでは、バックグラウンドで実行されているプロセスが 1 つだけあり、すべてのリクエストはこのプロセスを通じて完了します。各リクエストを処理するときに、処理用に別のスレッドが作成されます。

マルチスレッド モードを使用しているため、グローバル変数に直接アクセスでき、データベース接続プールの実装が容易になります。

写真: 3.jpg

6. この拡張機能を使用するための前提条件と方法

1. widnwos での IIS サーバーまたは Apache マルチスレッド モード、php5.3.*

2. php.ini を変更し、 を追加します。 [ my_mysql]

my_mysql.host = localhost

my_mysql.user = root

my_mysql.password =

my_mysql.port = 3306

my_mysql.max_connection = 200 //最大接続数

my_mysql.min_connection = 100 // デフォルトの最小接続数

ここでの構成を見ると、このデータベース接続プール拡張機能が複数のデータ ソースの接続プールを実装していないことがわかります。接続プール自体が目的ではないため、複数のデータソースの関数を記述する特別な目的はありません。

3. php.ini を変更し、

extension=php_my_mysql.dll を追加します

4. Apache サーバーを再起動します

拡張子 DLL のダウンロード: php_my_mysql.dll

ソースコードのダウンロード: http://yアンパン. cn/QWmEN8PuuRVYN

拡張テスト結果

テスト構成:

[my_mysql]

my_mysql.max_connection = 2 //最大接続数

my_mysql.min_connection = 1 //デフォルトの最小接続数

3つ使用ブラウザでは、次のテスト スクリプトを実行します:

<?php/*** 从数据库连接池中取得一个链接资源* 可能产生如下情景* 1.如果有空闲连接则直接返回链接资源* 2.如果没有空闲连接,并且连接数没有超过最大连接数,则扩充连接池并返回新建的链接资源* 3.如果没有空闲连接同时已经是最大连接数,则进入等待,超过1.5s仍没有空闲资源则超时返回NULL.** 失败返回NULL*/$db = my_mysql_get_conn();   if($db === false){     exit('dbpool is exhushed.');}   /*** 选择数据库* @param resource $db* @param string $db_name 数据库名称*/my_mysql_select_db($db, 'test');   /*** ping数据库*/my_mysql_ping($db);   /*** 执行SQL语句,可以执行INSERT、SHOW、SELECT、UPDATE、DELETE等语句* @param  resource $db* @param string $sql SQL*/my_mysql_query($db, "INSERT INTO test VALUES(id, 'dbpool', 'test dbpool')");   // 获取上一条INSERT语句返回的自增ID$id = my_mysql_get_insert_id($db);echo $id;   $result = my_mysql_query($db, "SELECT * FROM test");   /*** 将查询结果转换为二维数组* @param resource $db*/$arr = my_mysql_fetch_assoc($result);   print_r($arr);   sleep(3);   var_dump($db);//sleep之后,必须输出$db,否则会因为PHP的解析优化,sleep过程中已经将$db释放,就没有办法测试连接被占用的情况。

テスト結果の画像:

画像: 4.jpg

接続プールのリソースが占有されており、待機状態になるため、警告が返されます。 1.5 秒待ってもリソースが存在しない場合は、dbpool is exhushed が返されます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。