3

サーバーは本質的にアイテムのキューであり、クライアントはそのようなアイテムのプロデューサーおよび/またはコンシューマーとして機能します。

サーバーは次のことを行う必要があります。

  • put / take リクエストをリッスンし、それに応じて処理します。通常、これにはあまり時間がかかりません。次の要素で構成されます。
    1. 短い文字列を解析します。
    2. アンHashMap.get;
    3. ロックの取得。
    4. PriorityQueue.pollまたはPriorityQueue.offer; _
  • すべてのクライアントに、すべてのアイテム アクティビティをできるだけ早く通知して、すべてのクライアントが何が起こっているかをリアルタイムで確認できるようにします。

これを設定する最も簡単な方法は、acceptクライアントをスレッド化してから、クライアントごとに 2 つのスレッドを作成することです。

  • InputStreamリクエストの待機をブロックする を処理するもの。
  • もう 1 つはOutputStream、キューでイベントをリッスンし、情報をクライアントに送信する を処理します。

確かにこれはスケーラブルではなく、クライアントごとに 2 つのスレッドを持つのは無駄に思えます。

また、単一のスレッドを使用することも考えました。

  • ソケットのタイムアウトをread約 1 秒に設定します。
  • readタイムアウトの場合、またはリクエストの処理後に、すべての新しいイベントをクライアントに送信します。
  • これら 2 つのアクションをループします。

ただし、リクエストとイベントのポーリングも無駄です。

別のアプローチでは、スレッド プールを使用し、上記の 2 つのアクションをそれぞれの に配置しますRunnable。これらのランナブルは、Executor. これは、それ以上ではないにしても、同じくらい無駄に思えます。

私はいくつかの 質問を読んでいましたが、ノンブロッキング操作とイベント駆動型サーバーが正しいアプローチであるように思われるため、NIO に興味があります。

上記の設計のいずれかがこのタスクに適していますか、または NIO で取り組む必要がありますか?

数に関して言えば、これは実際のシステムというよりも演習であるため、何千ものクライアントを処理する必要はありませんが、理想的には、パフォーマンスとスケーリングが適切に実行できる必要があります。

4

4 に答える 4

2

ランナーを管理する必要があるため、ThreadPool を使用し続ける必要があります。このクライアントがサーバーに接続し、サーバーがクライアントの要求 (データ) を待機し、サーバーがジョブをキューに入れるため、MOA 構造をビジネスに組み込むことをお勧めします (処理できるスレッドがない場合)、サーバーでクライアント プロセス ID を指す long 値をすぐに応答し、ソケットを閉じます。クライアントのリクエストが処理され、アクションの準備が整ったらどうなるでしょうか? したがって、ここには2つのアプローチがあります。良い方法は、完了したリクエストについてサーバーがクライアントに通知することです(したがって、クライアントはサーバーの応答[ServerSocket]についてリッスンする必要があります)。OR クライアントは定期的にサーバーをチェックし、プロセスのステータスをチェックします。

于 2013-10-02T19:25:38.557 に答える
1

私はいくつかのプロダクション レベルのリアルタイム システムを設計および実装しました (ミリ秒レベルの遅延について話しますが、クライアントは少数です)。IMHOは間違いなくNIOアプローチをとるべきです。

NIO のコアは基本的に select() です。これにより、異なるソケット/クライアントからの入力に同時に取り組むことができます。その後、イベントを適切なキューに入れたり、システム全体にブロードキャストしたりします。次に、キューを処理してスレッドを割り当てる方法は、IO タスクとは完全に無関係であり、独自の調整次第です。

また、本質的に同じ考え方を適用する ZeroMQ も見てください。複数のソケットモデルでのポーラーを見てください。JMS/EMS、TibcoRV、29 West LBM など (現在は Informatica 傘下) を含む最新のメッセージング フレームワークのほとんどは、すべて同様のアプローチを取っていると思います。

于 2013-10-03T03:26:57.323 に答える