Удаленные подключения ActiveMQ отклонены, несмотря на 0.0.0.0 в URL-адресе брокера

У меня есть брокер ActiveMQ v5.7.0, работающий в Karaf v2.3.3, который я хочу включить для удаленных подключений. Я установил URL-адрес брокера на 0.0.0.0:61616, чтобы он мог прослушивать сетевой трафик. Я открыл брандмауэр, чтобы разрешить трафик с клиентских машин. Однако все удаленные подключения отклоняются. Быстрый netstat, кажется, говорит мне, что брокер не слушает за пределами локального хоста.

jeremy@server:~$ netstat -pan | grep 61616
tcp6       0      0 127.0.0.1:61616         :::*                    LISTEN      -               

Глядя на брокера через Hawtio, я понимаю, что URL-адрес выглядит так, как должен.

Transport connectors    Openwire: tcp://0.0.0.0:61616?maximumConnections=1000&wireformat.maxFrameSize=104857600

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

Брокер правильно реагирует на подключения с локального хоста.

2013-10-14 17:34:29 Connected to localhost:61613

Это ошибка, которую я получаю от удаленных подключений: -

Error connecting to xxx.xxx.xxx.xxx:61613: IO::Socket::INET: connect: Connection refused at /usr/local/share/perl/5.14.2/Net/Stomp.pm line 102.

EDIT: добавлен вывод telnet

Локальный порт 61613

jeremy@server:~$ telnet localhost 61613
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Порт удаленного подключения 61613

jeremy@other-server:~$ telnet xxx.xxx.xxx.xxx 61613
Trying xxx.xxx.xxx.xxx...
telnet: Unable to connect to remote host: Connection refused

Порт подключения Localhost 61616 (это интересно)

jeremy@server:~$ telnet localhost 61616
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
ðActiveMQ       Þ
MaxFrameSizÿÿÿ  CacheSize
CacheEnabledSizePrefixDisabled MaxInactivityDurationInitalDelay'TcpNoDelayEnabledMaxInactivityDurationu0TightEncodingEnabledStackTraceEnabledPuTTYConnection closed by foreign host.

Порт удаленного подключения 61616

jeremy@other-server:~$ telnet xxx.xxx.xxx.xxx 61616
Trying xxx.xxx.xxx.xxx...
telnet: Unable to connect to remote host: Connection refused

EDIT: добавлен вывод журнала karaf удаленного сервера.

2013-10-15 19:00:46,599 | ERROR | c.event.invited] | faultJmsMessageListenerContainer | .DefaultMessageListenerContainer  909 | 69 - org.springframework.jms - 3.2.4.RELEASE | Could not refresh JMS Connection for destination 'Consumer.notifications.VirtualTopic.event.invited' - retrying in 5000 ms. Cause: Error while attempting to add new Connection to the pool; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://xxx.xxx.xxx.xxx:61616. Reason: java.net.ConnectException: Connection refused

Вот файл broker.xml.

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
  xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
  xmlns:amq="http://activemq.apache.org/schema/core">

  <ext:property-placeholder />

  <broker xmlns="http://activemq.apache.org/schema/core"
    brokerName="jellyfish-messaging"
    dataDirectory="${karaf.data}/activemq/localhost"
    useShutdownHook="false"
    persistent="true"
    schedulerSupport="true"
    startAsync="true">

    <destinationPolicy>
      <policyMap>
        <policyEntries>
          <policyEntry topic=">" producerFlowControl="true" memoryLimit="1mb">
            <pendingSubscriberPolicy>
              <vmCursor />
            </pendingSubscriberPolicy>
          </policyEntry>
          <policyEntry queue=">" producerFlowControl="true" memoryLimit="1mb">
          </policyEntry>
        </policyEntries>
      </policyMap>
    </destinationPolicy> 

    <persistenceAdapter>
      <kahaDB directory="${karaf.data}/activemq/localhost/kahadb"/>
    </persistenceAdapter>

    <systemUsage>
        <systemUsage>
            <memoryUsage>
                <memoryUsage limit="64 mb"/>
            </memoryUsage>
            <storeUsage>
                <storeUsage limit="100 gb"/>
            </storeUsage>
            <tempUsage>
                <tempUsage limit="50 gb"/>
            </tempUsage>
        </systemUsage>
    </systemUsage>

    <!-- The transport connectors ActiveMQ will listen to -->
    <transportConnectors>
        <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
        <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600"/>
        <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600"/>
    </transportConnectors>

  </broker>

  <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://0.0.0.0:61616" />
  </bean>

  <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
    <property name="maxConnections" value="8" />
    <property name="maximumActive" value="500" />
    <property name="connectionFactory" ref="jmsConnectionFactory" />
  </bean>

  <bean id="resourceManager" class="org.apache.activemq.pool.ActiveMQResourceManager" init-method="recoverResource">
    <property name="transactionManager" ref="transactionManager" />
    <property name="connectionFactory" ref="jmsConnectionFactory" />
    <property name="resourceName" value="activemq.localhost" />
  </bean>

  <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="pooledConnectionFactory" />
    <property name="transacted" value="false" />
    <property name="concurrentConsumers" value="10" />
  </bean>

  <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsConfig" />
  </bean>

  <reference id="transactionManager" interface="javax.transaction.TransactionManager" />

  <service ref="pooledConnectionFactory" interface="javax.jms.ConnectionFactory">
    <service-properties>
      <entry key="name" value="localhost"/>
    </service-properties>
  </service>
</blueprint>

Может ли кто-нибудь сказать мне, что мне не хватает?

Спасибо,

J.


person Jeremy Gooch    schedule 14.10.2013    source источник
comment
Не могли бы вы попробовать подключиться по телнету к 61613 и 61616 с локального и удаленного хоста и добавить вывод к вопросу?   -  person Jakub Korab    schedule 14.10.2013
comment
Все это выглядит нормально с точки зрения конфигурации ActiveMQ. Это определенно похоже на проблему с брандмауэром — если вы работаете на машине с Linux, у вас может быть запущен локальный, такой как iptables. Telnet-подключение к JMX (1099) должно подтвердить это - ни в одной конфигурации нет ничего, что блокировало бы его от удаленных ящиков.   -  person Jakub Korab    schedule 16.10.2013
comment
Спасибо - я вернулся к этому, и это действительно не похоже на проблему с брандмауэром. Вывод netstat (вверху моего поста) указывает мне, что ActiveMQ не прослушивает за пределами локального хоста. Я попытался подключиться по телнету с сервера ActiveMQ к его собственному IP-адресу с отключенным брандмауэром, но все равно получаю сообщение об отказе в подключении. jeremy@server:~$ sudo ufw disable Firewall stopped and disabled on system startup jeremy@server:~$ telnet xxx.xxx.xxx.xxx 61616 Trying xxx.xxx.xxx.xxx... telnet: Unable to connect to remote host: Connection refused jeremy@server:~$ sudo ufw enable   -  person Jeremy Gooch    schedule 17.10.2013
comment
Просто дополнительная мысль - может ли кто-нибудь поделиться рабочим примером broker.xml, который принимает внешний трафик? На всякий случай, если с моим что-то явно не так.   -  person Jeremy Gooch    schedule 17.10.2013
comment
По умолчанию conf/activemq.xml принимает внешний трафик.   -  person Jakub Korab    schedule 18.10.2013
comment
Еще раз спасибо - я разверну его копию на проблемной машине и посмотрю, как это выглядит в netstat.   -  person Jeremy Gooch    schedule 18.10.2013


Ответы (1)


Я решил это. Это не было проблемой ни с брандмауэром, ни с конфигурацией ActiveMQ.

Файл Karaf kar, в котором был определен брокер ActiveMQ, включал функцию activemq-web-console. Мы не использовали эту функцию, так как мы фанаты Hawtio, поэтому никогда не настраивали ее.

Согласно этой записи в блоге, консоль работала с настройками по умолчанию, включая прослушивание порта 61616. Это означало, что два брокера находились в состоянии гонки при запуске, а тот, который определялся веб-консолью, обычно выигрывал. Поскольку по умолчанию он не настроен для удаленного доступа, он блокировал порт только для соединений с локальным хостом.

Подарком был каталог под названием ${activemq.data} (буквально) в домашнем каталоге Karaf, содержащий второй репозиторий Kahadb. Вся конфигурация нашего брокера была настроена на использование каталога data, и мы никогда специально не устанавливали переменные среды ActiveMQ, поэтому это заставило нас искать, откуда мог взяться второй брокер.

Возможно, мы бы заметили это быстрее, если бы мы сделали activemq:list внутри сеанса Karaf, так как он выводит список двух брокеров.

Простое решение — удалить activemq-web-console из XML-файла функций.

person Jeremy Gooch    schedule 21.10.2013