Как и в случае всех прочих программных моделей, для использования программной модели с компонентами, управляемыми сообщениями, было разработано несколько оптимальных подходов. Эти методы рассматриваются ниже.
• Передавайте реализацию бизнес-логики другому обработчику.
Традиционно функция сеансовых компонентов без сохранения состояния (stateless session bean) состоит в формировании фасада для бизнес-логики. Компоненты, управляемые сообщениями, должны делегировать бизнес-логику, связанную с обработкой содержимого сообщений, не сохраняющему состояние сеансовому компоненту. Таким образом MDB-компоненты смогут сконцентрироваться на том, для чего они предназначены, т. е. на обработке сообщений. Это показано на рис. 8.17.
Рис. 8.17. Передача бизнес-логики сеансовому компоненту без сохранения состояния
Дополнительное преимущество такого подхода состоит в том, что бизнес-логика, заключенная в сеансовом компоненте без сохранения состояния может быть повторно использована другими EJB-клиентами. Это показано на рис. 8.18.
Рис. 8.18. Повторное использование бизнес-логики
• Не сохраняйте данные о состоянии, специфичные для клиента, в MDB-компоненте. Как уже говорилось ранее, экземпляры управляемых сообщениями компонентов не должны от имени клиента сохранять данные о взаимодействии. Это позволяет EJB-контейнеру работать с пулом экземпляров MDB-компонентов и выбирать из этого пула любой экземпляр для обработки входящего сообщения. Однако это не
предохраняет компонент, управляемый сообщениями, от сохранения данных о состоянии, не являющихся специфичным и для клиента, например ссылок на источники данных и ссылок на другие EJB.
• Избегайте создавать сообщения с большим телом.
JMS-сообщение в какой-то момент своей жизни будет передаваться через сеть. Оно наверняка будет обрабатываться JMS-провайдером. Все эти компоненты влияют на общую производительность и надежность системы. Объем данных, содержащихся в теле JMS-сообщения, следует свести к минимуму, чтобы избежать нагрузки на сеть JMS-провайдера.
• Сводите к минимуму время обработки сообщения.
Вспомните из обсуждения в разделе 8.4.4, «Жизненный цикл компонентов, управляемых сообщениями», что экземпляры MDB-компонентов извлекаются из пула компонентов для обработки входящих сообщений. Эти экземпляры не возвращаются в пул до тех пор, пока обработка не будет завершена. Следовательно, чем больше времени MDB-компонент будет обрабатывать сообщение, тем дольше он будет недоступен для повторного извлечения.
Если приложение должно обрабатывать большое количество сообщений, количество экземпляров MDB-компонентов в пуле может быстро уменьшаться, если каждое сообщение требует длительной обработки. EJB-контейнеру потребуется гораздо больше драгоценного процессорного времени на создание дополнительных экземпляров MDB-компонентов для пула, что еще больше повлияет на производительность приложения.
Особую осторожность следует соблюдать, если в ходе обработки сообщения в глобальной транзакции привлекаются другие ресурсы. EJB-контейнер не будет пытаться зафиксировать глобальную транзакцию до тех пор, пока метод onMessage MDB-компонента не завершит свою работу. А до тех пор, пока не будет зафиксирована глобальная транзакция, ресурсы в соответствующем менеджере ресурсов нельзя будет освободить.
По этим причинам время, затрачиваемое на обработку каждого сообщения, следует свести к минимуму.
• Избегайте зависимостей от порядка сообщений.
Старайтесь избегать в приложении предположений о том, в каком порядке будут обрабатываться JMS-сообщения. Это связано с тем, что серверы приложений разрешают параллельную обработку JMS-сообщений MDB-компонентами, и с тем, что одни сообщения обрабатываются дольше, чем другие. Следовательно, обработка сообщения, доставленного позже, может завершится до обработки сообщения, доставленного раньше. Существует возможность настроить сервер приложений так, чтобы порядок сообщений в приложении сохранялся, но это обычно достигается за счет производительности и архитектурной гибкости, например, за счет невозможности размещать приложение в кластере.
• Помните о «ядовитых» сообщениях.
Иногда в пункт назначения приходят JMS-сообщения с неверным форматом. Такое сообщение может привести к генерации исключения в MDB в ходе обработки.
После этого MDB-компонент, использующий контейнерно-управляемые транзакции, помечает транзакцию для отката, как это описывается в разделе 8.4.5, «Компоненты, управляемые сообщениями, и транзакции». EJB-контейнер производит откат транзакции, и это приводит к тому, что сообщение возвращается в очередь для повторной доставки. Однако при следующей доставке сообщения в MDB возникает та же проблема. В этой ситуации сообщение может приниматься и возвращаться в очередь снова и снова. Такие сообщения называются «ядовитыми» сообщениями (poison message). К счастью, в некоторых провайдерах систем обмена сообщениями реализованы механизмы, которые могут обнаруживать «ядовитые» сообщения и перенаправлять их в другой пункт назначения. Двумя такими провайдерами являются WebSphere MQ и сервисная интеграционная шина.