JMS message size

I am currently working on a bandwidth limiting function (don't ask me why this is not my solution) for an application that uses JMS (Spring framework JMS and Active MQ specifically) to send messages with payload between the server and clients.

I found many throttling methods to restrict incoming JMS messages (but none of them are based on the actual bandwidth load), however I did not find a possible way to limit the outgoing message flow. So I decided to write the Leaky bucket algorithm myself.

Is there a way to get the size of a JMS message? Except for the implementation of 'sizeof' in Java ( In Java, what is the best way to determine the size of an object? )

+7
source share
3 answers

Because JMS messages are serialized during the sending process, the best way to get the message size is through an 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(); } 
+3
source

I don’t think you have a good alternative for determining the size of a JMS message than measuring its serialized size.

But you can add some optimizations if you want. There are several types of messages (for example, MapMessage, ObjectMessage, TextMessage).

The size of a text message is the length of its text. The size of a map message is the total size of all its fields. Fields are primitives or java.util.Date, so it does not bother to measure them. The object message contains a serializable object, so you can measure its size by writing to ByteOutputStream.

I think that implementing a leaking bucket using JMS can be simplified if you use the hidden function of most JMS providers to send pending messages. You can measure the message when queuing and decide when you want the subscriber to receive it. Please read here to learn how to send pending messages: http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html

+4
source

In addition to the earlier comment by @AlexR, BytesMessage has a getBodyLength () method

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

and you can probably estimate the typical size of the header in the path by capturing several objects created using Session.createMessage () - that is, a JMS message type without a payload. I think I will be tempted to work directly with the payload in byte [] using BytesMessage and compress via ZipOutputStream if the bandwidth is critical. In addition, JMS allows hints to suppress message timestamps and message identifiers, which can help reduce message size, for example.

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

although providers are not required to support it,

If the JMS provider accepts this prompt, these messages must have a message identifier of null; if the provider ignores the prompt, the message identifier must be set to its usual unique value

I once worked with bandwidth-limited JMS in WebSphere MQ, and it was possible that the message size was quite small, although the wireframe format was also optimized for size in this case

+1
source

All Articles