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

Я пытаюсь проверить устойчивость очереди ActiveMQ.

У меня есть встроенный сервер ActiveMQ с уникальным потребителем. Этот встроенный сервер получает сообщения JMS от многих других приложений JVM.

Работает нормально, пользовательское приложение получает уведомления.

Итак, я попытался проверить устойчивость сообщений. Я установил (удаленную) точку останова на MessageListener потребителя, чтобы я мог поставить в очередь много сообщений и вызвать сбой сервера ActiveMQ. При перезапуске сервера я бы хотел, чтобы все помещенные в очередь сообщения можно было использовать, а не терять.

А потом я попробовал этот тест. Я попал в эту точку останова при первой отправке сообщения. Но для всех сообщений, которые я пытаюсь отправить, я получаю следующий стек на стороне производителя:

Exception in thread "main" org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is javax.jms.JMSException: Wire format negotiation timeout: peer did not send his wire format.
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
    at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:168)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:469)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:534)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:612)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:604)
    at com.xxxxxxxxxxx.mobilepush.client.RealClientTest.main(RealClientTest.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: javax.jms.JMSException: Wire format negotiation timeout: peer did not send his wire format.
    at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62)
    at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1380)
    at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1466)
    at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnection.java:308)
    at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:196)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:457)
    ... 9 more
Caused by: java.io.IOException: Wire format negotiation timeout: peer did not send his wire format.
    at org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:98)
    at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:68)
    at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:81)
    at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:86)
    at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1351)
    ... 13 more

Я не понимаю, почему мой производитель будет заблокирован, когда мой потребитель находится в моей точке останова.

URI моего брокера: mobilepush.activemq.broker.transport.connector.uri=tcp://0.0.0.0:61616

Производитель подключается через tcp к брокеру. Потребитель, находящийся вместе с брокером, подключается через vm://localhost.


Моя конфигурация довольно проста:

SERVER:

    <!--  lets create an embedded ActiveMQ Broker -->
    <amq:broker useJmx="false" persistent="true">
        <amq:transportConnectors>
            <amq:transportConnector uri="${mobilepush.activemq.broker.transport.connector.uri}" />
        </amq:transportConnectors>
        <amq:persistenceAdapter>
            <amq:kahaPersistenceAdapter directory="${mobilepush.activemq.broker.queue.persistence.directory}" maxDataFileLength="100 Mb"/>
        </amq:persistenceAdapter>
    </amq:broker>

CONSUMER:
(management namespace and xebia class it only a JMX decorator)

<bean id="connectionFactory" class="fr.xebia.management.jms.SpringManagedConnectionFactory">
        <property name="connectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory" >
                <property name="brokerURL" value="${mobilepush.activemq.broker.uri}"/>
            </bean>
        </property>
    </bean>

    <bean id="pushConsumer" class="com.xxxxxxxxxxxxxxx.mobilepush.messaging.jms.PushConsumer">
        <property name="jmsPushMessageConverter" ref="jmsPushMessageConverter"/>
        <property name="pushDelegate" ref="directPushDelegate"/>
    </bean>

    <management:executor-service id="pushConsumerExecutor"
                                 pool-size="${mobilepush.consumer.thread.min}-${mobilepush.consumer.thread.max}" keep-alive="60" />

    <jms:listener-container
            task-executor="pushConsumerExecutor"
            connection-factory="connectionFactory"
            acknowledge="auto"
            container-class="fr.xebia.springframework.jms.ManagedDefaultMessageListenerContainer">
        <jms:listener destination="mobilepush.queue" ref="pushConsumer" method="onMessage" />
    </jms:listener-container>

PRODUCER:

    <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"  >
        <property name="brokerURL" value="${mobilepush.activemq.broker.uri}"/>
    </bean>


    <bean id="mobilePushJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="defaultDestination" ref="mobilePushQueue"/>
        <property name="messageConverter" ref="jmsPushMessageConverter"/>
        <property name="connectionFactory">
            <!-- lets wrap in a pool to avoid creating a connection per send -->
            <bean class="org.springframework.jms.connection.SingleConnectionFactory">
                <property name="targetConnectionFactory">
                    <ref local="connectionFactory" />
                </property>
            </bean>
        </property>
    </bean>

person Sebastien Lorber    schedule 04.09.2012    source источник


Ответы (4)


Я нашел проблему!

Удаленная точка останова, которую я установил для своего встроенного потребителя ActiveMQ, была точкой останова по умолчанию с suspend-policty = all.

И поскольку потребитель и сервер работают на одной и той же JVM, я также приостанавливал все потоки сервера ActiveMQ!

Решение состоит в том, чтобы использовать точку останова suspend-policy = thread, чтобы только поток потребителя был приостановлен, а потоки сервера могли продолжать работу.

person Sebastien Lorber    schedule 05.09.2012

"java.io.IOException: Wire format negotiation timeout: peer did not send his wire format" кажется довольно ясным. вы блокируете клиентский поток, который является другим концом сетевого подключения. сервер получает сетевые тайм-ауты, пытаясь взаимодействовать с клиентом. сетевые соединения - это ситуация, когда сложно отлаживать произвольную приостановку потока.

person jtahlborn    schedule 04.09.2012
comment
Да, я понимаю, но пока потребитель занят, разве мы не должны иметь возможность отправлять сообщения ??? Предполагается, что клиентский поток будет выполняться в пуле потоков, который я предоставил, так почему, черт возьми, он заблокирует отправителя ??? - person Sebastien Lorber; 04.09.2012
comment
@SebastienLorber - не знаю, возможно, сервер activemq однопоточный. - person jtahlborn; 04.09.2012

Брокер activemq будет ждать несколько секунд, пока клиент отправит формат провода, прежде чем принудительно отключиться. В URL-адрес вашего подключения попробуйте добавить следующий параметр, чтобы увеличить это время до того, что позволит вам выполнять отладку:

tcp://localhost:61616?wireFormat.maxInactivityDurationInitalDelay=30000 

Целочисленное значение - это количество миллисекунд ожидания.

person jkysam    schedule 04.09.2012
comment
Я знаю, читайте об этом на странице ActiveMQ. Я пробовал, и это только вызывает исключение на 20 секунд позже, чем раньше ... - person Sebastien Lorber; 05.09.2012

Я исправил эту проблему, используя последнюю версию jar-файла logback-core и logback-classic - 1.1.2.

person Ker p pag    schedule 09.07.2014