EJBException: не удалось получить семафор пула - PullRequest
3 голосов
/ 10 августа 2011

Иногда я получаю следующее исключение EJB для нескольких различных bean-компонентов, управляемых сообщениями:

javax.ejb.EJBException: Failed to acquire the pool semaphore, strictTimeout=10000

Это поведение близко соответствует тому, когда у конкретной базы данных возникают проблемы, и, следовательно, увеличивает количество времени, затрачиваемого на функцию MDB onMessage. Сообщения доставляются брокером ActiveMQ (версия 5.4.2). Предварительная выборка на MDB составляет 2000 (20 сеансов x 100 сообщений за сеанс).

Мой вопрос общий. Что именно здесь происходит? Я знаю, что сообщение, доставленное на сервер, на котором работает MDB, истечет через 10 секунд, если в пуле компонентов не будет экземпляра для его обработки, однако как это сообщение было доставлено на сервер? До этого момента я предполагал, что MDB запрашивает сообщения у брокера в количестве, только если у него больше нет сообщений для обработки. Они просто слишком долго ждут в этом серверном «ведре»?

Кто-нибудь еще сталкивался с этим? Предложения по настройке времени ожидания предварительной выборки / семафора?

РЕДАКТИРОВАТЬ: Забыл упомянуть, что я использую JBoss AS 5.1.0

Ответы [ 2 ]

10 голосов
/ 26 августа 2011

После некоторых исследований я нашел удовлетворительное объяснение этому исключению EJB.

У MessageDrivenBeans есть пул экземпляров.Когда пакет сообщений JMS доставляется в MDB в количестве предварительной выборки, каждому из них назначается экземпляр из этого пула, и они доставляются этому экземпляру с помощью функции onMessage.

Немного о том, как этот пулработает: в JBoss 5.1.0 объединенные в пул bean-компоненты, такие как MDB и SessionBeans, настраиваются по умолчанию через JBoss AOP, в частности файл в каталоге развертывания с именем "ejb3-interceptors-aop.xml".Этот файл создает привязки перехватчиков и аннотации по умолчанию для любого класса, соответствующего его домену.В случае домена, управляемого сообщениями, помимо прочего, аннотация org.jboss.ejb3.annotation.Pool:

<annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.Pool)">
     @org.jboss.ejb3.annotation.Pool (value="StrictMaxPool", maxSize=15, timeout=10000)
</annotation>

Параметры этой аннотации описаны здесь .

Здесьложь руб.Если предварительная выборка сообщения превышает maxSize этого пула (что обычно происходит для приложений обмена сообщениями с высокой пропускной способностью), у вас обязательно будут сообщения, ожидающие экземпляра MDB. Если время от доставки сообщения до вызова onMessage превышает время ожидания пула для любого сообщения, будет выдано исключение EJBException. Это может не быть проблемой для первых нескольких итераций распространения сообщения, но если у вас естьбольшая предварительная выборка и большое среднее время сообщения, сообщение к концу очереди начнет давать сбой.

Некоторая быстрая алгебра показывает, что это произойдет, грубо говоря, когда

timeout < (prefetch x onMessageTime) / maxSize

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

Решение этой проблемы более субъективно.Простое увеличение времени ожидания является наивным вариантом, поскольку оно маскирует тот факт, что сообщения находятся на вашем сервере приложений, а не в вашей очереди.Учитывая, что время onMessage несколько фиксировано, уменьшение предварительной выборки, скорее всего, является хорошим вариантом, так как увеличивает размер пула, если позволяют ресурсы.При настройке этого я уменьшил время ожидания в дополнение к существенному уменьшению предварительной выборки и увеличению maxSize, чтобы держать сообщения в очереди дольше, сохраняя при этом мой индикатор оповещения, когда время onMessage выше, чем обычно.

0 голосов
/ 11 марта 2014

То, что говорит Джпредхам, верно. Также, пожалуйста, проверьте, если

'strictMaximumSize' установлен в true

, что может привести к https://issues.jboss.org/browse/JBAS-1599

...