検索
ホームページバックエンド開発PHPチュートリアルredis/分散ファイル ストレージ システム/データベースはセッションを保存し、ロード バランシング クラスターでのセッションの不整合の問題を解決します。redissession_PHP チュートリアル

redis/分散ファイルストレージシステム/データベースはセッションを保存し、負荷分散クラスターでのセッションの不整合の問題を解決します

まず、セッションとCookieの類似点と相違点について話しましょう

セッションと Cookie は、一方がサーバー側に保存され、もう一方がクライアント側に保存されるというような一般的なものではありません

セッションはサーバー側に保存されますが、ブラウザーのセッションが常に同じである理由を想像してみてください (有効期限や終了はカウントされません)。 「PHPSESSID」という名前のブラウザ側のクックです。「PHPSESSID」クッキーには文字列が含まれています。この文字列はセッションをマークするために使用され、サーバーはこの Cookie を見つけると、サーバー側のセッション ファイル ストレージ ディレクトリに移動して「sess_PHPSESSID value」という名前のファイルを検索します (存在しない場合は作成します)。このファイル内には、保存されたセッション データ (シリアル化されたデータ) が含まれています

そのため、このファイルを削除しても、次回セッションを使用するときに同じ名前のファイルが再作成されます。もちろん、Cookieを削除した場合は、名前を変更する必要があります。

セッションはデフォルトで各サーバーのローカルディレクトリに保存され、対応する設定が「php.ini」にあります

サーバー側の設定:

session.save_handler = files (デフォルトは file で、セッションをサーバーに保存する方法を定義します。ファイルとは、セッションを一時ファイルに保存することを意味します。データベースなどの他の保存方法をカスタマイズしたい場合は、 「ユーザー」に設定する必要があります)

session.save_path = "D:/wamp/php/sessiondata/" (サーバーがセッションを保存する一時ファイルの場所を定義します)

session.auto_start = 0 (1に設定すると、各ファイルに session_start() を記述する必要がなく、セッションが自動的に開始されます:)

session.gc_probability = 1


session.gc_divisor = 100

session.gc_maxlifetime = 1440 (上記の 3 つはセッションの自動ガベージ コレクション メカニズムを構成し、session.gc_probability と session.gc_divisor はセッション クリーンアップを実行する確率を構成します。理論上説明 サーバーは定期的に gc 関数を呼び出して、一定の確率でセッションをクリーンアップします。 クリーンアップの確率は次のとおりです。 たとえば、1/100 は、新しいセッションが初期化されるたびに、1% の確率でセッションがクリーンアップされることを意味します。ガベージコレクションメカニズムによってリサイクルされます。クリーニングの基準は、session.gc_maxlifetime)
で定義された時間です。

クライアント関連の設定もいくつかあります

session.use_cookies = 1 (クライアント上のセッション ID の保存方法。1 を設定すると、Cookie を使用してクライアントのセッション ID を記録します。同時に、クッキー $_COOKIE['PHPSESSIONID'] が $_COOKIE 変数に存在します。

session.use_only_cookies = 1 (クライアント上のセッション ID によって使用される保存方法も定義します。1 を設定すると、セッション ID の保存に Cookie のみを使用することを意味します)

session.use_trans_sid = 0 (上記の設定に対応します。ここで 1 に設定すると、セッション ID が url パラメーターを介して渡されることが許可されることを意味します。同様に、0 に設定することをお勧めします。そのため、ここにいくつかのインタビューがありますCookie を無効にしてもセッションを使用できるかどうかを修正するための質問です。答えは、もちろん、値を 1) に設定するだけです。

session.referer_check = (この設定は session.use_trans_sid = 1 の場合にのみ有効です。目的は、HTTP ヘッダーの「Referer」をチェックして、URL に含まれるセッション ID が有効かどうかを判断することです。HTTP_REFERER には次の文字が含まれている必要がありますこのパラメータで指定されている場合、URL 内のセッション ID は無効とみなされ、通常はデフォルトで空、つまりチェックされません)

session.name = PHPSESSID (sessionid の名前、つまり変数名を定義します。つまり、ブラウザ http ツールから見える http ヘッダー ファイル内の PHPSESSID = ##############)

session.cookie_lifetime = 0 (セッション ID を保存する Cookie ファイルのライフサイクル。0 に設定すると、セッションが終了し、セッション ID は自動的に消えます。ブラウザを強制的に閉じると、最後のセッション ID が失われます。失われた)



上記のことから、デフォルトではセッションは各サーバーにローカルに保存されることがわかります。そのため、クラスター環境でセッションを使用したい場合、デフォルトの構成を使用すると問題が発生します。つまり、クライアントはサーバー A のセッション ファイルにアクセスしたところです。セッション ファイルは A に存在しますが、後で顧客 B サーバーに割り当てられる可能性があります。この時点では、ファイルは B サーバーに存在せず、データは失われます。

以上です。問題の解決策は、データベース、Redis、またはファイル サーバーのいずれかにセッションを別のサーバーに保存することです

ここで作者が設定方法を一つ一つ解説しています

1. Redis を使用してセッションを保存します

この著者は最も単純なものについてのみ説明します。多くの人が使用しているものを使用する代わりに、それを保存する方法を規定する PHP クラスを作成する必要があります (もちろん、特別なニーズがある場合はこれを行うこともできます)。

まずphp.ini設定を変更します

リーリー

もちろん、phpプログラムで設定することもできます

リーリー

Redis でパスワードが設定されている場合は、次のように設定できます

リーリー

2. ファイルサーバーを使用してセッションを保存します

这个笔者觉得比较简单,笔者公司里面直接把分布式文件服务器挂载到指定目录下,然后访问分布式文件服务器就像访问本地文件夹一样,这里只需要设置下 保存路径即可

session.save_path = <span>"</span><span>xxxx</span><span>"</span>

 

三、使用数据库存放session

这个略显复杂,要写个PHP类,指定如何打开、读取、写入、销毁、GC垃圾回收、关闭,不过笔者不懒还是手动写一个意思意思

<?<span>php 
</span><span>class</span><span> sessionHandler{
    </span><span>/*</span><span>*
    * session 存放的库
    </span><span>*/</span>
    <span>const</span> SESSION_DB = 'mytest'<span>;

    </span><span>/*</span><span>*
    * session 存放的表
    </span><span>*/</span>
    <span>const</span> SESSION_TABLE = 'session'<span>;

    </span><span>/*</span><span>*
    * @var string $_dbHandler 数据库链接句柄
    </span><span>*/</span>
    <span>private</span> <span>$_dbHandler</span><span>;

    </span><span>/*</span><span>*
    * @var string $_dbHost 数据库主机
    </span><span>*/</span>
    <span>private</span> <span>$_dbHost</span><span>;

    </span><span>/*</span><span>*
    * @var string $_dbUser 数据库用户名
    </span><span>*/</span>
    <span>private</span> <span>$_dbUser</span><span>;

    </span><span>/*</span><span>*
    * @var string $_dbUser 数据库密码
    </span><span>*/</span>
    <span>private</span> <span>$_dbPasswd</span><span>;

    </span><span>/*</span><span>*
    * @var string $_name session 名称
    </span><span>*/</span>
    <span>private</span> <span>$_name</span><span>;

    </span><span>/*</span><span>*
    * 构造函数
    * @param string $dbHost 数据库主机
    * @param string $dbUser 数据库用户名
    * @param string $dbPasswd 数据库密码
    * @return void
    </span><span>*/</span>
    <span>public</span> <span>function</span> __construct(<span>$dbHost</span>, <span>$dbUser</span>, <span>$dbPasswd</span><span>)
    {
        </span><span>$this</span>->_dbHost = <span>$dbHost</span><span>;
        </span><span>$this</span>->_dbUser = <span>$dbUser</span><span>;
        </span><span>$this</span>->_dbPasswd = <span>$dbPasswd</span><span>;
    }

    </span><span>/*</span><span>*
    * 链接数据库
    * @param string $savePath 存储路径
    * @param string $name 名称
    * @return boolean
    </span><span>*/</span>
    <span>public</span> <span>function</span> open(<span>$savePath</span>, <span>$name</span><span>)
    {
        </span><span>$this</span>->_dbHandler = <span>mysql_connect</span>(<span>$this</span>->_dbHost, <span>$this</span>->_dbUser, <span>$this</span>-><span>_dbPasswd);
        </span><span>if</span>(!<span>$this</span>-><span>_dbHandler)
        {
            </span><span>return</span> <span>false</span><span>;
        }
        </span><span>$this</span>->_name = <span>$name</span><span>;
        </span><span>mysql_select_db</span>(self::SESSION_DB, <span>$this</span>-><span>_dbHandler);
        </span><span>return</span> <span>true</span><span>;
    }

    </span><span>/*</span><span>*
    * 读session
    * @param string $sessionId session id
    * @return mixd 存在返回数组  否则返回空
    </span><span>*/</span>
    <span>public</span> <span>function</span> read(<span>$sessionId</span><span>)
    {
        </span><span>$data</span> = ''<span>;
        </span><span>$sql</span> = <span>sprintf</span>('SELECT `data` FROM ' . self::SESSION_TABLE . ' WHERE `id`="%s"', <span>$sessionId</span><span>);
        </span><span>$result</span> = <span>mysql_query</span>(<span>$sql</span>, <span>$this</span>-><span>_dbHandler);
        </span><span>if</span>(<span>mysql_num_rows</span>(<span>$result</span>) == 1<span>)
        {
            </span><span>list</span>(<span>$data</span>) = <span>mysql_fetch_array</span>(<span>$result</span>,<span> MYSQL_NUM);
        }
        </span><span>return</span> <span>$data</span><span>;
    }

    </span><span>/*</span><span>*
    * 链接数据库
    * @param string $sessionId session id
    * @param string $data 数据
    * @return boolean
    </span><span>*/</span>
    <span>public</span> <span>function</span> write(<span>$sessionId</span>, <span>$data</span><span>)
    {
        </span><span>$sql</span> = <span>sprintf</span><span>(
                </span>'<span>REPLACE INTO 
                </span>' . self::SESSION_TABLE . '<span> (`id`, `data`, `last_time`) 
                VALUES 
                ("%s", "%s", %d)</span>', 
                <span>$sessionId</span>,     
                <span>mysql_escape_string</span>(<span>$data</span>),  
                <span>time</span><span>()
                );
        </span><span>mysql_query</span>(<span>$sql</span>, <span>$this</span>-><span>_dbHandler);
        </span><span>return</span> <span>mysql_affected_rows</span>(<span>$this</span>->_dbHandler) > 0<span>;
    }

    </span><span>/*</span><span>*
    * 链接数据库
    * @param int $expire 生存周期
    * @return boolean
    </span><span>*/</span>
    <span>public</span> <span>function</span> gc(<span>$expire</span><span>)
    {
        </span><span>$sql</span> = <span>sprintf</span><span>(
                        </span>'DELETE FROM `' . self::SESSION_TABLE . '<span>`
                        WHERE 
                        `last_time` < NOW() - %d</span>',
                        <span>$expire</span><span>
                    );
        </span><span>mysql_query</span>(<span>$sql</span>, <span>$this</span>-><span>_dbHandler);
        </span><span>return</span> <span>mysql_affected_rows</span>(<span>$this</span>->_dbHandler) > 0<span>;
    }

    </span><span>/*</span><span>*
    * 关闭数据库链接
    * @param void
    * @return boolean
    </span><span>*/</span>
    <span>public</span> <span>function</span><span> close()
    {
        </span><span>return</span> <span>mysql_close</span>(<span>$this</span>-><span>_dbHandler);
    }

    </span><span>/*</span><span>*
    * 销毁session
    * @param string $sessionId
    * @return boolean
    </span><span>*/</span>
    <span>public</span> <span>function</span> destroy(<span>$sessionId</span><span>)
    {
        </span><span>$sql</span> = <span>sprintf</span>('DELETE FROM `' . self::SESSION_TABLE . '` WHERE `id`="%s"', <span>$sessionId</span><span>);
        </span><span>mysql_query</span>(<span>$sql</span>, <span>$this</span>-><span>_dbHandler);
        </span><span>$_SESSION</span> = <span>array</span><span>();
        </span><span>return</span> <span>mysql_affected_rows</span>(<span>$this</span>->_dbHandler) > 0<span>;
    }
}


</span><span>$sessionHandler</span> = <span>new</span> sessionHandler('localhost', 'root', '123abc+'<span>);
</span><span>session_set_save_handler</span><span>(
                            </span><span>array</span>(<span>$sessionHandler</span>, 'open'),
                            <span>array</span>(<span>$sessionHandler</span>, 'close'),
                            <span>array</span>(<span>$sessionHandler</span>, 'read'),
                            <span>array</span>(<span>$sessionHandler</span>, 'write'),
                            <span>array</span>(<span>$sessionHandler</span>, 'destroy'),
                            <span>array</span>(<span>$sessionHandler</span>, 'gc'<span>)
                        );


</span><span>/*</span><span>
    在 PHP 5.0.5 中,在对象销毁之后才会调用 write 和 close 回调函数, 所以,在这两个回调函数中不可以使用对象,也不可以抛出异常。 
    如果在函数中抛出异常,PHP 既不会捕获它,也不会跟踪它, 这样会导致程序异常终止。 
    但是对象析构函数可以使用会话。
    可以在析构函数中调用 session_write_close() 函数来解决这个问题。 
    但是注册 shutdown 回调函数才是更加可靠的做法
</span><span>*/</span>
<span>register_shutdown_function</span>('session_write_close'<span>);

</span><span>session_start</span><span>();
</span><span>$_SESSION</span>['test'] = 'aa';

然后了建立一个表 叫 session  ,记住先建立数据库'mytest'奥  session表中有三个字段

id   vchar(100)  primary  sessionid的主键

data vchar(1000) 数据内容(序列化后的)

last_time int(10)  最后修改的时间戳

 

整完了运行下发现表里面的内容

大家可以看得出,通过代码自定义session的这种方式不仅可以应用到数据库上,也可以使用其他的,如文件、redis之类

 

 

至此,session的原理,如何自定义存放session,在集群中如何使用session,就已经完了

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1100144.htmlTechArticleredis/分布式文件存储系统/数据库 存储session,解决负载均衡集群中session不一致问题,redissession 先来说下session和cookie的异同 session和cookie不...
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPの現在のステータス:Web開発動向を見てくださいPHPの現在のステータス:Web開発動向を見てくださいApr 13, 2025 am 12:20 AM

PHPは、現代のWeb開発、特にコンテンツ管理とeコマースプラットフォームで依然として重要です。 1)PHPには、LaravelやSymfonyなどの豊富なエコシステムと強力なフレームワークサポートがあります。 2)パフォーマンスの最適化は、Opcacheとnginxを通じて達成できます。 3)PHP8.0は、パフォーマンスを改善するためにJITコンパイラを導入します。 4)クラウドネイティブアプリケーションは、DockerおよびKubernetesを介して展開され、柔軟性とスケーラビリティを向上させます。

PHP対その他の言語:比較PHP対その他の言語:比較Apr 13, 2025 am 12:19 AM

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 Pythonと比較して、PHPはWeb開発においてより多くの利点がありますが、データサイエンスの分野ではPythonほど良くありません。 Javaと比較して、PHPはエンタープライズレベルのアプリケーションでより悪化しますが、Web開発により柔軟性があります。 JavaScriptと比較して、PHPはバックエンド開発により簡潔ですが、フロントエンド開発のJavaScriptほど良くありません。

PHP対Python:コア機能と機能PHP対Python:コア機能と機能Apr 13, 2025 am 12:16 AM

PHPとPythonにはそれぞれ独自の利点があり、さまざまなシナリオに適しています。 1.PHPはWeb開発に適しており、組み込みのWebサーバーとRich Functionライブラリを提供します。 2。Pythonは、簡潔な構文と強力な標準ライブラリを備えたデータサイエンスと機械学習に適しています。選択するときは、プロジェクトの要件に基づいて決定する必要があります。

PHP:Web開発の重要な言語PHP:Web開発の重要な言語Apr 13, 2025 am 12:08 AM

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

PHP:多くのウェブサイトの基礎PHP:多くのウェブサイトの基礎Apr 13, 2025 am 12:07 AM

PHPが多くのWebサイトよりも優先テクノロジースタックである理由には、その使いやすさ、強力なコミュニティサポート、広範な使用が含まれます。 1)初心者に適した学習と使用が簡単です。 2)巨大な開発者コミュニティと豊富なリソースを持っています。 3)WordPress、Drupal、その他のプラットフォームで広く使用されています。 4)Webサーバーとしっかりと統合して、開発の展開を簡素化します。

誇大広告を超えて:今日のPHPの役割の評価誇大広告を超えて:今日のPHPの役割の評価Apr 12, 2025 am 12:17 AM

PHPは、特にWeb開発の分野で、最新のプログラミングで強力で広く使用されているツールのままです。 1)PHPは使いやすく、データベースとシームレスに統合されており、多くの開発者にとって最初の選択肢です。 2)動的コンテンツ生成とオブジェクト指向プログラミングをサポートし、Webサイトを迅速に作成および保守するのに適しています。 3)PHPのパフォーマンスは、データベースクエリをキャッシュおよび最適化することで改善でき、その広範なコミュニティと豊富なエコシステムにより、今日のテクノロジースタックでは依然として重要になります。

PHPの弱い参照は何ですか、そしていつ有用ですか?PHPの弱い参照は何ですか、そしていつ有用ですか?Apr 12, 2025 am 12:13 AM

PHPでは、弱い参照クラスを通じて弱い参照が実装され、ガベージコレクターがオブジェクトの回収を妨げません。弱い参照は、キャッシュシステムやイベントリスナーなどのシナリオに適しています。オブジェクトの生存を保証することはできず、ごみ収集が遅れる可能性があることに注意する必要があります。

PHPで__invoke Magicメソッドを説明してください。PHPで__invoke Magicメソッドを説明してください。Apr 12, 2025 am 12:07 AM

\ _ \ _ Invokeメソッドを使用すると、オブジェクトを関数のように呼び出すことができます。 1。オブジェクトを呼び出すことができるように\ _ \ _呼び出しメソッドを定義します。 2。$ obj(...)構文を使用すると、PHPは\ _ \ _ Invokeメソッドを実行します。 3。ロギングや計算機、コードの柔軟性の向上、読みやすさなどのシナリオに適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター