ホームページ >バックエンド開発 >PHPチュートリアル >PHP セッションのロックと同時実行性、phpsession_PHP チュートリアル

PHP セッションのロックと同時実行性、phpsession_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-12 09:00:11787ブラウズ

PHP セッションのロックと同時実行性、phpsession

この記事では、PHP セッションの使用中のロックと同時実行性の問題について説明します。関連する現象には、リクエストのブロック、セッション データの損失、セッション データの読み取り不可などがあります。

ログインできません
ある日、バグを解決するためにバックエンド システムの 1 つにログインしようとしました。アカ​​ウントとパスワードの確認コードを正確に入力したにもかかわらず、ログインできませんでした。多くの実験の結果、主に 2 つの原因があることがわかりました。エラーメッセージ:

  • csrf検証に失敗しました
  • 確認コードが間違っています[コードの神様に誓いますが、表示された確認コードを半角で入力し、同じ順序で余分な文字を入れずに入力しました]

私たちのシステム
私たちのシステムは falcon 2.0.8 に基づいて開発されており、フォームフィールドに CSRF 攻撃を防ぐためのフィールドが追加されています。キャプチャも有効になっています。

リーリー

最初にこれら 2 つのコンポーネントを確認したところ、どちらもセッションにデータを保存していることがわかりました。 リーリー

その後、セッションの実装を確認したところ、データが Redis に保存されていることがわかりました。

見て見て
ログインできない問題は何ですか?データの検証に問題があるため、テスト環境の redis マシンにログインし、redis-cli モニターを実行して、ログイン プロセスを実行したところ、出力は次のようになりました。 ):

  • セッションIDを取得する
  • セッションIDを取得する
  • SETEX セッション ID 3600 csrf=xxxx
  • SETEX セッション ID 3600 captcha=abcd
次のことがわかります:

1. ここには 2 つのリクエストがあります。1 つはフォームのロードで、もう 1 つは検証コードの生成です。

2. 「同時実行」状況が存在します。これらの 2 つのリクエストは、フォームがロードされて表示された後に検証コードを要求する必要があります。つまり、セッション シーケンスは get->set->get->set である必要があります。同時リクエストのようです?
3. 後者の SETEX には csrf コンテンツがありません。つまり、以前のデータが上書きされます
世界全体が良いことではありませんが、何が問題なのか少しは理解できました。何が問題なのでしょうか? PHP のセッション データ アクセスから始まる長い話です。

PHPセッションデータへのアクセス
セッションデータは文字列にエンコードされ、ストレージ[ファイル、データベース、redis、memcacheなど]に保存されます。セッションを使用するとき、いつストレージからデータを取得しますか?データはいつメモリに書き込まれますか?

この質問に対する答えは、一部の友人が考えているものとは異なる可能性があります。リクエストでは、PHP は session_start 中に一度だけメモリを読み取り、その後はリクエストの終了時に一度だけメモリに書き込みます。 session_write_close を呼び出すと、データがメモリにフラッシュされてセッションが閉じられます。

そして次の質問が来ます:

1. セッション内に同時に 2 つの読み取りおよび書き込みセッション リクエストがある場合、get 1-write 1-get 2-write 2 の保証はなく、cas バージョン管理メカニズムがないため、これらの同時リクエストは相手が書き込まないと、最後の書き込みによって、前のリクエストによって書き込まれたセッションが上書きされます。

2. ログイン ページのフォームや確認コードなど、リクエストがシリアルである場合、前のリクエストでコンテンツがすでに出力されているものの、セッションがまだ書き込まれておらず、後続のリクエストが開始されている可能性があります。

ロックまたはロック解除 このようなリソースの同時実行性の解決は、通常、ロックまたはバージョン管理を通じて処理されます。しかし、バージョン管理を行う良い方法がわかりません。ロックについて話しましょう。

実際、ロックはあまり適しておらず、デメリットもあります。

PHP のセッションはデフォルトでファイルに保存され、セッションが開かれると、そのファイルに排他的ロックが追加され、他のリクエストはロックを取得できなくなり、前のロックが解放されるまで待つことができます。

これにより、読み取り-書き込み、読み取り-書き込みの順序が保証されます。

mysql などの他のストレージは、select for update を使用して行ロックを実行できます。 Redis は、自動インクリメント キーを介して実装でき、1 を返してロックを取得するなどします。

この実装はデータ フローには理想的ですが、Ajax がページで広く使用されている現在の状況では、すべてのリクエストが処理のためにキューに入れられるため、ページ表示の時間が大幅に増加し、リクエストなどの利用不能エラーが発生することもあります。タイムアウト。

解決策はありません
セッションを過度に使用することはお勧めできません。そのリードワンスライトワンスメカニズムによって引き起こされる問題は、落とし穴を引き起こす可能性があります。
テンプレートをレンダリングする前、または出力をリクエストする前に session_write_close を呼び出します

リーリー リーリー

上記は php セッションのロックと同時実行性についてです。皆さんの学習に役立つことを願っています。

興味がありそうな記事:

  • 複数のセッションを同時に実行するための複数の PHP サーバー
  • PHP セッションのデッドロックを解決する方法
  • PHP でのセッション変数の破棄
  • PHP エラー 警告: SESSION_START() [FUNCTION.SESSION- START]解決策
  • ThinkPHP テンプレートでセッションデータを呼び出す方法
  • PHP でセッションの有効期限を正確に設定する方法
  • ThinkPHP でのセッションの使用方法の詳細な説明
  • PHP セッションファイルの排他ロックによるブロック問題の解決方法
  • PHPセッションは同時実行の問題を引き起こす可能性があります
  • セッションを簡単に分析すると、PHP で同時実行の問題が発生する可能性があります

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/1094746.html技術記事 PHP セッションのロックと同時実行性、phpsession この記事では、使用中の PHP セッションのロックと同時実行性の問題について説明します。関連する現象には、リクエストのブロック、セッション データの損失、セッション データなどがあります。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。