2011-08-17 10 views
7

私は現在、JMS(SpringフレームワークJMSとアクティブMQ)を使用するアプリケーションのための帯域幅制限機能(なぜか、私の決定ではないと私に尋ねないでください)クライアント。JMSメッセージのサイズ

私は、着信JMSメッセージを制限するための多くの調整方法(実際の帯域幅の負荷に基づいていない)を見つけましたが、送信メッセージフローを制限する方法はありませんでした。だから私は自分でLeaky bucket algorithmと書くことに決めました。

JMSメッセージのサイズを取得する方法はありますか。 Javaの 'sizeof'実装以外(In Java, what is the best way to determine the size of an object?

+0

なぜActiveMQでは、宛先でproducerFlowControlとmemoryLimitsを使用することができますか。私はなぜあなたが発信メッセージを制限したいのか知りたいのです。さらに、この種のものは、あなたのブローカーの前に座っている何らかの種類のアプリケーション配信コントローラー(あなたがそのオプションを持っていると仮定して)からより良く制御されないでしょう。 – whaley

+0

私たちの顧客は、生産者からの発信帯域幅を制限したいとします(たとえば、顧客は100 mbitの帯域幅を持っていますが、わずか10 mbitを使用したいとします)。それは私を夢中にさせる。 JMSはできるだけ早くメッセージを配信するように作られているので、私はその要求を本当に理解していません。しかし、悲しいことに、それは私の決断ではない。 – Sorceror

答えて

3

JMSメッセージは送信プロセスでシリアル化されるため、メッセージのサイズを取得する最も良い方法はthrough 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(); 
} 
4

JMSメッセージのサイズを判断するために、シリアライズされたサイズを測定するよりも、まったく優れているとは思いません。

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

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

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

+0

+1を考えてみるといいアイデアのために。 – Sorceror

1

を、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 Everyplaceの上で非常に帯域幅が制限されたJMSで働いていた、そしてメッセージのサイズがかなり小さな取得することが可能でしたこの方法ではネイティブのワイヤフレームフォーマットもサイズに合わせて最適化されましたが、

+0

帯域幅は重要ではなく、私たちの顧客はスループットを管理したいだけです。 +1は 'getBodyLength()'に対してですが、私はこれが 'BytesMessage'インスタンスに対してのみ動作することを肯定しています。 – Sorceror

関連する問題