我目前正在研究带宽限制功能(不要问我为什么,这不是我的决定),用于使用JMS(即Spring框架JMS和Active MQ)在服务器和客户端之间发送带有有效负载的消息的应用程序。
我发现了许多限制传入JMS消息的节流方法(但没有一种是基于实际带宽负载的),但是我没有找到任何限制传出消息流的可能方法。所以我决定自己写Leaky bucket algorithm。
**有没有办法获取JMS消息的大小?**除了Java中的“sizeof”实现之外(In Java, what is the best way to determine the size of an object?)
3条答案
按热度按时间a7qyws3x1#
我不认为您有比测量其序列化大小更好的替代方法来确定JMS消息大小。
但是如果你愿意的话,你可以添加一些优化。有几种类型的消息(例如,MapMessage、ObjectMessage、TextMessage)。
文本消息的大小是其文本的长度。map消息的大小是其所有字段的总大小。这些字段都是原语或java.util.Date,所以度量它们不是问题。对象消息包含可序列化的对象,因此您可以通过写入ByteOutputStream来测量其大小。
我认为,如果您使用大多数JMS提供程序的隐藏功能来发送延迟消息,那么使用JMS实现漏桶可能会得到简化。您可以在接收消息时测量消息,并决定您希望订阅者何时接收消息。有关如何发送延迟消息的详细信息,请阅读此处:http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html
7jmck4yq2#
由于JMS消息在发送过程中是序列化的,因此获取消息大小的最佳方法是through ObjectOutputStream。
s8vozzvw3#
除了@AlexR之前的评论之外,BytesMessage还有一个getBodyLength()方法
http://download.oracle.com/javaee/1.4/api/javax/jms/BytesMessage.html#getBodyLength
您可以通过捕获使用Session. Message()创建的一些对象来估计传输中的典型头大小-即没有有效负载的JMS消息类型。我想我会尝试直接使用byte[]中的有效负载,使用BytesMessage,如果带宽很关键,则通过ZipOutputStream进行压缩。此外,JMS允许隐藏消息时间戳和消息ID的提示,这可能有助于减少消息大小,例如
http://download.oracle.com/javaee/1.4/api/javax/jms/MessageProducer.html#setDisableMessageTimestamp%28boolean%29
尽管不要求提供商支持它,
如果JMS提供者接受此提示,则这些消息必须将消息ID设置为空;如果提供程序忽略提示,则必须将消息ID设置为其正常的唯一值
我曾经在WebSphere MQ上的任何地方使用带宽非常有限的JMS,通过这种方式可以使消息的大小非常小-尽管在这种情况下本机线框格式也针对大小进行了优化