JMS消息大小

时间:2011-08-17 08:46:31

标签: java spring jms activemq bandwidth-throttling

我目前正在研究带宽限制功能(不要问我为什么,这不是我的决定)对于使用JMS(Spring框架JMS和Active MQ)在服务器和客户端之间发送带有效负载的消息的应用程序。 / p>

我发现很多限制方法来限制传入的JMS消息(但没有基于实际的带宽负载),但是我没有找到任何限制传出消息流的方法。所以我决定自己写Leaky bucket algorithm

有没有办法获取JMS消息的大小?除了Java中的'sizeof'实现(In Java, what is the best way to determine the size of an object?

3 个答案:

答案 0 :(得分:4)

我认为您没有比测量其序列化大小更好的替代方法来确定JMS消息大小。

但如果您愿意,可以添加一些优化。有几种类型的消息(例如MapMessage,ObjectMessage,TextMessage)。

短信的大小是其文本的长度。地图消息的大小是其所有字段的总大小。字段是基元或java.util.Date,因此测量它们不是问题。 对象消息包含可序列化对象,因此您可以通过写入ByteOutputStream来测量其大小。

如果您使用大多数JMS提供程序的隐藏功能来发送延迟消息,我认为使用JMS实现漏桶可能会简化。您可以在排队时测量消息,并确定您希望订户何时接收消息。 有关如何发送延迟消息的详细信息,请阅读此处:http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html

答案 1 :(得分: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();
}

答案 2 :(得分:1)

除了@AlexR早期的评论之外,BytesMessage还有一个getBodyLength()方法

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

并且您可以通过捕获使用Session.createMessage()创建的一些对象(即没有有效负载的JMS消息类型)来估计传输中的典型标头大小。我想我很想直接使用字节[]中的有效负载,使用BytesMessage,如果带宽很重要,则通过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,并且可以通过这种方式使消息大小非常小 - 尽管在这种情况下本机线框格式也针对大小进行了优化