ホームページ > バックエンド開発 > PHPチュートリアル > PHP は異なるサーバー上で SESSION 操作を共有します_PHP チュートリアル

PHP は異なるサーバー上で SESSION 操作を共有します_PHP チュートリアル

WBOY
リリース: 2016-07-13 17:52:58
オリジナル
815 人が閲覧しました

1. 問題の原因 7 O8 X8 R7 o& Z) Y# i3 O
やや大きな Web サイトでは通常、複数のサーバーがあり、各サーバーは異なる機能を持つモジュールを実行し、異なる第 2 レベルのドメイン名を使用します。総合的な Web サイトでは、ユーザー システム、つまりユーザー名のセットが統一されています。 Web サイト全体のすべてのモジュールにログインします。サーバー間でのユーザー データの共有は、バックエンドにデータベース サーバーを配置するだけで比較的簡単に実装でき、各サーバーは統一されたインターフェイスを通じてユーザー データにアクセスできます。しかし、まだ問題があります。つまり、ユーザーがこのサーバーにログインした後、別のサーバーの他のモジュールに入るときに、再度ログインする必要があります。これは 1 回限りのログインであり、一般的な問題はすべて にマッピングされています。実際には、さまざまなサーバー間で SESSION データを共有する方法です。 ! n) o+ ~2 R# T8 P$ @ R% PC
/ S" G* k: }5 j' R( {7 v5 {

2. PHP セッションの仕組み # Z3 ?; .C) Z, n# ]9 ^- K9 B8 }- G
; 問題を解決する前に、まず PHP SESSION がどのように機能するかを理解しましょう。クライアント (ブラウザなど) が Web サイトにログインすると、訪問した PHP ページは session_start() を使用して SESSION を開くことができ、これによりクライアントの一意の識別 SESSION ID が生成されます (この ID は関数 session_id( ))。 SESSION ID は 2 つの方法でクライアントに保持できるため、PHP プログラムは別のページをリクエストするときにクライアントの SESSION ID を学習できます。1 つは、デフォルトで GET URL または POST フォームに SESSION ID を自動的に追加することです。最初の方法では、変数名は PHPSESSID ですが、もう 1 つの方法では、COOKIE を通じてセッション ID を保存します。デフォルトでは、この COOKIE の名前は PHPSESSID です。ここでは、広く使われている COOKIE メソッドを中心に説明します。

それでは、SESSION データはどこに保存されるのでしょうか?もちろんサーバー側ですが、メモリ内ではなく、ファイルまたはデータベース内にあります。デフォルトでは、php.ini で設定される SESSION の保存方法はファイル (session.save_handler = files) です。つまり、ファイルの読み書きによって SESSION データが保存され、SESSION ファイルが保存されるディレクトリはセッションによって指定されます。 save_path であり、sess_c72665af28a8b14c0fe11afe3b59b51b のように、ファイル名は接頭辞である sess_ で始まり、その後にセッション ID が続きます。ファイル内のデータはシリアル化後の SESSION データです。アクセス数が多い場合は、さらに多くの SESSION ファイルが生成される可能性があります。この場合、SESSION ファイルを保存するための階層ディレクトリを設定すると、設定方法が大幅に向上します。 session.save_path= N;/save_path"、N は階層レベル、save_path は開始ディレクトリです。 SESSION データを書き込むとき、PHP はクライアントの SESSION_ID を取得し、この SESSION ID を使用して、指定された SESSION ファイル格納ディレクトリ内で対応する SESSION ファイルを検索し、存在しない場合は作成し、最後にデータをシリアル化して書き込みます。ファイル。 。 SESSION データの読み取りも同様の操作プロセスで、読み取りデータを逆シリアル化する必要があり、対応する SESSION 変数が生成されます。 &S!m7 D7 J% O

; [' U9 u2 t-d

3. マルチサーバー共有セッションの主な障害と解決策

SESSION の仕組みを理解すると、デフォルトで各サーバーが同じクライアントの SESSION ID を生成することがわかります。たとえば、同じユーザー ブラウザの場合、サーバー A によって生成される SESSION ID は 30de1e9de3192ba6ce2992d27a1b6a0a であり、サーバーによって生成される SESSION ID は B です。 c72665af28a8b14c0fe11afe3b59b51b。また、PHP の SESSION データは、このサーバーのファイル システムに別途保存されます。以下の図に示すように: 8 w) T" B/ f, J+ t$ }1 R: f; q
) O# ^1 |, C- u+ t# Z
; 問題を特定したら、解決を開始できます。 SESSION データを共有したい場合は、2 つの目標を達成する必要があります。1 つは、同じクライアントに対して各サーバーによって生成された SESSION ID が同じである必要があり、同じ COOKIE を介して渡せることです。つまり、各サーバーは次のことを行うことができなければなりません。もう 1 つは、SESSION データの保存方法と場所が各サーバーにアクセスできるようにする必要があることです。簡単に言えば、複数のサーバーはクライアントの SESSION ID を共有し、サーバーの SESSION データも共有する必要があります。
" X8 {7 ]% Q5 k# a1 L
最初の目標の実現は実際には非常に簡単です。デフォルトでは、COOKIE のドメインは現在のサーバーのドメイン名/IP アドレスになります。各サーバーのドメインは異なります。たとえば、www.aaa.com のサーバーは、www.bbb.com のサーバーが設定した COOKIE を読み書きすることはできません。
- g8 q8 |; U1 u8 `6 K* J
ここで説明している同じ Web サイトのサーバーにはそれぞれ独自の特徴があります。つまり、同じ第 1 レベルのドメインに属しています。たとえば、aaa.infor96.com と www.infor96.com は両方ともドメイン .infor96 に属しています。 .com の場合、COOKIE のドメインを .infor96.com に設定して、aaa.infor96.com、www.infor96.com などがこの COOKIE にアクセスできるようにします。 PHPコードでの設定方法は以下の通りです

ini_set('session.cookie_domain', '.infor96.com');
?>

コードをコピー
このようにして、各サーバーが同じクライアント SESSION ID を共有するという目的が達成されます。 ; l, @8 W1 ]& ~.S: y9 O;

2 番目の目標は、NFS などのファイル共有方法を使用することで達成できますが、設定と操作はやや複雑です。前述のユーザー システムを統合する方法、つまりデータベースを使用して SESSION データを保存する方法を参照すると、各サーバーが同じデータ ソースに簡単にアクセスして同じ SESSION データを取得できます。

解決策は以下のとおりです: o T/ N( c0 x P/ ^" U6 A& c

5 H+ K1 h, f; `2 o) U

4. コードの実装 ! m1 C8 / r1 v) O

0 V3 {( ^; |! o! $ C) u3 Y0 b
まずデータテーブルを作成します。My SQL の SQL ステートメントは次のとおりです。
テーブル `sess` を作成 (

`sesskey` varchar(32) NOT NULL デフォルト '',

`expiry` bigint(20) NOT NULL デフォルト '0'、
`data` ロングテキスト NOT NULL,
主キー (`sesskey`)、
KEY `有効期限` (`有効期限`)
) TYPE=MyISAMsesskey は SESSION ID、expiry は SESSION の有効期限、data は SESSION データの保存に使用されます。

コードをコピー

デフォルトでは、SESSION データはファイル モードで保存されます。データベース モードで保存する場合は、各 SESSION 操作の処理関数を再定義する必要があります。 PHP には session_set_save_handle() 関数が用意されており、この関数を使用して SESSION 処理プロセスをカスタマイズできます。もちろん、まず session.save_handler を PHP で設定できるように変更する必要があります。

セッションモジュール名('ユーザー');

?>


コードをコピー
次に、session_set_save_handle() 関数に注目してみましょう。この関数には 6 つのパラメーターがあります。

session_set_save_handler (string open、string close、string read、string write、string destroy、string gc) 各パラメータは、各操作の関数名です。これらの操作は、 open、close、read、write、destroy、garbage collection の順序です。詳細な例は PHP マニュアルにあります。ここでは OO を使用してこれらの操作を実装します。詳細なコードは次のとおりです。

Define('MY_SESS_TIME', 3600); //SESSION 生存時間
//クラス定義
クラスMy_Sess
{
関数 init()
{
$domain = '.infor96.com';
//GET/POST変数メソッドは使用しないでください
ini_set('session.use_trans_sid', 0);
// ガベージ コレクションの最大存続時間を設定します
ini_set('session.gc_maxlifetime', MY_SESS_TIME);

//COOKIEを使用してSESSION IDを保存する方法
ini_set('session.use_cookies', 1);
ini_set('session.cookie_path', '/');
//複数のホストがセッション ID を保存する COOKIE を共有します
ini_set('session.cookie_domain', $domain);

// session.save_handler をデフォルトのファイルではなくユーザーに設定します
セッションモジュール名('ユーザー');
//SESSION の各操作に対応するメソッド名を定義します:
session_set_save_handler(
array ('My_Sess', 'open'), // 静的メソッド My_Sess::open() に対応、以下同様。
array('My_Sess', 'close'),
array('My_Sess', 'read'),
array('My_Sess', 'write'),
array('My_Sess', 'destroy'),
array('My_Sess', 'gc')
);
//関数の終了

関数 open($save_path, $session_name) {
true を返します;
//関数の終了

関数 close() {
グローバル $MY_SESS_CONN;

if($ my_sess_conn){ $MY_SESS_CONN->Close();
}
true を返します;
//関数の終了

関数 read($sesskey) {
グローバル $MY_SESS_CONN;

$sql = 'SELECT data FROM sess WHERE sesskey=' . $MY_SESS_CONN->qstr($sesskey) ' および expiry>=' 。 $rs =& $MY_SESS_CONN->実行($sql);
if ($rs) {
If ($rs->EOF) {
戻ります '';
//セッションIDに対応するセッションデータを読む $v = $rs->fields[0];
$rs->Close();
$v を返す;
//end if
//end if
戻ります '';
//関数を終了します

関数 write($sesskey, $data) {
グローバル $MY_SESS_CONN;

$qkey = $MY_SESS_CONN->qstr($sesskey);
$expiry = time() + My_SESS_TIME;
//セッションを書きます
$arr = array(
'sesskey' => $qkey,
'有効期限' => $有効期限,
に $MY_SESS_CONN->Replace('sess', $arr, 'sesskey', $autoQuote = true);
true を返します;
//関数の終了

関数 destroy($sesskey) {
グローバル $MY_SESS_CONN;

$MY_SESS_CONN->qstr($sesskey);
$rs =& $MY_SESS_CONN->実行($sql);
true を返します;
//関数の終了

関数 gc($maxlifetime = null) {
グローバル $MY_SESS_CONN;

$sql = 'sess WHERE から削除< time();
' $MY_SESS_CONN->Execute($sql);
// テーブル sess での削除操作が頻繁に行われるため、断片化が発生しやすくなります。
//したがって、テーブルはガベージ コレクション中に最適化されます。
$sql = 'テーブル最適化セッション';
$MY_SESS_CONN->Execute($sql);
true を返します;
//関数の終了
} } ///:~

//ADOdb をデータベース抽象化レイヤーとして使用します。
require_once('adodb/adodb.inc.php');
//データベース設定項目は設定ファイル (config.inc.php など) に配置できます。
$db_type = 'mysql';
$db_host = '192.168.212.1';
$db_user = 'sess_user';
$db_pass = 'sess_pass';
$db_name = 'sess_db';
//データベース接続を作成します。これはグローバル変数です。
$GLOBALS['MY_SESS_CONN'] =& ADONewConnection($db_type);
$GLOBALS['MY_SESS_CONN']->Connect( $db_host, $db_user, $db_pass, $db_name);
//SESSION 設定を初期化します。session_start() の前に実行する必要があります。 !
My_Sess::init(); www.2cto.com
?>

コードをコピー
5. 残りの問題 ' % p* 9 a5 N+ G+ v

アクセス数が多いWebサイトの場合、SESSIONによるデータベースへの読み書きが頻繁に行われるため、効率が大幅に低下します。通常、SESSION データはそれほど大きくないことを考慮して、C/Java でマルチスレッド プログラムを作成し、HASH テーブルを使用して SESSION データを保存し、ソケット通信を通じてデータの読み書きを試みることができます。メモリに保存され、読み書き速度が大幅に向上するはずです。さらに、負荷分散によりサーバーの負荷を分散できます。


作者: ああ彼

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