Размер сообщения JMS - PullRequest
       18

Размер сообщения JMS

7 голосов
/ 17 августа 2011

В настоящее время я работаю над функцией ограничения пропускной способности (не спрашивайте меня, почему, это не мое решение) для приложения, которое использует JMS (Spring Framework JMS и Active MQ, а именно) для отправки сообщений с полезной нагрузкой между сервером и клиентами.

Я нашел множество методов регулирования для ограничения входящих сообщений JMS (но ни один из них не основан на фактической загрузке полосы пропускания), однако я не нашел никакого возможного способа ограничения потока исходящих сообщений. Поэтому я решил написать алгоритм Leaky Bucket самостоятельно.

Есть ли какой-нибудь способ, как получить размер сообщения JMS? Кроме реализации 'sizeof' в Java ( В Java, какой лучший способ определить размер объекта? )

Ответы [ 3 ]

4 голосов
/ 17 августа 2011

Я не думаю, что у вас есть какая-либо более серьезная альтернатива для определения размера сообщения JMS, чем измерение его сериализованного размера.

Но вы можете добавить некоторые оптимизации, если хотите.Существует несколько типов сообщений (например, MapMessage, ObjectMessage, TextMessage).

Размер текстового сообщения - это длина его текста.Размер сообщения карты - это общий размер всех его полей.Поля являются примитивами или java.util.Date, поэтому их измерение не является проблемой.Сообщение объекта содержит сериализуемый объект, поэтому вы можете измерить его размер, записав в ByteOutputStream.

Я думаю, что реализация утечек, использующих JMS, может быть упрощена, если вы используете скрытую функцию большинства провайдеров JMS для отправки отложенных сообщений.Вы можете измерить сообщение при постановке в очередь и решить, когда вы хотите, чтобы подписчик получил его.Пожалуйста, прочитайте здесь, чтобы узнать, как отправлять отложенные сообщения: http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html

3 голосов
/ 16 января 2012

Поскольку сообщения JMS сериализуются в процессе отправки, лучший способ получения размера сообщения - через 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();
}
1 голос
/ 17 августа 2011

В дополнение к более раннему комментарию @AlexR, BytesMessage имеет метод getBodyLength ()

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

, и вы, вероятно, можете оценить типичный размер заголовка при передаче, захватив несколько объектовсозданный с использованием Session.createMessage () - то есть тип сообщения JMS без полезной нагрузки.Я думаю, что у меня возникнет соблазн работать с полезной нагрузкой в ​​байте [], используя BytesMessage, и сжимать с помощью ZipOutputStream, если пропускная способность критична.Кроме того, JMS позволяет подсказкам подавлять временную метку и идентификатор сообщения, что может помочь уменьшить размер сообщения, например,

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

, хотя поставщики не обязаны его поддерживать,

Если провайдер JMS принимает эту подсказку, для этих сообщений должен быть установлен нулевой идентификатор сообщения;если провайдер игнорирует подсказку, для идентификатора сообщения должно быть установлено его обычное уникальное значение

Однажды я работал с JMS с очень ограниченной пропускной способностью в WebSphere MQ везде, и было возможно получить размер сообщениятаким образом, довольно маленький - хотя собственный формат каркаса был также оптимизирован для размера в этом случае

...