PHP Sessionは同時問題を引き起こす可能性がある
3710 ワード
Webアプリケーションの開発を行う際には、Sessionでデータを格納することがよくあります.しかし、PHPではSessionの不適切な使用が同時問題を引き起こす可能性があることを知らない人もいるかもしれません.インドの医療業界のソフトウェアソリューションプロバイダPlus 91 Technologiesの高級エンジニアKishan Gorは、個人ブログでこの問題を説明した.
同じクライアントが複数のリクエストを同時に送信し、各リクエストがSessionを使用している場合、PHP Sessionロックが存在すると、サーバはパラレルではなくシリアルにこれらのリクエストに応答します.これは、デフォルトではPHPがファイルを使用してSessionデータを格納しているためです.新しいセッションごとにPHPはファイルを作成し、データを書き込み続けます.したがって、セッションを呼び出すたびにstart()メソッドでは、セッションファイルが開き、ファイルのパーソナルロックが取得されます.これにより、サーバ・スクリプトが要求を処理しており、クライアントが同じセッションを使用する必要がある要求を送信している場合、前の要求処理が完了するまで、ファイル上の排他ロックが解放されるまで、後の要求はブロックされます.ただし、これは、同じクライアントからの複数の要求に限定され、すなわち、あるクライアントからの要求は、別のクライアントからの要求をブロックしない.
スクリプトが短い場合は、通常は問題ありません.ただし、スクリプトの実行時間が長い場合は、問題が発生する可能性があります.現代のWebアプリケーション開発では、AJAX技術を用いて同じページ内で複数のリクエストを送信してデータを取得するという非常に一般的なケースがある.これらのリクエストがすべてSessionを使用する必要がある場合、最初のリクエストがサーバに到着するとSessionロックが取得され、他のリクエストは待機しなければなりません.すべてのリクエストは、互いに依存関係がなくてもシリアル処理されます.これにより、ページの応答時間が大幅に増加します.
この問題を回避する方法は、Sessionを使用した直後にsession_を呼び出すことです.write_close()メソッドはセッションを閉じます.これにより、現在のスクリプトが処理を待っていても、セッションロックが解放されます.このメソッドを呼び出すと、現在のスクリプトはセッションをさらに操作できないことに注意してください.
特に、本明細書で述べた問題および観点は、session_の使用にのみ適用されることを指摘する必要がある.start()メソッドのPHPデフォルトセッション管理モード.たとえば、AWS EC 2にアプリケーションを管理し、DynamoDBを正しく構成すれば、Sessionロックの問題は発生しないというユーザーもいます.
例:
PHPのデフォルトのセッションプロセッサはセッションです.save_handler=files(ファイル)です.同じクライアントで複数のリクエスト(ajaxがページで複数のリクエストを同時に送信するなど)を同時に送信し、スクリプトの実行時間が長い場合、sessionファイルがブロックされ、パフォーマンスに影響します.PHPはリクエストごとにセッションを実行するのでstart()では、ファイル排他ロックが取得され、そのリクエスト処理が終了した後にのみ、排他ロックが解放されます.これにより、同時に複数のリクエストがブロックされます.
sessionブロック単純プレゼンテーション2つのphpファイルを作成する:session_a.php,session_b.php.
この2つのスクリプトに同時にアクセスすると、1つのスクリプトが別のスクリプトより5秒遅れていることがわかります.ファイルのセッションをwrite_close()関数コメントがキャンセルされた後、同時にアクセスすると2つのスクリプトが同時に実行できることがわかります.
sessionロック処理メカニズムちなみにsession_commit()はセッションですwrite_close()の別名は、後者の代わりに前者を使用することもできます.
session_start()呼び出しの場合、session処理メカニズムはデフォルトでseesionファイルを開くか作成し、すぐにこのファイルにロック状態(locked)を与えます.session_commit()呼び出し時またはスクリプト実行が完了すると、ファイルはロック解除されます.
ロック状態には重要な影響があります.セッションを使用したPHPスクリプトを同時に要求するのは、並列実行ではなく、分離されます.ユーザが1つのリクエストを開始し、同時に別のリクエストを開始すると、前のリクエストが完全に完了するまでブロックされます.
Sessionロックのメリットとは思わないでくださいいわゆるブロック現象はPHPのBUGで、もちろんそうではありませんが、逆に分離して実行するのが正しい場合があります.カートのケースを考えてみましょう.
ユーザーはA要求を開始し、スクリプトはショッピングカートの物品を表示するためのsessionデータを読み取る.Aリクエストが完了する前に、ユーザーは「カートに加入する」ボタンをクリックし、Bリクエストを送信した.B A要求が完了するのを待って、セッションにデータを追加する.セッションをロックしなかったらどうなりますか?
BはAの完了を待たずにセッションデータを読み出して書き込む.Aは、前に読み取ったセッションデータの完了と書き込みを要求し、上記Bに書き込まれたデータを上書きする.したがって、セッションを使用するときは、現在の実際の環境を考慮する必要があります.
ThinkPHPはどのようにsessionブロックを解決するか最近国内のPHPフレームワークThinkPHPを使用し始めたが、ブロック問題に遭遇した.公式文書をよく見ていないので、長い間デバッグしていなかったが、もう少しで怒ってフレームワークを放棄するところだった.その後、配置項目に「SESSION_AUTO_START」の配置があり、sessionを自動的にロードし、断固としてFALSEに設定し、すべて正常に戻った.
セッションを使用する必要がある場合は、PHP固有の関数を使用します.
参照先:
http://www.infoq.com/cn/news/2015/01/php-session-concurrency-problems
http://www.phpddt.com/php/php-session-problem.html
http://www.blhere.com/984.html
転入先:PHPセッションで同時発生の問題が発生する可能性がある
同じクライアントが複数のリクエストを同時に送信し、各リクエストがSessionを使用している場合、PHP Sessionロックが存在すると、サーバはパラレルではなくシリアルにこれらのリクエストに応答します.これは、デフォルトではPHPがファイルを使用してSessionデータを格納しているためです.新しいセッションごとにPHPはファイルを作成し、データを書き込み続けます.したがって、セッションを呼び出すたびにstart()メソッドでは、セッションファイルが開き、ファイルのパーソナルロックが取得されます.これにより、サーバ・スクリプトが要求を処理しており、クライアントが同じセッションを使用する必要がある要求を送信している場合、前の要求処理が完了するまで、ファイル上の排他ロックが解放されるまで、後の要求はブロックされます.ただし、これは、同じクライアントからの複数の要求に限定され、すなわち、あるクライアントからの要求は、別のクライアントからの要求をブロックしない.
スクリプトが短い場合は、通常は問題ありません.ただし、スクリプトの実行時間が長い場合は、問題が発生する可能性があります.現代のWebアプリケーション開発では、AJAX技術を用いて同じページ内で複数のリクエストを送信してデータを取得するという非常に一般的なケースがある.これらのリクエストがすべてSessionを使用する必要がある場合、最初のリクエストがサーバに到着するとSessionロックが取得され、他のリクエストは待機しなければなりません.すべてのリクエストは、互いに依存関係がなくてもシリアル処理されます.これにより、ページの応答時間が大幅に増加します.
この問題を回避する方法は、Sessionを使用した直後にsession_を呼び出すことです.write_close()メソッドはセッションを閉じます.これにより、現在のスクリプトが処理を待っていても、セッションロックが解放されます.このメソッドを呼び出すと、現在のスクリプトはセッションをさらに操作できないことに注意してください.
特に、本明細書で述べた問題および観点は、session_の使用にのみ適用されることを指摘する必要がある.start()メソッドのPHPデフォルトセッション管理モード.たとえば、AWS EC 2にアプリケーションを管理し、DynamoDBを正しく構成すれば、Sessionロックの問題は発生しないというユーザーもいます.
例:
PHPのデフォルトのセッションプロセッサはセッションです.save_handler=files(ファイル)です.同じクライアントで複数のリクエスト(ajaxがページで複数のリクエストを同時に送信するなど)を同時に送信し、スクリプトの実行時間が長い場合、sessionファイルがブロックされ、パフォーマンスに影響します.PHPはリクエストごとにセッションを実行するのでstart()では、ファイル排他ロックが取得され、そのリクエスト処理が終了した後にのみ、排他ロックが解放されます.これにより、同時に複数のリクエストがブロックされます.
sessionブロック単純プレゼンテーション2つのphpファイルを作成する:session_a.php,session_b.php.
<?php
// session_a.php
session_start();
$_SESSION['a'] = date('H:i:s');
// session_write_close();
sleep(5);
echo $_SESSION['a'];
<?php
// session_b.php
session_start();
$_SESSION['b'] = date('H:i:s');
// session_write_close();
sleep(5);
echo $_SESSION['b'];
この2つのスクリプトに同時にアクセスすると、1つのスクリプトが別のスクリプトより5秒遅れていることがわかります.ファイルのセッションをwrite_close()関数コメントがキャンセルされた後、同時にアクセスすると2つのスクリプトが同時に実行できることがわかります.
sessionロック処理メカニズムちなみにsession_commit()はセッションですwrite_close()の別名は、後者の代わりに前者を使用することもできます.
session_start()呼び出しの場合、session処理メカニズムはデフォルトでseesionファイルを開くか作成し、すぐにこのファイルにロック状態(locked)を与えます.session_commit()呼び出し時またはスクリプト実行が完了すると、ファイルはロック解除されます.
ロック状態には重要な影響があります.セッションを使用したPHPスクリプトを同時に要求するのは、並列実行ではなく、分離されます.ユーザが1つのリクエストを開始し、同時に別のリクエストを開始すると、前のリクエストが完全に完了するまでブロックされます.
Sessionロックのメリットとは思わないでくださいいわゆるブロック現象はPHPのBUGで、もちろんそうではありませんが、逆に分離して実行するのが正しい場合があります.カートのケースを考えてみましょう.
ユーザーはA要求を開始し、スクリプトはショッピングカートの物品を表示するためのsessionデータを読み取る.Aリクエストが完了する前に、ユーザーは「カートに加入する」ボタンをクリックし、Bリクエストを送信した.B A要求が完了するのを待って、セッションにデータを追加する.セッションをロックしなかったらどうなりますか?
BはAの完了を待たずにセッションデータを読み出して書き込む.Aは、前に読み取ったセッションデータの完了と書き込みを要求し、上記Bに書き込まれたデータを上書きする.したがって、セッションを使用するときは、現在の実際の環境を考慮する必要があります.
ThinkPHPはどのようにsessionブロックを解決するか最近国内のPHPフレームワークThinkPHPを使用し始めたが、ブロック問題に遭遇した.公式文書をよく見ていないので、長い間デバッグしていなかったが、もう少しで怒ってフレームワークを放棄するところだった.その後、配置項目に「SESSION_AUTO_START」の配置があり、sessionを自動的にロードし、断固としてFALSEに設定し、すべて正常に戻った.
セッションを使用する必要がある場合は、PHP固有の関数を使用します.
session_start();
//...
session_commit(); // session_write_close()
TP :
session('[start]');
//...
session('[pause]');
参照先:
http://www.infoq.com/cn/news/2015/01/php-session-concurrency-problems
http://www.phpddt.com/php/php-session-problem.html
http://www.blhere.com/984.html
転入先:PHPセッションで同時発生の問題が発生する可能性がある