Java JMS - как обрабатывать большое количество пунктов назначения без параллелизма для каждого пункта назначения - PullRequest
0 голосов
/ 19 июля 2011

Я ищу совет по архитектуре на основе JMS ...

Моему приложению необходимо получать сообщения JMS от имени тысяч различных пунктов назначения, а затем доставлять их в пункты назначения по протоколам, отличным от JMS (т. Е. Это шлюз). Допустимые решения - для всех сообщений, изначально отправленных в одну очередь JMS, или для перехода в одну очередь на пункт назначения.

Решения должны хорошо работать с таким большим количеством пунктов назначения (и большим количеством сообщений в секунду).

Требования:

  1. Во время доставки сообщения в один пункт назначения никакое другое сообщение не может быть обработано для этого пункта назначения.
  2. Сообщения должны быть доставлены FIFO по назначению на основе того, когда они были отправлены в JMS
  3. Ни один не может быть потерян (семантика транзакции JMS адекватна)
  4. Поставки должны выполняться параллельно нескольким адресатам (кроме параллелизма по пунктам назначения)
  5. Существует несколько идентичных экземпляров приложения на разных машинах, которые реализуют это, и все они работают одновременно. Они могут общаться через общий кеш или JMS, но связь должна быть простой и минимальной.
  6. Шлюз будет находиться в контейнере J2EE, но для использования MDB

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 20 июля 2011

@ Mesocyclone: ​​Исходя из данных вашего вопроса и решения, предоставленного Moe выше, это то, что я могу порекомендовать возможное решение, которое вы ищете.

Вы можете ввести одну очередь на пункт назначения внутри вашего шлюзаприложение, а именнопример dest1queue, dest2queue и так далее, и только одна входная очередь предоставляется для получения сообщения.Вы можете иметь один поток MDB, слушающий каждую из этих внутренних очередей, развернутых на другом сервере.Например, dest1queue прослушивается MDB (однопоточным) на сервере server1, dest2queue прослушивается MDB (однопоточным) на server2, dest3queue прослушивается MDB (однопоточным) на server3 ...

Так что в основном поток будетбыть: -

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

Преимущество вышеуказанного дизайна будет:

  1. Может быть, каждая внутренняя очередь прослушивается потоком MDB, развернутым на разных серверах, так что каждый поток MDB получает максимальное время обработки.
  2. В любой момент времени вы можете изменить номерпотоков, прослушивающих один пункт назначения без влияния на другие.
  3. Однако приведенный выше дизайн требует наличияСоздайте резервную копию сервера MDB для каждой из внутренних очередей, чтобы избежать SPOF.Возможно, ваш сервер, на котором вы развертываете приложение, предоставляет некоторую возможность переключения при сбое.
1 голос
/ 19 июля 2011

Похоже, вы могли бы использовать одну очередь на пункт назначения для доставки сообщений от разных издателей к шлюзу. В этом случае шлюз должен быть многопоточным, с одним потоком на потребителя очереди. Таким образом, для x числа производителей, публикующих по n адресатам, шлюзу потребуется n потоков, по одному на адресат. Эта архитектура обеспечит вам пропускную способность, которая зависит от того, сколько обработки шлюз должен выполнить с сообщением, прежде чем оно переадресует его в конечный пункт назначения, и сколько времени потребуется для обработки сообщения конечным пунктом назначения до шлюза. Можно отправить следующее сообщение.

У этого дизайна есть 2 недостатка:

  1. У ваших приложений будет одна точка отказа - шлюз. Вы не сможете сбалансировать его, потому что для вас важен порядок потребления, поэтому вы не хотите, чтобы 2 шлюза истощали одну и ту же очередь.
  2. Каждая очередь потенциально может стать узким местом, засоряя сообщения, которые обрабатываются недостаточно быстро.

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

Другой выбор, который у вас есть, - выполнить пакетную обработку. В любой конкретный момент времени потребитель выгружает все доступные сообщения в очереди и обрабатывает их сразу. Это означает, что вам придется выполнять синхронное потребление сообщений (Consumer # receive ()), а не асинхронное потребление с onMessage.

...