51

OK、それで、負荷分散された PHP Web サイトのこのまったく珍しいユニークなシナリオを手に入れました。残念なことに、以前は負荷分散されていませんでした。今、問題が発生し始めています...

現在、唯一の問題は PHP セッションにあります。当然のことながら、最初は誰もこの問題について考えていなかったので、PHP セッション構成はデフォルトのままにされました。したがって、両方のサーバーには独自のセッションファイルの小さな隠し場所があり、最初のサーバーで作成したセッションがないため、他のサーバーにスローされた次の要求を取得するユーザーは悲惨です。

今、私はこの状況を解決する方法について PHP のマニュアルを読んでいます。そこで の素敵な機能を見つけましたsession_set_save_handler()。(偶然にも、SO に関するこのトピック) いいですね。ただし、Web サイトのすべてのページでこの関数を呼び出す必要があります。また、将来のページの開発者は、常にそれを呼び出すことも覚えておく必要があります。おそらく十数のベストコーディングプラクティスに違反していることは言うまでもありません。いくつかのグローバル構成オプションを反転させるだけで、セッションがすべて DB やメモリ キャッシュなどに魔法のように保存されれば、はるかに良いでしょう。

これを行う方法についてのアイデアはありますか?


追加:明確にするために - これは標準的な解決策による標準的な状況であると予想しています。参考までに - MySQL DB を利用できます。確かに、これを解決するすぐに使えるコードがそこにあるに違いありませんか? もちろん、私は独自のセッション保存機能を書くことができ、Gregauto_prependが指摘したオプションは有望に思えますが、それは車輪の再発明のように感じます。:P
追加 2:ロード バランシングは DNS ベースです。これがどのように機能するかはわかりませんが、次のようになるはずです
追加 3: OK、解決策の 1 つは、すべてのスクリプトauto_prependに呼び出しを挿入するオプションを使用しsession_set_save_handler()、独自の DB パーシスタを作成することです。おそらく、memcachedパフォーマンスを向上させるために呼び出しをスローします。けっこうだ。

これをすべて自分でコーディングしないようにする方法もありますか? よくテストされた有名な PHP プラグインが好きですか?

ずっと後で追加しました:これは私が最終的に行った方法です: PHP + MySQL でカスタム セッション パーシスタを適切に実装するにはどうすればよいですか?

また、すべてのページに手動でセッション ハンドラーを含めただけです。

4

10 に答える 10

22

これを処理する方法は、memcachedを使用することです。必要なのは、次のようにphp.iniを変更することだけです。

session.save_handler = memcache
session.save_path = "tcp://path.to.memcached.server:11211"

AWS ElastiCacheを使用しているため、サーバーパスはドメインですが、ローカルmemcachedでも同様であると確信しています。

この方法では、アプリケーションコードを変更する必要はありません。

于 2012-10-24T15:20:12.680 に答える
10

負荷分散に使用しているテクノロジー(ソフトウェア、ハードウェアなど)については言及していません。ただし、いずれの場合でも、問題の解決策は、ロードバランサーで「スティッキーセッション」を採用することです。

要約すると、これは、「新しい」訪問者からの最初の要求が着信すると、クラスターから特定のサーバーが割り当てられることを意味します。セッションの存続期間中の今後のすべての要求は、そのサーバーに送信されます。実際には、これは、単一のサーバーで動作するように作成されたアプリケーションを、コードの変更がゼロまたは少ないバランスの取れた環境にアップスケールできることを意味します。

ラドウェアデバイスなどのハードウェアバランサーを使用している場合、スティッキーセッションはクラスターセットアップの一部として構成されます。ハードウェアデバイスは通常、新しいユーザーが割り当てられているサーバーなど、よりきめ細かい制御を提供し(ヘルスステータスなどをチェックして、最も正常で最も使用率の低いサーバーを選択できます)、サーバーの実行時に何が発生するかをより詳細に制御します。失敗し、クラスターから脱落します。ハードウェアバランサーの欠点はコストですが、それだけの価値はあります。

ソフトウェアバランサーに関しては、それはあなたが使用しているものに帰着します。Apacheの場合、mod_proxyにstickysessionプロパティがあります-これをphpセッションで機能させるためのGoogle経由の記事がたくさんあります(たとえば


編集:元の質問の後に投稿された他のコメントから、「バランシング」はラウンドロビンDNSを介して行われているように思われるため、上記はおそらく当てはまりません。これ以上コメントしたり、ラウンドロビンDNSに対して炎上したりすることは控えます。

于 2009-06-15T08:48:58.480 に答える
4

最も簡単な方法は、常に同じセッションを同じサーバーに送信するようにロード バランサーを構成することです。

それでも使いたい場合はsession_set_save_handler、auto_prepend を見てください。

于 2009-06-15T08:10:14.877 に答える
3

PHP セッションを使用している場合は、クラスター内のすべてのサーバー間で、セッションが保存されていると思われる /tmp ディレクトリを NFS と共有できます。そうすれば、データベースは必要ありません。

編集: memcachedb (永続的で高速) などの外部サービスを使用して、セッション情報を memcachedb インデックスに保存し、コンテンツのハッシュまたはセッション ID で識別することもできます。

于 2009-06-15T12:02:35.177 に答える
2

memcacheをセッションハンドラーとして使用することもできます

于 2009-06-15T08:51:34.810 に答える
2

手遅れかもしれませんが、これをチェックしてください: http://www.pureftpd.org/project/sharedance

Sharedance は、一時的なキー/データ ペアをリモート ホスト上で集中管理するための高性能サーバーであり、オーバーヘッドや SQL データベースの複雑さはありません。

主に、Web サーバーのプール間でキャッシュとセッションを共有するように設計されています。シェアダンス サーバーへのアクセスは、単純な PHP API を介して簡単に行うことができ、PHP 4 および PHP 5 セッション ハンドラーの期待と互換性があります。

于 2013-12-03T10:29:30.593 に答える