JMS message size

被刻印的时光 ゝ 提交于 2019-12-08 17:18:45

问题


I'm currently working on bandwidth limiting feature (don't ask me why, its not my decision) for application which use JMS (Spring framework JMS and Active MQ namely) to sending messages with payload between server and clients.

I found lot of throttling methods to limit incoming JMS messages (but none of them based on actual bandwidth load), however I didn't find any possible way to limit outgoing message flow. So I decided to write Leaky bucket algorithm on my own.

Is there some way how to obtain size of JMS message? Other than 'sizeof' implementation in Java (In Java, what is the best way to determine the size of an object?)


回答1:


I do not think that you have any seriously better alternative to determine the JMS message size than measuring of its serialized size.

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

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

I think that implementation of leaky bucket using JMS may be simplified if you are using hidden feature of most JMS providers to send delayed messages. You can measure the message when enqueueing it and decide when do you want the subscriber to receive it. Please read here for details of how to send delayed messages: http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html




回答2:


Because JMS messages are serialized in sending process, the best way how to obtain size of message is 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();
}



回答3:


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 typical header size in transit by capturing a few objects created using Session.createMessage() - i.e. the JMS message type with no payload. I think i'd be tempted to work directly with a payload in a byte[], using a BytesMessage, and compress via a ZipOutputStream if bandwidth is critical. In addition, JMS allows hints to suppress message timestamp and message id, which may help reduce message size e.g.

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 hint, these messages must have the message ID set to null; if the provider ignores the hint, the message ID must be set to its normal unique value

I once worked with very bandwidth-limited JMS on WebSphere MQ everyplace, and it was possible to get the message size pretty small in this way - although the native wireframe format was also optimised for size in that case



来源:https://stackoverflow.com/questions/7090028/jms-message-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!