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

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

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

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

3 ответов


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

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

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

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


поскольку сообщения 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();
}

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

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

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

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

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

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

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