Почему я должен использовать JMS, а не RMI+Queue?


В данный момент я использую RMI или hessian library для связи между моим сервером и клиентами (через LinkedBlockingQueue). Теперь я читаю о JMS, которые могут быть использованы и в этой области. Это правильно? Если да, не могли бы вы дать мне простой список преимуществ/недостатков, потому что это, кажется, довольно сложная и "полномасштабная" область.

Каковы преимущества? А как насчет производительности по сравнению с RMI + Queue? Может ли JMS победить RMI+очередь?

PS: Я знаю, что есть подобные вопросы , но я хотел бы иметь JMS по сравнению с RMI+Queue.

5 8

5 ответов:

Упрощенное сравнение было бы (не особенно для JMS, больше похоже на сравнение с MQ в целом)...

  1. Автоматический повтор
    Если вы являетесь клиентом, выполняющим RMI для сервера, и по какой-то причине RMI терпит неудачу, вы должны попробовать еще раз. Если бы вы использовали JMS, и вы являетесь клиентом, вы бы просто отправили сообщение JMS. Когда сервер не может быть достигнут, ваше сообщение будет сохранено, а затем доставлено, когда сервер снова заработает.

  2. Постоянная очередь
    С вы используете LinkedBlockingQueue, вы можете иметь либо ограниченную очередь, либо неограниченную очередь в памяти. Первый начнет перехватывать потоки, как только очередь заполнится, и в конечном итоге выйдет из строя при высокой нагрузке. Позже, в конечном итоге, вместо того, чтобы бросать исключение OutOfMemoryError. Однако если вы используете JMS, он может автоматически начать "сохранять" сообщения в "постоянное хранилище". Обычно "постоянным хранилищем" является БД, которая обычно имеет гораздо большую емкость, чем очередь в памяти. Конечно, содержание в памяти очередь теряется, когда сервер выходит из строя и т. д., в то время как в JMS вы можете выбрать долговременное сообщение/постоянное сообщение, которое переживает такое событие. Это также позволяет иметь кластеризацию, что также очень важно для корпоративных программ...

  3. Абстракция
    Вы будете использовать стандартизированный API (хорошо, у вас есть протоколы и в RMI, но если вы хотите передавать сообщения, MQ обеспечивает гораздо более высокий уровень абстракции, чем RMI+in-memory queue). Что означает, вы получаете возможность использовать будущие реализации JMS.. Возможно, что-то, что не нуждается в БД для обеспечения долговечности и постоянства, более масштабируемое, чем сегодняшняя реализация и т. д. Или, может быть, вы можете отправить то же самое сообщение в совершенно другой сервис, из-за стандартизации. В принципе, более высокая абстракция может дать вам гибкость, чего RMI+in-memory queue не делает.

Некоторое время назад я работал с большой компанией, которая хотела использовать их внутреннюю структуру для интеграции нашего материала. Около в тот раз мы не использовали MQ. Мы попросили их использовать наш собственный асинхронный протокол, основанный на RMI. Поверьте, мы очень, очень сожалели об этом решении...

Другие ответы охватывают многие аспекты JMS, но я чувствую, что очень важный из них нуждается в большем акценте, а именно тот факт, что JMS поддерживает несколько одновременных потребителей в транзакционном способе. Это для меня функция Убийцы.

  1. Вы можете легко построить систему с единственным потребителем и производителем, который не является транзакционным.
  2. вы также можете сделать его (более или менее) транзакционным с немного большей работой.
  3. аналогичным образом можно добавить поддержку для нескольких производителей и одного потребителя относительно легко, например, если вы используете транзакционную базу данных для хранения сообщения.
  4. Но становится очень трудно иметьнесколько одновременных потребителей и иметь потребление сообщений транзакционным. Это в основном требует нетривиальной схемы блокировки, и даже с использованием транзакционной базы данных задача не из легких.

Когда мы говорим о JMS масштабируемости , мы, однако, говорим об этом: способность приложение. сервер для добавления / удаления потребителя / производителя для управления нагрузкой.

Другими преимуществами JMS являются качество обслуживания и управления, например, попытка повторной доставки, очередь мертвых сообщений, мониторинг и т. д.

Если вам это действительно не нужно, может сработать несколько более простое решение. Вы также можете увидеть другой мой ответ, где я освещаю аналогичный вопрос: почему выбор JMS для асинхронного решения ?

Что вы используете для части вашего решения" очередь"? Твой собственный код?

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

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

Простой RMI плохо масштабируется или имеет дело с проблемами надежности, хорошая система массового обслуживания может быть как масштабируемой, так и гибкой.

Я думаю, что справедливо сказать, что JMS и остальная часть Java EE предназначена для того, чтобы ваше приложение было корпоративного качества. Первоначально я думал, что Java EE overal была сложной, хотя я думал, что JMS был одним из более простых углов. Сегодня я не уверен, что написать RMI + свою собственную очередь проще, чем просто использовать JMS.

Возможно, существенная разница заключается в том, что использование JMS в значительной степени предполагает наличие некоторой инфраструктуры, такой как сервер приложений.

JMS является транзакционной, может координироваться с транзакциями базы данных.
JMS разъединяет производителей и потребителей, то есть им не нужно работать одновременно.
JMS-это гарантированная доставка, то есть сообщения гарантированно попадают туда в случае сбоя (в зависимости от типа сбоя может потребоваться кластеризация).
JMS может выполнять синхронные, асинхронные операции точка-точка, а также публиковать/подписываться.
Большинство реализаций JMS используют систему массового обслуживания, которая может работать с другими языками, операционками.

' автоматическая повторная попытка Если вы являетесь клиентом, выполняющим RMI для сервера, и по какой-то причине RMI терпит неудачу, вы должны попробовать еще раз. Если бы вы использовали JMS, и вы являетесь клиентом, вы бы просто отправили сообщение JMS. Когда сервер не может быть достигнут, ваше сообщение будет сохранено, а затем доставлено, когда сервер снова заработает. '

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

Если вы попытаетесь отправить сообщение брокеру, который недоступен, то вы должны получить исключение JMSException, и в этом смысле ваши клиентские сообщения могут быть потеряны, если ваше приложение не сделает некоторого условия, чтобы сохранить их самостоятельно и повторить попытку. В этом смысле клиент к серверу JMS ведет себя так же, как клиент к серверу RMI. Вы все равно потеряете сообщение, если этот сервер не работает.