Назад | Перейти на главную страницу

ActiveMQ Artemis: клиенты подключаются к порту кластера брокера

Мы подключаемся с некоторыми клиентами JMS к брокерам ActiveMQ Artemis (v2.14.0), работающим в конфигурации кластера. Сегодня мы заметили, что клиенты подключаются к акцептору, который предназначен для кластерных коммуникаций, и задаются вопросом, почему это происходит.

Вот соответствующие broker.xml фрагменты:

<configuration xmlns="urn:activemq" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
  <core xmlns="urn:activemq:core" xsi:schemaLocation="urn:activemq:core ">
    […]
    <connectors>
      <connector name="netty-connector">tcp://${ipv4addr:localhost}:61618?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;useEpoll=true</connector>
    </connectors>
    <acceptors>
      <!-- Acceptor for every supported protocol -->
      <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;connectionsAllowed=10000</acceptor>
      <!-- AMQP Acceptor.  Listens on default AMQP port for AMQP traffic.-->
      <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
      <!-- STOMP Acceptor. -->
      <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
      <!-- HornetQ Compatibility Acceptor.  Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
      <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
      <!-- MQTT Acceptor -->
      <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
      <acceptor name="netty-acceptor">tcp://0.0.0.0:61618?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;useEpoll=true</acceptor>
      <acceptor name="artemis-tls">tcp://0.0.0.0:61617?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;sslEnabled=true;keyStorePath=/var/lib/artemis/certs/keystore.jks;keyStorePassword=${keyStorePassword};enabledProtocols=TLSv1.2</acceptor>
    </acceptors>
    <broadcast-groups>
      <broadcast-group name="cluster-broadcast-group">
        <broadcast-period>5000</broadcast-period>
        <jgroups-file>jgroups.xml</jgroups-file>
        <jgroups-channel>active_broadcast_channel</jgroups-channel>
        <connector-ref>netty-connector</connector-ref>
      </broadcast-group>
    </broadcast-groups>
    <discovery-groups>
      <discovery-group name="cluster-discovery-group">
        <jgroups-file>jgroups.xml</jgroups-file>
        <jgroups-channel>active_broadcast_channel</jgroups-channel>
        <refresh-timeout>10000</refresh-timeout>
      </discovery-group>
    </discovery-groups>
    <cluster-connections>
      <cluster-connection name="artemis-cluster">
        <connector-ref>netty-connector</connector-ref>
        <retry-interval>500</retry-interval>
        <use-duplicate-detection>true</use-duplicate-detection>
        <message-load-balancing>STRICT</message-load-balancing>
        <!-- <address>jms</address> -->
        <max-hops>1</max-hops>
        <discovery-group-ref discovery-group-name="cluster-discovery-group"/>
        <!-- <forward-when-no-consumers>true</forward-when-no-consumers> -->
      </cluster-connection>
    </cluster-connections>
  </core>
</configuration>

Намерение состоит в том, чтобы использовать порт 61616 (простой TCP, принимающий artemis) и 61617 (TLS, акцептор artemis-tls) для клиентских подключений. Брокеры должны использовать порт 61618 (принимающий netty-acceptor) для внутренних коммуникаций кластера. Однако во время обнаружения топологии брокер отправляет клиенту порт 61618 (вместо ожидаемого порта 61616). Хотя это работает, когда все коммуникации являются обычным TCP, все становится странным, когда netty-acceptor настроен для TLS, а клиентские подключения - нет. Затем клиент показывает такие сообщения, как

2020-08-24 17:58:13,833 | WARN  | Thread-1 (ActiveMQ-client-netty-threads) | i.n.c.ChannelInitializer | Failed to initialize a channel. Closing: [id: 0x5bb533bc]

java.lang.Exception: Failed to find a store at /var/lib/artemis/certs/truststore.jks

    at org.apache.activemq.artemis.core.remoting.impl.ssl.SSLSupport.validateStoreURL(SSLSupport.java:278)

Итак, брокер передает клиенту свою внутреннюю конфигурацию. (/var/lib/artemis/certs/truststore.jks существуют только в контейнере Artemis.)

Как мы можем настроить брокера для выделенных клиентских и кластерных подключений и гарантировать, что клиент никогда не получит конечную точку кластера? Кроме того, можем ли мы независимо настроить TLS для клиентских и кластерных подключений? Документы здесь не особо полезны.

РЕДАКТИРОВАТЬ

Переосмысление этой проблемы приводит к связанному с этим вопросу: как обеспечить, чтобы клиенты, подключающиеся через TCP, всегда получали порт TCP во время обнаружения, а клиенты, подключающиеся через TLS, получали порт TLS?

ОБНОВИТЬ

Присмотритесь к Artemis docs раскрывает это объяснение:

Хотя это значение можно настроить на сервере, оно загружается и используется клиентом.

Хорошо, это немного объясняет. Однако я до сих пор не могу понять, как сообщить клиентам, какой соединитель использовать. в RedHat AMQ 7.2 документы, глава 6.3 говорит

На указанный выше коннектор будет ссылаться клиент или даже сам брокер при создании TCP-соединения с указанным IP-адресом и портом, 10.10.10.2:61617.

предлагая клиенту сопоставить IP-адрес и порты, чтобы найти подходящий соединитель. Однако, похоже, это не работает с Artemis v2.14.0.