2010-12-02 20 views
1

複数のクライアントからのログインを処理するJavaサーバーがあります。サーバーは、各tcp/ipソケット・リスナーのスレッドを作成します。データベースアクセスは、サーバーが作成する別のスレッドによって処理されます。Javaでの非同期メッセージキューの実装

私がサーバに接続しているクライアントの数はかなり少なく(< 100)、実際のパフォーマンスの心配はありませんが、将来どのようにクライアントを処理するべきかを考えています。私の関心事は、多くのクライアントでは、サーバとデータベースのスレッドが、クライアントスレッドからのメソッドへの定数呼び出しによって邪魔になることです。

具体的には、データベースとの関係:各クライアントスレッドは、そのサーバーの親のパブリックデータベーススレッドにアクセスし、データアクセスメソッドを実行します。私がやるべきことは、何らかのメッセージキューを用意して、クライアントスレッドがそのデータ要求を置くことができ、データベーススレッドがラウンドしたときにそれを行うということです。データアクセス呼び出しから返されるデータがあれば、それをクライアントスレッドがピックアップするためにキューに置くことができます。これはすべてメインサーバーコードや他のクライアントスレッドには当てはまりません。

したがって、私は、クライアントスレッドがメッセージを置くことができる非同期メッセージキューを実装したいと思って、データベーススレッドが拾い上げます。それは正しいアプローチですか?私が実装について読むことができるどんな考えやリンクもありがたいです。

+0

答えがありませんので、コメントしてください...あなたはおそらくGoogleに "Java C10Kの問題"を望むでしょう。基本的に、TCP/IP接続ごとに1つのスレッドは、あなたが疑っているとおりに切断していません。あなたの問題は必ずしもあなたが書いた「定数呼び出し」*ではありませんが、クライアントの数が多くなると(クライアントごとに1つのスレッドを使用し続けると)巨大な数のスレッド間で一定のスワッピングが行われます。 – SyntaxT3rr0r

+0

IOをブロックすることは、最近10Kスレッドまで非常によく実行できます。 espをJava 6と一緒に使用しています。これは以前と同じくらい問題ではありません。 –

答えて

4

このアプローチはお勧めしません。

JMSはこの種のもののために生まれました。最初から書き込む実装よりも優れています。 JMSが組み込まれているJava EEアプリケーションサーバーや、Tomcatなどのサーブレットエンジンに追加できるActiveMQやRabbitMQなどを使用することをお勧めします。

あなた自身で作成する前に、これらを調査することを強くお勧めします。

1

説明している内容は、ExecutorCompletionServiceのようになります。これは本質的に、1つのスレッドからの要求(RunnableまたはCallable秒)を受け取り、Futureという形で次の結果に「ハンドル」を返す非同期タスクブローカーです。その後、要求はthread poolsingle thread thread poolである可能性があります)で実行され、要求の結果はFutureを介して呼び出しスレッドに返されます。

要求が送信されてから応答が提供されるまでの間に、クライアントスレッドは将来的に(オプションのタイムアウトを使用して)待機します。

しかし、クライアント(したがってクライアントスレッド)の数が大幅に増えることが予想される場合は、Java NIOサーバーフレームワークのいくつかを評価する必要があります。これにより、クライアントごとに1つのスレッドを割り当てることを避けることができます。特に、これらのスレッドがすべてDB要求を待つ時間を費やすことが予想されるためです。このような場合は、MINAまたはNettyをご覧ください。

乾杯。

//ニコラス

0

何がやりたいことは許可したいデータベースへの同時要求の数を制限しているように聞こえます。 (オーバーロードを止めるには)

限られたサイズの接続プールをお勧めします。データベースを使用したいスレッドが多すぎる場合、接続が解放されるまで待つ必要があります。これを行う簡単な方法は、すべての接続が事前に作成された状態でBlockingQueueを使用することです。

private final BlockingQueue<Connection> connections = new ArrayBlockingQueue<Connection>(40); { 
    // create connections 
} 

// to perform a query. 
Connection conn = connections.get(); 
try { 
    // do something 
} finally { 
    connections.add(conn); 
} 

この方法であなたはそれがあるとほとんど同じあなたのスレッドのデザインを維持し、データベースへの同時クエリの数を制限することができます。いくつかの微調整では、必要に応じて接続を作成し、データベース接続を迅速に取得できない場合にはタイムアウトを提供することができます。

関連する問題