13

今年の UberConf のスライドを読みましたが、講演者の 1 人が、Spring JMS がメッセージ キュー システムにパフォーマンスのオーバーヘッドを追加するという議論をしていますが、それを裏付ける証拠はスライドに見当たりません。また、スピーカーは、各メッセージがすべてのコンシューマーにブロードキャストされるのではなく、1 回だけ送信されるため、従来の「パブリッシュ-サブスクライブ」方式よりもポイントツーポイントの方が高速であると主張しています。

経験豊富な Java メッセージングの第一人者がここで検討して、いくつかの技術的事項を明確にしてくれるかどうか疑問に思っています。

  • 純粋な JMS の代わりに Spring JMS を使用すると、実際にパフォーマンスのオーバーヘッドが発生しますか? もしそうなら、どのように、どこに導入されますか? それを回避する方法はありますか?
  • P2P が pub-sub モデルよりも高速であることを裏付ける実際の証拠はありますか? もしそうなら、P2P で pub-sub を使用したい場合はありますか (つまり、なぜ遅くなるのですか?!? )?
4

4 に答える 4

25

1) 主に、Spring JMS のオーバーヘッドは、JmsTemplate を使用して、下にキャッシュメカニズムなしでメッセージを送信することです。基本的に、JmsTemplate は送信するメッセージごとに次のことを行います。

  • 接続を作成
  • セッションの作成
  • プロデューサーの作成
  • メッセージを作成
  • メッセージを送る
  • セッションを閉じる
  • 接続を閉じる

これは、再利用する手動で記述されたコードと比較できます。

  • 接続を作成
  • セッションの作成
  • プロデューサーの作成
  • メッセージを作成
  • メッセージを送る
  • メッセージを作成
  • メッセージを送る
  • メッセージを作成
  • メッセージを送る
  • セッションを閉じる
  • 接続を閉じる

接続、セッション、およびプロデューサーの作成には、クライアントと JMS プロバイダー間の通信、およびもちろんリソースの割り当てが必要であるため、多数の小さなメッセージに対してかなり大きなオーバーヘッドが発生します。

これは、JMS リソースをキャッシュすることで簡単に回避できます。たとえば、Spring CachingConnectionFactoryまたは ActiveMQs PooledConnectionFactoryを使用します (この質問にタグを付けた ActiveMQ を使用している場合)。

完全な JavaEE コンテナ内で実行している場合、JNDI 接続ファクトリを取得するときにプーリング/キャッシングが組み込まれていることが多く、暗黙的に行われます。

Spring の Default Message Listening Container を使用して受信する場合、Spring にはオーバーヘッドがほとんど追加されない可能性のある薄いレイヤーがありますが、主な側面は、同時実行性などの点でパフォーマンスを微調整できることです。この記事ではそれについて非常によく説明されています。

2)

PubSub は、パブリッシャーがどのサブスクライバーが存在するかを知る必要がない使用パターンです。p2p でそれを単純にエミュレートすることはできません。そして、何の証拠もありませんが、あるアプリケーションから他の 10 個のアプリケーションに同じメッセージを送信したい場合、メッセージを p2p で 10 回送信するよりも、pub-sub セットアップの方が高速であると主張します。

一方、プロデューサーとコンシューマーが 1 つずつしかない場合は、代わりにキューを使用する P2P パターンを選択してください。いくつかの面で管理が簡単だからです。P2P (キュー) は負荷分散を可能にしますが、pub/sub では (簡単に) 不可能です。

ActiveMQ には、ハイブリッド バージョンのVirtualDestinationsもあります。これは、本質的に負荷分散に関するトピックです。

実際の実装はベンダーによって異なりますが、トピックとキューは根本的に異なるわけではなく、同様のパフォーマンスで動作するはずです。代わりにチェックする必要があるのは次のとおりです。

  • 持続性?(=遅い)
  • メッセージセレクター? (=遅い)
  • 同時実行性?
  • 永続的なサブスクライバー? (=遅い)
  • リクエスト/リプライ、一時キューと「同期的に」 (= オーバーヘッド = 遅い)
  • キューのプリフェッチ (= いくつかの点でパフォーマンスに影響します)
  • キャッシング
于 2012-08-07T09:17:38.767 に答える
4

Mark Richards のスライドについて話しているのですか? 彼はベンチマーク用のソース コードを投稿したので、JmsTemplate のパフォーマンスに関する彼の主張を実際にテストできます。彼のベンチマーク コードは Spring の CachingConnectionFactory を使用していますが、キャッシングにもかかわらず、JmsTemplate でパフォーマンスが大幅に低下することを示しています。私は彼のコードを実行し、プロファイリングし、分析しました。簡単な答えは、JmsTemplate からのオーバーヘッドは無視できるほどであり、彼のコードの測定可能なパフォーマンスの不一致は、ActiveMQ の非同期送信モードと同期送信モードに関係しているということです。ここに私の分析を投稿しました:

JmsTemplate は悪ではない

于 2013-01-06T04:18:56.200 に答える
2

1) Spring テンプレートは、送受信される各メッセージの接続/セッションを開閉します。それが遅い理由です。ほとんどの JMS 実装は、接続/セッションが開いたままの場合にパフォーマンスが向上するため、メッセージのプリフェッチなどの最適化を使用できるだけでなく、すべての接続のセットアップ/切断ビットを実行するオーバーヘッドを回避できます。

2) トピックが複数のコンシューマーにデータをコピー/レプリケートしている場合、トピックは通常遅くなります。これは単なる物理の問題です。10 MB のメッセージがキューにキュー送信される場合、10 MB のデータのみがコンシューマーに送信される必要があります。トピックについて言えば、10 人の消費者がいて、それに 10 メガのデータを送信する場合、100 メガのデータを消費者に送信する必要があります。したがって、ほとんどの JMS 実装では次のようになります。

  • コンシューマをトピックに追加すると、消費速度が遅くなるだけです。
  • コンシューマーをキューに追加すると、通常、デキュー率が向上します。
于 2012-08-07T12:56:33.987 に答える
1

私は教祖にメッセージを送っているわけではありません。ここで私の考えを共有しないでください ;)

  1. 余分な間接性があるため、常にオーバーヘッドが発生します。コール スタックの単なる余分なレベルであっても、依然としてオーバーヘッドです。ただし、そのようなオーバーヘッドは最小限であると考えています。JmsTemplate のソース コードを参照してください。送信中にSpringによって追加される余分なものはあまりありません。JmsTemplate は、とにかく JMS を使用している場合に必要なことをほとんど行っています。これらの追加のチェックとより深いメソッド呼び出しは、常により多くの CPU サイクルとメモリを消費すると主張することができます。それはそうですが、それがどれほど重要なのだろうかと思います。

  2. PubSub と P2P (JMS 用語ではトピックとキュー) は、2 つの異なるモデルにすぎません。私はそれらが互いに置き換えることはできないと信じています。キューを使用して「一度送信して複数の受信者にブロードキャストする」動作を行うことはできず、同時に、トピックを使用するときに配信保証動作を行うことはできません (Durable Subscriber を使用しない限り、それは別のトピックです)。したがって、P2P が PubSub よりも優れているとやみくもに言うのではなく、何をしているかに応じて適切なタイプを選択してください (これはナンセンスだと思います)。

于 2012-08-07T07:48:54.170 に答える