1

大量のメッセージ (トレーディング システムなど) を処理できる単純なアプリケーション (j2ee と jms なし) を設計したいと考えています。

メッセージを受信して​​キューに入れることができるサービスを作成して、過負荷時にシステムがスタックしないようにしました。

次に、キューをラップし、キューからメッセージをポップアウトする pop メソッドを持つサービス (QueueService) を作成しました。メッセージが null を返さない場合、このメソッドは次のステップで「同期済み」としてマークされます。

メッセージの処理方法を知っているクラス (MessageHandler) と、新しいスレッドでメッセージを「リッスン」できる別のクラス (MessageListener) を作成しました。スレッドには「while(true)」があり、常にメッセージをポップしようとします。

メッセージが返された場合、スレッドは MessageHandler クラスを呼び出し、それが完了すると、別のメッセージを要求します。

これで、10 個の MessageListener を開いて複数のメッセージを処理できるようにアプリケーションを構成しました。

現在、常にループしているスレッドが 10 個あります。

いいデザインですよね??

そのようなシナリオを処理する方法について、誰かが私にいくつかの本やサイトを参照してもらえますか??

ありがとう、ロニー

4

7 に答える 7

5

あなたの説明から、あなたは正しい道を進んでいるように見えますが、1 つの小さな例外があります。キューからメッセージを取得する際にビジー待機を実装しました。

より良い方法は、同期されたpopMessage()メソッドでスレッドをブロックしwait()、メッセージをポップすることができなくなったときにキュー リソースを実行することです。キューにメッセージを追加すると、待機中のスレッドが を介して起動されnotifyAll()、1 つ以上のスレッドがメッセージを取得し、残りのスレッドが再びwait()状態に入ります。

これにより、CPU リソースの分配がよりスムーズになります。

于 2009-11-23T15:15:25.643 に答える
3

Websphere や Sonic などのキューイング プロバイダーには費用がかかることは理解していますが、常に JBoss Messaging やFUSE with ApacheMQ などがあります。JMS よりも優れた JMS を作成しようとしないでください。ほとんどの JMS プロバイダーには、キュー サーバーまたはアプリケーション サーバーが停止した場合にフォールト トレランスを提供する永続化機能があります。車輪を再発明しないでください。

于 2009-11-23T14:58:49.747 に答える
2

イベントループ

代わりにイベント ループ/メッセージ ポンプを使用するのはどうですか? 私は実際に、Ryan による優れたnode.jsビデオ プレゼンテーションを見て、このテクニックを学びました。

Thread aからへ最大 10 件のメッセージをプッシュしますThread b(満杯の場合はブロックします)。スレッド a には無制限の があり[LinkedBlockingQueue][3]()ます。スレッド b には、[ArrayBlocking][4]サイズ 10 の境界があります ( new ArrayBlockingQueue(10))。と の両方thread athread b、無限の「while ループ」があります。Thread bから入手可能なメッセージを処理しますArrayBlockingQueue。この方法では、無限の「while ループ」が 2 つだけになります。補足として、仕様を読む際には、次の文のために 2 つの arrayBlockingQueues を使用することをお勧めします。

通常、リンクされたキューはアレイベースのキューよりもスループットが高くなりますが、ほとんどの同時実行アプリケーションではパフォーマンスが予測しにくくなります。

もちろん、配列でバックアップされたキューには、事前にサイズを設定する必要があるため、より多くのメモリを使用するという欠点があります(小さすぎると、いっぱいになるとブロックされるため、メモリが不足している場合は大きすぎると問題になる可能性があります)使用.

受け入れられた解決策:

私の意見では、受け入れられた解決策よりも私の解決策を優先する必要があります。その理由は、可能な場合はjava.util.concurrentパッケージのみを使用する必要があるためです。適切なスレッド コードを記述するのは困難です。間違いを犯すと、デッドロックや飢餓などに陥ります。

レディス:

他の人がすでに述べたように、これには JMS を使用する必要があります。私の提案はこれに沿ったものですが、私の意見では、使用/インストールが簡単です。まず、サーバーが Linux を実行していると仮定します。Redis をインストールすることをお勧めします。Redis は本当に素晴らしく高速なので、データストアとしても使用する必要があります。使用できるブロックリスト操作があります。Redis は結果をディスクに保存しますが、非常に効率的な方法です。


幸運を!

于 2010-05-02T23:57:26.753 に答える
2

行間を少し読むと、MQ などの JMS プロバイダーを使用していないように思えます。あなたのソリューションはほとんどの場合問題ないように思えますが、JMS を使用しない理由について質問させていただきます。

あなたはトレーディングについて言及していますが、多くのトレーディング システムが j2ee の有無にかかわらず JMS を使用していることを確認できます。高いパフォーマンス、信頼性、および独自のキューイング システムを作成することによって車輪を再発明する必要がない場合は、JMS プロバイダーとそのクライアント API のいくつかを参照してください。

カール

于 2009-11-23T14:53:12.723 に答える
1

非常に軽量で、超高速で、スケーラブルなキューイングシステムが必要です。Hazelcast分散キューをお試しください!

これは、の分散実装ですjava.util.concurrent.BlockingQueue詳細については、ドキュメントを確認してください。

Hazelcastは、実際には分散キューより少し多いです。これは、Javaのキュー、トピック、マップ、マルチマップ、ロック、エグゼキューターサービスのトランザクション分散実装です。

Apacheライセンスの下でリリースされます。

于 2010-05-02T22:52:43.950 に答える
1

時代遅れになってきていますが、Practical .NET for Financial Marketsは、金融取引システムを開発する際に考慮すべき普遍的な概念のいくつかを示しています。.Net を対象としていますが、一般的な概念を Java に変換できるはずです。

于 2009-11-23T14:53:10.337 に答える
1

メッセージのリッスンとその処理を分離することは、私には理にかなっているように思えます。スケーラブルな数の処理スレッドを持つことも良いことです。プラットフォームでどれだけの並列処理が機能するかを調べながら、数を調整できます。

私があまり満足していないのは、スレッドがメッセージの到着をポーリングする方法です。ここでは忙しい仕事をしています。それを減らすためにスリープを追加すると、メッセージの到着にすぐに反応しません。JMS API と MDB は、よりイベント駆動型のアプローチを採用しています。代替手段を確認できるように、オープン ソース JMS でそれがどのように実装されているかを見てみましょう。[自分で JMS を再発明するのはおそらく悪い考えであるという意見も支持します。] 心に留めておくべきことは、システムがより複雑になるにつれて、より多くのキューを追加し、より多くの忙しい作業を処理すると、より大きな影響を与えるということです。

私が抱えているもう 1 つの懸念は、1 台のマシンを使用することの制限にぶつかることです。まず、リスナーが多くのマシンに存在できるようにすることで、スケーラビリティを高めることができます。次に、単一障害点があります。明らかに、この種の問題を解決することは、メッセージング ベンダーが収益を上げているところです。これは、複雑なミドルウェアではビルドよりも購入が有利になるもう 1 つの理由です。

于 2009-11-23T14:59:02.897 に答える