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

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

Jul 12, 2016 am 08:59 AM
session

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 までご連絡ください。

ホット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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SpringBootセッションでセッションタイムアウトを設定する方法 SpringBootセッションでセッションタイムアウトを設定する方法 May 15, 2023 pm 02:37 PM

Springboot プロジェクトの本番環境のセッションアウト タイムアウトで問題が見つかりました。問題の説明は次のとおりです: テスト環境では、application.yaml を変更することでセッションアウトが構成されていました。別の時間を設定してセッションアウト構成を確認した後、有効期限がリリース時に直接 8 時間に設定され、運用環境に到着しました。しかし、正午にお客様から、プロジェクトの有効期限が短く設定されており、30分操作がないとセッションが期限切れになり、再度ログインが必要になるというフィードバックをいただきました。開発環境の扱いの問題を解決します。springboot プロジェクトには Tomcat が組み込まれているため、プロジェクト内の application.yaml で設定されたセッションアウトが有効になります。本番環境: 本番環境リリースは

更新後にPHPセッションが消えた場合はどうすればよいですか? 更新後にPHPセッションが消えた場合はどうすればよいですか? Jan 18, 2023 pm 01:39 PM

更新後に PHP セッションが消える問題の解決策: 1. 「session_start();」を通じてセッションを開きます; 2. すべてのパブリック設定を PHP ファイルに書き込みます; 3. 変数名は配列の添字と同じにすることはできません。 4. phpinfoでセッションデータの保存パスを確認し、ファイルディレクトリ内のsessioが正常に保存されているか確認してください。

セッション失敗を解決する方法 セッション失敗を解決する方法 Oct 18, 2023 pm 05:19 PM

セッション障害は通常、セッションの有効期間の期限切れまたはサーバーのシャットダウンによって発生します。解決策: 1. セッションの有効期間を延長する; 2. 永続ストレージを使用する; 3. Cookie を使用する; 4. セッションを非同期的に更新する; 5. セッション管理ミドルウェアを使用する。

セッションphpのデフォルトの有効期限は何時間ですか? セッションphpのデフォルトの有効期限は何時間ですか? Nov 01, 2022 am 09:14 AM

セッション PHP のデフォルトの有効期限は 1440 秒、つまり 24 分です。つまり、クライアントが 24 分を超えて更新されない場合、現在のセッションは期限切れになります。ユーザーがブラウザを閉じると、セッションは終了し、セッションは存在しなくなります。

PHP セッションのクロスドメイン問題の解決策 PHP セッションのクロスドメイン問題の解決策 Oct 12, 2023 pm 03:00 PM

PHPSession のクロスドメイン問題の解決策 フロントエンドとバックエンドの分離の開発では、クロスドメイン要求が標準になっています。クロスドメインの問題に対処するときは、通常、セッションの使用と管理が必要になります。ただし、ブラウザーのオリジンポリシーの制限により、デフォルトではセッションをドメイン間で共有できません。この問題を解決するには、いくつかの技術と方法を使用して、セッションのクロスドメイン共有を実現する必要があります。 1. ドメイン間でセッションを共有するための Cookie の最も一般的な使用法

Springboot2のセッションタイムアウト設定が無効になる問題の解決方法 Springboot2のセッションタイムアウト設定が無効になる問題の解決方法 May 22, 2023 pm 01:49 PM

問題: 今日、プロジェクトで設定タイムアウトの問題が発生し、SpringBoot2 の application.properties への変更が反映されませんでした。解決策:server.* プロパティは、SpringBoot によって使用される埋め込みコンテナーを制御するために使用されます。 SpringBoot は、ServletWebServerFactory インスタンスの 1 つを使用してサーブレット コンテナのインスタンスを作成します。これらのクラスは、server.* プロパティを使用して、制御されるサーブレット コンテナ (tomcat、jetty など) を構成します。アプリケーションが war ファイルとして Tomcat インスタンスにデプロイされる場合、server.* プロパティは適用されません。それらは当てはまりませんが、

Redis 共有セッション アプリケーションに SMS ログインを実装する方法 Redis 共有セッション アプリケーションに SMS ログインを実装する方法 Jun 03, 2023 pm 03:11 PM

1. セッションに基づく SMS ログインの実装 1.1 SMS ログインのフローチャート 1.2 SMS 検証コード送信の実装 フロントエンド リクエストの説明: リクエスト メソッドの説明 POST リクエスト パス /user/code リクエスト パラメータ 電話 (電話番号) 戻り値 バックエンド インターフェイスなし実装: @Slf4j@ ServicepublicclassUserServiceImplextendsServiceImplimplementsIUserService{@OverridepublicResultsendCode(Stringphone,HttpSessionsession){//1。次の場合は携帯電話番号を確認します。

JavaScript Cookie と PHP Cookie の違いは何ですか? JavaScript Cookie と PHP Cookie の違いは何ですか? Sep 02, 2023 pm 12:29 PM

JavaScriptCookies JavaScript Cookie の使用は、設定、購入、手数料、その他の情報を記憶および追跡する最も効果的な方法です。訪問者のエクスペリエンスを向上させるために必要な情報やウェブサイトの統計。 PHPCookieCookie は、クライアント コンピューターに保存され、追跡目的で保持されるテキスト ファイルです。 PHP は HTTP Cookie を透過的にサポートします。 JavaScript Cookie はどのように機能しますか?サーバーは、訪問者のブラウザに Cookie の形式でデータを送信します。ブラウザは Cookie を受け入れることができます。存在する場合、それは訪問者のハードドライブにプレーンテキストレコードとして保存されます。さて、訪問者がサイト上の別のページに到達すると、

See all articles