8

私は現在、サーバーとクライアントの間でペイロードを含むメッセージを送信するために JMS (つまり、Spring フレームワーク JMS と Active MQ) を使用するアプリケーションの帯域幅制限機能 (理由は聞かないでください。私の決定ではありません) に取り組んでいます。

着信 JMS メッセージを制限するスロットリング方法はたくさん見つかりましたが (ただし、実際の帯域幅負荷に基づくものはありませんでした)、発信メッセージ フローを制限する方法は見つかりませんでした。そこで、リーキー バケット アルゴリズムを自分で作成することにしました。

JMS メッセージのサイズを取得する方法はありますか? Java での「sizeof」実装以外 ( Java では、オブジェクトのサイズを決定する最良の方法は何ですか? )

4

3 に答える 3

4

シリアル化されたサイズを測定するよりも、JMS メッセージのサイズを決定するための真剣に優れた代替手段があるとは思いません。

ただし、必要に応じて最適化を追加できます。メッセージにはいくつかのタイプがあります (MapMessage、ObjectMessage、TextMessage など)。

テキスト メッセージのサイズは、そのテキストの長さです。マップ メッセージのサイズは、そのすべてのフィールドの合計サイズです。フィールドはプリミティブまたは java.util.Date であるため、それらを測定しても問題ありません。オブジェクト メッセージにはシリアライズ可能なオブジェクトが含まれているため、ByteOutputStream に書き込むことでそのサイズを測定できます。

ほとんどの JMS プロバイダーの隠し機能を使用して遅延メッセージを送信している場合、JMS を使用したリーキー バケットの実装が簡素化される可能性があると思います。メッセージをエンキューするときにメッセージを測定し、いつサブスクライバーにメッセージを受信させるかを決定できます。遅延メッセージの送信方法の詳細については、こちらをお読みください: http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html

于 2011-08-17T09:19:51.317 に答える
4

JMS メッセージは送信プロセスでシリアル化されるため、メッセージのサイズを取得する最良の方法はObjectOutputStreamを使用することです。

private int getMessageSizeInBytes(MessageWrapper message) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(message);
    oos.close();
    return baos.size();
}
于 2012-01-16T10:16:23.167 に答える
1

@AlexR による以前のコメントに加えて、BytesMessage には getBodyLength() メソッドがあります。

http://download.oracle.com/javaee/1.4/api/javax/jms/BytesMessage.html#getBodyLength

また、Session.createMessage() を使用して作成されたいくつかのオブジェクト (つまり、ペイロードのない JMS メッセージ タイプ) をキャプチャすることで、転送中の典型的なヘッダー サイズを見積もることができます。帯域幅が重要な場合は、BytesMessage を使用して byte[] のペイロードを直接操作し、ZipOutputStream を介して圧縮したくなると思います。さらに、JMS では、ヒントでメッセージのタイムスタンプとメッセージ ID を抑制することができます。これにより、メッセージ サイズの削減に役立つ場合があります。

http://download.oracle.com/javaee/1.4/api/javax/jms/MessageProducer.html#setDisableMessageTimestamp%28boolean%29

プロバイダーはそれをサポートする必要はありませんが、

JMS プロバイダーがこのヒントを受け入れる場合、これらのメッセージのメッセージ ID を null に設定する必要があります。プロバイダーがヒントを無視する場合、メッセージ ID は通常の一意の値に設定する必要があります

私は以前、どこでも WebSphere MQ で非常に帯域幅が制限された JMS を使用していました。この方法でメッセージ サイズをかなり小さくすることができましたが、その場合、ネイティブのワイヤーフレーム形式もサイズに対して最適化されていました。

于 2011-08-17T14:05:36.280 に答える