Потребитель не получает сообщения от ActiveMQ

мы столкнулись со случайной проблемой с ActiveMQ и его потребителями. Мы наблюдаем, что немногие потребители не получают сообщения, даже если они подключены к очереди ActiveMQ. Но он отлично работает после перезапуска потребителя.

У нас есть очередь с именем testQueue на стороне ActiveMQ. Потребитель пытается де-очередь сообщений из этой очереди. Для этой цели мы используем Spring DefaultMessageListenerContainer. Сообщение доставляется на узел потребителя из ActiveMQ Брокер. Из tcpdump также было очевидно, что сообщение достигает узла потребителя, но фактический код потребителя не может видеть сообщение. Другими словами, сообщение, Похоже, застряло либо в потребительском коде ActiveMQ, либо в DefaultMessageListenerContainer Spring.

см. ниже Рис. для большей ясности по этому вопросу. Сообщение достигает потребительского узла, но не достигает "фактического потребительского класса", что означает, что сообщение застряло либо в AMQ код потребителя или весна DMLC.

enter image description here

Ниже приведены данные, полученные от администратора ActiveMQ.

Имя Очереди /Ожидании-Сообщение-Граф /Потребитель-Граф /Сообщения-Очереди /Сообщения-Удалены Из Очереди testQueue /9 /1 /9 /0

Ниже приведены более подробные сведения.

подключения-код /Код /селектор /помещает /извлекает /передается /отправляется-очереди /предвыборки ID:bearsvir52-45176-1375519181268-3:5 /1 / /9 /0 /9 /9 /250

из второй таблицы очевидно, что сообщения доставляются потребителю, но потребитель не признавая сообщение. Следовательно, сообщения застряли в отправленной очереди на стороне брокера.

несколько очков для вашего уведомления:

1) нет разницы во времени между узлом брокера b/w и узлом потребителя.

2) наблюдал tcpdump на стороне потребителя. Мы видим, что пакет MessageDispatch(Openwire) передается в потребительский узел, но не смог найти MessageAck (Openwire) для того же самого.

3) Иногда он работает на узле, а иногда создает проблему на том же узле.

2 ответов


потребовалось много времени, чтобы выяснить решение. Кажется, есть какая-то проблема с org.апаш.в частности, ActiveMQ.ActiveMQConnection.java класс, в случае сбоя AMQ. В таких случаях объект подключения не запускается на стороне потребителя.

следующие исправления я добавил в ActiveMQConnection.java-файл и скомпилированные источники для создания activemq-core-x.x.x.jar

private final Object startMutex = new Object();

добавлена проверка в createSession метод

public Session createSession(boolean transacted, int acknowledgeMode) throws JMSException {
    synchronized (startMutex) {
        if(!isStarted()) {
            start();
        }
    }

одной из причин этого может быть неправильно используете CachingConnectionFactory (с кэшированными потребителями) с контейнером прослушивателя, который динамически настраивает потребителей (max consumers > consumers). Вы можете в конечном итоге кэшированный потребитель просто сидит в пуле и не активно используется. Вам никогда не нужно кэшировать потребителей с помощью контейнера прослушивателя.

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