8

私は現在、ある種のコメットテクニック(ロングポーリングXHRリクエスト)用の単純なHTTPサーバーを実装しようとしています。JavaScriptクロスドメイン リクエストについては非常に厳格であるため、いくつか質問があります。

  1. 私が理解しているように、リクエストを処理している間はすべての Apache ワーカーがブロックされるため、通常の Web サイトのように「スクリプト」を記述すると、すべてのワーカーがリクエストを処理しているときに Apache がブロックされます。--> 動かない!
  2. 私は、この長いポーリング リクエストを処理するためだけに、独自の単純な HTTP サーバーを作成するというアイデアを思いつきました。このサーバーはブロックされるべきではないため、各ワーカーは同時に多くのリクエストを処理できます。私のサイトにはコンテンツ/画像なども含まれており、サーバーはコンテンツをサーバーする必要がないため、80 とは別のポートで彼を開始しました。現在の問題はJavaScript、Apache によって配信されたものと実行中の comet-server の間で対話できないことです。いくつかのクロスドメイン制限のため、別のポートで。--> 動かない!
  3. mod_proxy次に、サーバーを新しいサブドメインにマップするために使用するアイデアを思いつきました. 私は実際にどのように機能するのか理解できませんでしたがmod_proxy、最初のアプローチと同じ効果があることを知っていると想像できますか?

この種の古典的な Web サイトとこれらのロングポーリング XHR リクエストを組み合わせて作成するには、どのような方法が最適でしょうか? 自分のサーバーに自分でコンテンツ配信を実装する必要がありますか?

4

5 に答える 5

3

これは難しい問題です。直面しているセキュリティの問題を乗り越えたとしても、現在 Web ページを見ているすべてのクライアントに対して TCP 接続を開いたままにしておく必要があります。各接続を処理するスレッドを作成することはできず、単一のスレッドからすべての接続を「選択」することはできません。以前にこれを行ったことがあるので、簡単ではないことがわかります。memcachedが同様の目的で使用するlibevent調べることをお勧めします。

ある程度までは、長いタイムアウトを設定し、Apache に膨大な数のワーカーを許可することで、ほとんどの場合アイドル状態になる可能性があります。Apache ワーカー モジュールを慎重に選択して構成することで、これを何千もの同時ユーザーに拡張できると思います。ただし、ある時点で、それ以上スケールアップしなくなります。

インフラストラクチャがどのようなものかはわかりませんが、F5 と呼ばれるネットワーク ラックに負荷分散ボックスがあります。これらは単一の外部ドメインを提示しますが、応答時間、リクエスト ヘッダーの Cookie などに基づいてトラフィックを複数の内部サーバーにリダイレクトします。仮想ドメイン内の特定のパスのリクエストを特定のサーバーに送信するように構成できます。したがって、これらのコメット リクエストを処理するために、example.com/xhr/foo リクエストを特定のサーバーにマッピングすることができます。残念ながら、これはソフトウェア ソリューションではなく、かなり高価なハードウェア ソリューションです。

いずれにせよ、ある種の負荷分散システムが必要になるかもしれません (または、すでに持っているかもしれません)。おそらく、この状況を Apache よりもうまく処理するように構成できます。

何年も前に、独自のバイナリ プロトコルを使用するクライアント サーバー システムを使用している顧客がポート 80 でサーバーにアクセスできるようにするという問題がありました。これは、システムが使用するカスタム ポートのファイアウォールで継続的に問題が発生していたためです。私が必要としていたのは、ポート 80 に存在し、クライアントから渡されたものの最初の数バイトに応じて、トラフィックを Apache またはアプリケーション サーバーのいずれかに転送するプロキシでした。解決策を探しましたが、適切なものは見つかりませんでした。私は Apache モジュール、DeleGate 用のプラグインなどを書くことを検討しましたが、最終的には独自のカスタム コンテンツ センシング プロキシ サービスによって展開されました。それは、あなたがやろうとしていることの最悪のシナリオだと思います。

于 2009-07-19T22:26:31.953 に答える
3

mod_proxy を使用すると、リクエストの処理中にワーカーがブロックされると確信しています。

2 つの IP を使用できる場合は、かなり簡単な解決策があります。IP A が 1.1.1.1 で、IP B が 2.2.2.2 で、ドメインが example.com だとします。

これがどのように機能するかです:

-ポート 80 でリッスンするように Apache を構成しますが、IP A でのみリッスンします。

-他のサーバーをポート 80 で起動しますが、IP B のみで起動します。

- XHR リクエストをドメインのサブドメインに設定しますが、同じポートを使用します。したがって、クロスドメインの制限はそれらを妨げません. たとえば、あなたのサイトは example.com で、XHR リクエストは xhr.example.com に送信されます。

-example.com が IP A に解決され、xhr.example.com が IP B に解決されるように DNS を構成します。

-完了です。

このソリューションは、2 つのサーバーがあり、それぞれに IP がある場合に機能し、1 つのサーバーに 2 つの IP がある場合にも機能します。

2 つの IP を使用できない場合は、別の解決策があるかもしれません。それがあなたのケースに当てはまるかどうかを確認しています。

于 2009-07-17T06:07:23.887 に答える
0

3 つの選択肢:

  1. nginx を使用します。これは、nginx、Apache、および独自のサーバーの 3 つのサーバーを実行することを意味します。
  2. サーバーを独自のポートで実行します。
  3. Apache mod_proxy_http を使用します (独自の提案として)。

mod_proxy_http (Apache 2.2.16) が、GlassFish 3.1.1 で実行されている Comet アプリケーション (Atmosphere 0.7.1 を搭載) のプロキシとして機能することを確認しました。

完全なソースを含む私のテスト アプリはこちらです: https://github.com/ceefour/jsfajaxpush

于 2011-04-25T18:30:09.360 に答える
0

その 2 については、JSONP を使用してクロスドメインの制限を回避できます。

于 2009-11-25T14:58:58.383 に答える
0

mod-proxy に関する特定の質問に答えるには: yes、公開されていないサーバー (またはサービス) によって生成されたコンテンツを提供するように mod_proxy をセットアップできます (つまり、内部アドレスまたはローカルホスト経由でのみ利用可能です)。

私はこれを実稼働環境で実行しましたが、非常にうまく機能します。Apache は、一部のリクエストを AJP ワーカー経由で Tomcat に転送し、その他のリクエストを mod プロキシ経由で GIS アプリケーション サーバーに転送します。他の人が指摘しているように、クロスサイト セキュリティによりサブドメインでの作業が停止する場合がありますが、リクエストを mydomain.com/application にプロキシできない理由はありません。


あなたの特定の問題について話すために-私は本当にあなたが問題を「長命のリクエスト」として見ることに行き詰まっていると思います-つまり、これらのリクエストの1つを行うと、プロセス全体を停止する必要があると仮定します。システム アーキテクチャを変更することで、アプリケーション アーキテクチャの問題を解決しようとしているようです。実際、これらのバックグラウンド リクエストをそのように正確に処理する必要があります。そしてそれをマルチスレッド化します:

  • クライアントは、リモート サービスに「データ A、B、および C を使用してタスク X を実行する」という要求を行います。
  • あなたのサービスはリクエストを受け取ります: リクエストに対して一意のチケット/トークンを発行するスケジューラにそれを渡します。次に、サービスはこのトークンをクライアントに返します
  • 次に、クライアントはこのトークンにハングアップし、「読み込み中/お待ちください」ボックスを表示し、たとえば、引数に対して1秒ごとに起動するタイマーを設定します
  • タイマーが起動すると、クライアントはリモート サービスに別のリクエストを行います
  • その後、バックグラウンド サービスでスケジューラを確認し、空のドキュメント「いいえ、まだ完了していません」または結果を返す可能性があります。
  • クライアントが結果を取得すると、タイマーをクリアして表示することができます。

スレッド化にかなり慣れている限り (独自の HTTP サーバーを作成することを検討している場合は、スレッド化に慣れている必要があります)、これはあまり複雑ではないはずです - http リスナー部分の上に:

  • スケジューラ オブジェクト - シングルトン オブジェクトで、実際には「先入れ先出し」スタックをラップするだけです。新しいタスクはスタックの最後に置かれ、ジョブは最初から取得できます。ジョブを発行するコードがスレッド セーフであることを確認してください (スタックから同じジョブを取得する 2 つの作業が発生しないようにしてください)。
  • ワーカー スレッドは非常に単純です。スケジューラにアクセスし、次のジョブを要求します。次のジョブがある場合は結果を送信し、そうでない場合は一定期間スリープし、最初からやり直します。

このようにすれば、「do x」または「x の結果を教えてください」というリクエストを発行するだけなので、必要以上に長く Apache をブロックすることはありません。失敗したタスクを処理したり、クライアント側にタイムアウトを設けて無期限に待機しないようにしたりするなど、いくつかの点でいくつかの安全機能を組み込むことがおそらく必要になるでしょう。

于 2009-07-21T09:00:07.600 に答える