5

OSGi コンテナー (現在 Equinox) で実行されるアプリケーションを設計しています。RabbitMQ 経由でメッセージを受信し、内部で処理します。アプリケーションはサーバーとして継続的に実行されます。私の現在の計画は、RabbitMQ リスナー バンドルでキューを構成し、リスナーをそれらに配置してQueueingConsumer、独自のスレッドを使用して実行することです。リスナーは、メッセージを処理するために 1 つ以上の処理サービスを呼び出します。プロセッサーは、データベースにアクセスするために JDBC 呼び出しを行う必要があります。プロセッサが呼び出される順序を制御できるようにしたいと考えています。RabbitMQ リスナーを再コーディングせずに、後でサービスを追加できる柔軟性があると便利です。

私が直面している問題は、メッセージがバーストまたはゆっくりと届く可能性があることです。を使用してデータベースへのアクセスを高速化できるようにしPreparedStatementたいのですが、何も行われていない間、接続を長期間開いたままにしたくありません。DefaultConsumer直接サブクラス化して、 RabbitMQ のスレッドで実行することを考えましConnectionたが、何も起こっていないことを知る能力が失われます。私の最初のアイデアは、メッセージ プロセッサを OSGi サービスとして完全に分離し、それぞれが呼び出されるたびにプールからデータベース接続を取得することでしたが、それではプリペアド ステートメントの利点が失われました。Tomcat JDBC プールを使用していますが、Prepared Statement キャッシュがないようです。また、すべての呼び出しに対して準備済みステートメントを作成するのにどれだけの費用がかかるかはわかりませんが、無駄に思えます。

これまでに思いついた最良のアイデアは、リスナーを二重ループで処理させることです。外側のループはメッセージを待ってから、データベース接続と準備済みステートメントを確立する内側のループを呼び出し、指定されたタイムアウトまでメッセージが来なくなるまで実行し、接続を閉じて外側のループに戻ります。私はこれを 1 ビットの処理で動作させましたが、複数のプロセッサが異なる準備済みステートメントを持つ可能性がある場合、これを管理する方法を視覚化するのに苦労しています。

おそらく、複数のサービスのアイデアをあきらめて、処理をリスナーにハードコーディングする必要があります。

助言がありますか?ありがとう!

4

1 に答える 1

1

サービスをリスナーとして使用し、使用する必要がある JDBC 接続をサービスに渡してみませんか? 次に、1 つのコードでキューをサービスにディスパッチします。この中央ディスパッチャは、準備された JDBC 接続のプールを簡単に維持できます。API で JDBC 接続を表示したくない場合は、Coordinator サービスを使用して接続を保持します。「認識」サービスは、最適化された JDBC 接続を取得できます。

または、DataSource をリスナー サービスのサービスとして登録し、独自のプール ポリシーを実装します。OSGi サービス呼び出しの呼び出し元を知っているので、あらゆる種類の最適化を行うことができます。たとえば、バンドルの jar から準備されたステートメントを読み取り、それに応じてそれらをキャッシュします。

私はここでサービスをあきらめません。得られるデカップリングは素晴らしいものです。私は経験から知っていました。このモデルでは、サービス リスナーは RabbitMQ に依存していないため、簡単にテストしたり、別のキュー テクノロジーに切り替えたりすることができます。

繰り返しますが、これらの場合、最善の方法は、思いつく最も単純な解決策を実行することです. パフォーマンスに問題がある場合は、ボトルネックを測定して修正します。途方もない量の労力が時期尚早の解決策に浪費されている ...私が時間を無駄にしたばかげた時期尚早の最適化のかなりの数を言うことができます。

于 2012-10-02T06:44:55.827 に答える