ホームページ > バックエンド開発 > PHPチュートリアル > PHPセッションリサイクルメカニズム

PHPセッションリサイクルメカニズム

巴扎黑
リリース: 2016-11-22 16:22:00
オリジナル
981 人が閲覧しました

PHP の動作メカニズムにより、セッション情報を定期的にスキャンして、セッション情報が無効かどうかを判断するデーモン スレッドがありません。有効なリクエストが発生すると、PHP はグローバル変数 session.gc_probability/session.gc_divisor (php.ini または ini_set() 関数を通じて変更することもできます) の値に基づいて GC (ガベージ コレクター) を開始するかどうかを決定します。 。デフォルトでは、session.gc_probability = 1、session.gc_divisor = 100 です。これは、GC が開始される確率が 1% であることを意味します。

GC の仕事は、すべてのセッション情報をスキャンし、現在の時刻からセッションの最終変更時刻 (変更日) を減算し、それを session.gc_maxlifetime パラメーターと比較することです。生存時間が gc_maxlifetime を超えている場合は、セッション。

では、なぜ gc_maxlifetime が無効になるのでしょうか?

デフォルトでは、セッション情報はシステムの一時ファイルディレクトリにテキストファイルの形式で保存されます。 Linux では、このパスは通常 tmp であり、Windows では通常 C:WindowsTemp です。サーバー上に複数の PHP アプリケーションがある場合、それらのセッション ファイルは同じディレクトリに保存されます。同様に、これらの PHP アプリケーションも一定の確率で GC を開始し、すべてのセッション ファイルをスキャンします。

問題は、GC が動作しているときに、異なるサイト上のセッションが区別されないことです。たとえば、サイト A の gc_maxlifetime は 2 時間に設定され、サイト B の gc_maxlifetime はデフォルトの 24 分に設定されます。サイト B の GC が開始されると、パブリック一時ファイル ディレクトリがスキャンされ、サイト A からのものかサイト B からのものかに関係なく、24 分より古いすべてのセッション ファイルが削除されます。このように、サイト A の gc_maxlifetime 設定は役に立ちません。

問題を見つけたら、解決するのは簡単です。 session.save_path パラメータを変更するか、session_save_path() 関数を使用して、セッションが保存されるディレクトリを専用のディレクトリに指定します。 gc_maxlifetime パラメータは正常に機能します。

もう 1 つの問題は、gc_maxlifetime が保証できるのはセッションの存続時間の最短時間だけであり、この時間を過ぎるとセッション情報はすぐに削除されることです。 GC は確率に基づいて開始され、長期間開始されない可能性があるため、gc_maxlifetime を超えた後も多数のセッションが有効になります。この問題を解決する 1 つの方法は、session.gc_probability/session.gc_divisor の確率を高めることです。これを 100% に引き上げると、この問題は完全に解決されますが、パフォーマンスに重大な影響を与えることは明らかです。もう 1 つの方法は、コード内で現在のセッションの存続期間を確認し、それが gc_maxlifetime を超えた場合は、現在のセッションをクリアすることです。

phpセッションのGC関数はガベージコレクターです。この GC が開始されると、「タイムアウト」になったセッションがクリアされます。次のように動作します:

ユーザーが Web サイトにアクセスしてログインすると、バックグラウンドで session_start が呼び出され、セッションの生成が試行されます (すでにセッションがある場合、それは有効なセッション リクエストと同等です)

このリクエストのような有効なセッションごとに、Apache の PHP モジュールはセッション関連のグローバル変数 gc_probability/gc_divisor => に基づいて GC を開始する確率を計算し、この確率を使用してこのリクエストで GC を開始するかどうかを決定します。たとえば、session.gc_probability のデフォルト値が 1、session.gc_divisor のデフォルト値が 100 の場合、「ガベージ コレクション」が開始される確率は 1% になります。これは、100 リクエストごとに、ガベージ コレクションが開始されることを意味します。期限切れのセッションをクリーンアップすることが可能です

GC が開始されると、GC は現在のセッションのパス (session.save_path) にあるすべてのセッション ファイルをスキャンし、別のグローバル変数 session.gc_maxlifetime ("current 「time」と「セッションファイルのatimeまたはmtime」の差がgc_maxlifetime:expiredより大きい場合)、期限切れのセッションを削除してください

セッション開始後、長時間対話操作がなかった場合(例えば、 、ノンストップコーディングワード、送信されていない、または下書きとして保存されていない場合)、バックグラウンドで保存されたセッションファイルは、gc_maxlifetime(デフォルト値 1440 秒 = 24 分)後に変更またはアクセスされる機会がなくなり、無効になる可能性があります。 . クリアされた後、この後再度送信するとセッションが切れているためエラーが報告されます

gc_maxlifetime が 24 分に設定されていることがわかりますが、これはいくつかの記事を書くのに十分ではありません。これは、Linux では session.save_path のデフォルトのパスが /tmp であるため、この設定を変更するプログラムはほとんどありません。このサーバー上に複数の仮想ホストがある場合、異なる session_name を持つ多数のセッション ファイルが /tmp ディレクトリに保存されます。問題なのは、PHP の GC がセッションの所有権を区別しないことです。取得した gc_maxlifetime に基づいて、このディレクトリ内の期限切れのセッション ファイルがすべてクリーンアップされます。

上記の分析によると、解決策は次のとおりです: UTBLOG は .htaccess ファイルにステートメントを追加し、session.gc_maxlifetime のローカル値を 14400 (4 時間) に拡張し、バックグラウンドで session.save_path を /tmp/utblog に設定します。 . このようにすれば、utblog のセッション ファイルは他の Web サイトから干渉されることはありませんし、有効期限も 4 時間あれば十分だと思います。

テストした後、すべてが期待どおりでした。

また、/etc/php.iniを直接変更することももちろん可能です。 php.ini または Apache の conf ファイルを変更する権限がなく、.htaccess が禁止されている場合は、plog の sessionmanager.class.php ファイルを直接変更し、session_start 行の前に ini_alter("session.gc_maxlifetime", 14400) を追加します。 。 できる。 plog 構造は適切で、この部分のみが session_start を呼び出すため、この部分のみを変更する必要があります。ローカルでテストしましたが、うまくいきました。

------------------------------------------------ ------------------------

session.gc_probability integer

session.gc_probability と session.gc_divisor は、gc (ガベージ コレクション) を管理するために一緒に使用されます。ガベージコレクション) プロセスの起動確率。デフォルトは 1 です。詳細については、session.gc_divisor を参照してください。

session.gc_divisor integer

session.gc_divisor と session.gc_probability は一緒に、各セッションの初期化時に gc (ガベージ コレクション ガベージ コレクション) プロセスを開始する確率を定義します。この確率は、gc_probability/gc_divisor を使用して計算されます。たとえば、1/100 は、各リクエストで gc プロセスが開始される確率が 1% であることを意味します。 session.gc_divisor のデフォルトは 100 です。

session.gc_maxlifetime integer

session.gc_maxlifetime は、データが「ゴミ」と見なされ消去されるまでの秒数を指定します。

注:

異なるスクリプトの session.gc_maxlifetime 値が異なるが、セッション データを保存する場所が同じである場合、値が最も小さいスクリプトがデータをクリーンアップします。この場合、このディレクティブを session.save_path と一緒に使用します。

注: デフォルトのファイルベースのセッションハンドラーを使用する場合、ファイルシステムはアクセス時間 (atime) を追跡する必要があります。 Windows FAT ファイル システムは機能しないため、FAT ファイル システムまたは時刻を追跡できない別のファイル システムを使用する必要がある場合は、セッション データのガベージ コレクションを処理する別の方法を見つける必要があります。 PHP 4.2.3 以降、atime の代わりに mtime (変更時間) が使用されます。したがって、時刻を追跡できないファイル システムについては問題ありません。


関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート