PHPはMySQLの長い接続、接続プールを探索します

phpがmysqlに接続する方法は、ほとんどがmysql拡張、mysqli拡張、およびpdo_mysql拡張であり、これらは公式に提供されています。phpの操作メカニズムは、ページの実行後にphpプロセス内のすべてのリソースが解放されることです。ローカルテストページhttp://127.0.0.1/1.phpへの複数の同時アクセスがある場合、phpとWebサーバーの違いに応じて、対応するスレッドまたはプロセスを開いてリクエストを処理すると、リクエスト後に結果がリリースされます。つまり、phpは言語レベルからページ間で一部のデータを転送できませんが、pdoのmysql_pconnectとATTRは、配列(PDO :: ATTR_PERSISTENT => true)を次のように設定すると長い接続を実現できます。

$conn = new PDO($dsn, DB_USER, DB_PASSWORD,
    array(PDO::ATTR_PERSISTENT => true)
);

長い接続の役割は、高負荷状態で長い接続を再利用することにより、各ページのデータベース接続を確立する時間が短縮され、mysql接続を確立する時間が私のマシンにあることだと思います。

  • データベース接続が10未満の場合、mysql pdo接続確立時間は0.003ミリ秒、mysqli確立接続時間は0.14ミリ秒です。

  • データベース接続がほぼいっぱいになると、mysql pdoの接続時間は0.13ミリ秒、mysqliの接続時間は0.13ミリ秒になります。

上記のサンプルはすべて推定時間であり、推定するには小さすぎます。実際、接続を確立する時間は長くありませんが、なぜmysqlの長い接続や接続プールなどが必要なのですか?たとえば、単一のサーバーが受け入れることができるmysqlの同時実行性は約200であり、Webサーバーの同時実行性は約700です。500の同時接続が多数終了すると、Webサーバーが完全にロードされず、mysqlが早期に到着します。フルロードすると、すべてのページが応答しなくなったり、データベース接続を確立したページのパフォーマンスが非常に遅くなります。

phpでのMySQLの長い接続PHPには多くの動作モードがあるため、長い接続の実装もたくさんあります。PHPにはプロセスプールと接続プールの概念がないため、長い接続を実現するにはWebサーバーのサポートが必要です。ほとんどの場合、PHPアプリケーション自体はアプリケーションサーバーではありません(新星は優れたPHPアプリケーションサーバーですが、レベルc)で完了。したがって、phpの長い接続は、実際にはapacheなどのmpmモジュールを備えたWebサーバーです。Linuxでは、apacheはプロセスプールを維持します。apachempm機能をオンにすると、apacheはデフォルトでプロセスプールを維持します。mysqlの長い接続後の接続、およびソセット接続としては閉じられませんが、リリースされていないものとして、プロセスプール/スレッドプールに入れられます。接続が必要な場合、apacheは維持しているプロセスプール/スレッドプールからmysqlソケット接続を取り出し、接続を再利用できます。

ここでテストしてみましょう。まず、ネイティブ環境はarchlinuxであり、以下で使用されているmysql httpd phpは、すべて/ home / dengpan / optディレクトリにある独自にコンパイルされたソースコードです。httpdのmpmモデルはワーカーを使用します。httpdのmpm(並列機能に使用されるapache、一般に複数の処理モジュールとして知られています)には、実際にはperfork、worker、およびeventの3つのタイプがあります。mpmの利点は、apacheがいつでも予備のスペアまたはアイドル状態の子プロセス(サーバースレッドプール)を持ち、いつでも新しい要求を待機できるようにすることです。これにより、クライアントはサービスを要求する前に子プロセスの生成を待つ必要がなくなります。

使用するmpmは、作業mpmをapacheにコンパイルするなど、apacheにコンパイルするために個別に指定する必要があります。たとえば、私の最も単純化されたhttpdコンパイルパラメーターは次のとおりです。

./configure \
--with-apr=/home/dengpan/opt/apr-1.5.2 \
--with-apr-util=/home/dengpan/opt/apr-util-1.5.4 \
--prefix=/home/dengpan/opt/httpd-2.4.16 \
--with-mpm=worker

httpdによってロードされたモジュールを表示します。

ここに写真の説明を挿入

そのworker.cがコンパイルされているのを見て、

mpmの構成パラメーターは次のとおりです。

<IfModule mpm_worker_module>
	StartServers			 15
	MinSpareThreads		 75
	MaxSpareThreads		250
	ThreadsPerChild		 10
	MaxRequestWorkers	  400
	MaxConnectionsPerChild   0
</IfModule>

apacheを起動し、pstreeを使用して| -httpd—15 * [httpd—11 * [{httpd}]]を確認します。これは、15のサーバープロセスがあり、各サーバーに10の子スレッドがあることを示しています。mpm全体で維持されるアイドルスレッドの最小数は75で、アイドルスレッドの最大数は250です。完全にロードされた最大のワーカースレッドは400です。次に、シェルスクリプトを準備し、1秒ごとにmysqlのアクティブな接続の現在の数を出力し、mysqlの現在の接続の数を確認します。私が使用する方法は2つあります。

  • mysqlシェルに入り、SHOW STATUS WHERE variable_name= 'Threads_connected'を実行します。ただし、このメソッドではmysqlシェルを入力する必要があります。接続が多い場合、mysqlシェルは入力できず、クエリも実行できません。

  • シェルの直接クエリ、find / proc / pidof mysqld/ fd / -follow -type s | wc -l、root権限が必要です。利点は、接続が多すぎるためにmysqlがシェルに入ることができなくても、接続できることです。

ここでは方法2が使用されます。これは、マシンに戻るmysqlが後で完全にロードされるためです。次のようにシェルを記述します。

#!/bin/bash
while(true)
do
    find /proc/`pidof mysqld`/fd/ -follow -type s | wc -l
	sleep 1
done

シェルを実行した後、現在の接続数を継続的に出力し、テストを取得できます。

  1. cliでphpを実行します。長い接続は無効です。スクリプトがcliで終了するとすぐに、接続が解放されます。

  2. apche + mod_phpがmpmモジュールを開かない場合、mysqlmysql_pconnectまたはpdo_mysqllong接続に関係なく、ページにアクセスした後にmysql接続が解放されます。

  3. apche + mod_phpがmpmモジュール(ワーカーモード)をオンにすると、mysql mysql_pconnect、pdo_mysql long接続に関係なく、ページにアクセスし、mysql接続+1になり、mysql接続の最大数に達するまで増加しませんが、アクセスページは対応する接続​​クエリを再利用できます。データ。

  4. nginx + php-fpmでのMySQLの長い接続は基本的に効果がありません。

apacheがmysql接続を再利用できる理由は、apacheがmysql自体にいくつかの関数とモジュールを実装している必要があることを意味します。そうしないと、不明なタイプのソケットポインターを保存できません。lddで表示、

➜  mysql_persist  ldd /home/dengpan/opt/httpd-2.4.16/bin/httpd
        linux-vdso.so.1 (0x00007ffffcbde000)
        libpcre.so.1 => /usr/lib/libpcre.so.1 (0x00007f8e8d17c000)
        libaprutil-1.so.0 => /home/dengpan/opt/apr-util-1.5.4/lib/libaprutil-1.so.0 (0x00007f8e8cf57000)
        libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f8e8cd2d000)
        libapr-1.so.0 => /home/dengpan/opt/apr-1.5.2/lib/libapr-1.so.0 (0x00007f8e8cafb000)
        libuuid.so.1 => /usr/lib/libuuid.so.1 (0x00007f8e8c8f6000)
        librt.so.1 => /usr/lib/librt.so.1 (0x00007f8e8c6ee000)
        libcrypt.so.1 => /usr/lib/libcrypt.so.1 (0x00007f8e8c4b6000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f8e8c299000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f8e8c095000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f8e8bcf3000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8e8d3ec000)

/home/dengpan/opt/apr-util-1.5.4/lib/libaprutil-1.so.0および/home/dengpan/opt/apr-1.5.2/lib/libapr-1.so.0を推測できます。 mysqlに関連するコードセグメントを実装する必要があります。ローカルでコンパイルしたので、関数エントリを見つけるのは簡単です。ファイル/home/dengpan/github/apache-httpd/apr-util-1.5.4/dbd/apr_dbd_mysql.cは、実際には一般的なデータベースのapacheのmod_dbdです。長い接続をサポートします。nginxとphp-fpmの関係は、phpとapacheの関係とは異なるため、nginx + php-fpmは対応する長い接続を実現できません。おそらくphp-fpmはmysqlプロセスとスレッドプールを実行しません。

最後に、アドバイスをします。一般に、小さなPHPアプリケーションにはパフォーマンスの問題はありません。PHP自体は非常に高速にmysqlに接続し、それらの多くはパフォーマンスが過剰です。Apacheが徐々にnginxに置き換えられると、PHPのmysqlの長い接続は増加するだけです。チキンリブ。スタンドアロンマシンの場合、mysqlが接続を作成する必要があるのではないかと心配している場合は、mysqlの作成にシングルトンモードを使用するのが最適です。このようなページでは、mysql接続インスタンスが1つだけ作成されます。次のシングルトンのサンプルコードのように、これはシングルトンを実現するためにフレームワークで記述するのに適しています。

<?php
/**
 * Created by PhpStorm.
 * User: dengpan
 * Date: 15-7-24
 * Time: 下午2:56
 */
include "./db.php";
class DB {
    
    
	private static $_instance;
	private $db;
	private function __construct()
	{
    
    
		$this->db =  new mysqli(DB_HOST, DB_USER, DB_PASSWORD, 'my', 3307);
	}
	public static function getInstance()
	{
    
    
		if (!(self::$_instance instanceof DB)) {
    
    
			self::$_instance = new self();
		}
		return self::$_instance;
	}
	private function __clone()
	{
    
    
	}
	public function getConn()
	{
    
    
		return $this->db;
	}
}
$conn = DB::getInstance()->getConn();

注意してください、迷子にならないでください

さて、みなさん、上記はこの記事の全内容です。ここで見ることができるのはすべて才能です。さっきも言ったように、PHPには技術的なポイントがたくさんあります。多すぎるので、書くのは本当に不可能で、書いた後はあまり読まないので、必要に応じてここでPDFとドキュメントに整理します。できる

クリックしてシークレットコードを入力してください:PHP +「プラットフォーム」

ここに写真の説明を挿入

ここに写真の説明を挿入


学習内容の詳細については、[Comparative Standard Factory]の優れたPHPアーキテクトチュートリアルカタログをご覧ください。給与が確実に上がるように読むことができます(継続的な更新)

上記のコンテンツは、すべての人に役立つことを願っています。多くのPHP担当者は、上級者になると常に問題やボトルネックに直面します。ビジネスコードを書きすぎると、方向性がわかりません。どこから改善を始めればよいかわかりません。これに関する情報をまとめました。ただし、これらに限定されません。分散アーキテクチャ、高スケーラビリティ、高パフォーマンス、高同時実行性、サーバーパフォーマンスチューニング、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql最適化、シェルスクリプト、Docker、マイクロサービス、Nginxなど。多くの知識ポイント、高度な高度な乾物は、誰とでも無料で共有でき、必要な人は私のPHPテクノロジー交換グループに参加できます

おすすめ

転載: blog.csdn.net/weixin_49163826/article/details/108940141