在Wildfly 12中配置ActiveMQ Artemis以在群集中进行时间紧迫的消息传递

时间:2018-07-11 23:28:28

标签: jms wildfly activemq-artemis

当原始节点发生故障时,我不知道如何在Wildfly 12中获取消息传递子系统以将队列消息重新传递到另一个节点。当第一个尝试访问的节点没有足够快地确认/提交时,我需要一种将消息定向到其他节点的方法。

我有一个带有单个队列(TestQueue)的3节点Wildfly 12集群。我用一个可捕获JMS连接并与该队列上的使用者建立会话的单个bean部署应用程序。这是构造函数:

public TestMessageListener( ConnectionFactory connectionFactory, Destination destination )
{
    this.context = connectionFactory.createContext( JMSContext.DUPS_OK_ACKNOWLEDGE );
    this.consumer = this.context.createConsumer( destination );
    this.consumer.setMessageListener( this );
    this.context.start();
}

连接工厂和目标被注入到其他地方:

@Resource( lookup = "java:/ConnectionFactory" ) private ConnectionFactory connectionFactory;
@Resource( lookup = "java:/jms/queue/TestQueue" ) private Destination destination;

回到侦听器中,我只记录它收到的内容:

@Override
public void onMessage( Message message )
{
    try
    {
        message.acknowledge();
        String body = new String( message.getBody( byte[].class ), StandardCharsets.UTF_8 );
        LOG.info( body );
    }
    catch ( JMSException e )
    {
        LOG.warning( e.toString() );
    }
}

最后,我在消息传递子系统配置中启用了STOMP:

<socket-binding-groups>
    <socket-binding-group name="full-ha-sockets" default-interface="public">
        <socket-binding name="stomp" port="6164"/>
        ... 
    </socket-binding-group>
</socket-binding-groups>

<subsystem xmlns="urn:jboss:domain:messaging-activemq:3.0">
    <server name="default">
        <remote-acceptor name="stomp-acceptor" socket-binding="stomp">
            <param name="protocols" value="STOMP"/>
        </remote-acceptor>            
        <address-setting name="jms.queue.TestQueue" redistribution-delay="0"/>
        ...
    </server>

我通过踩踏连接并每2秒发送一次带有唯一标识符的测试消息。 3个节点中的每个节点依次接收一个轮询。然后,从其中一个节点上拔下网络电缆。

1分钟后(我假设是connection-ttl),我在其他2个节点上收到有关连接失败的错误消息:

2018-07-11 20:02:18,813 INFO  [TestMessageListener] (Thread-1 (ActiveMQ-client-global-threads)) TEST 435
2018-07-11 20:02:21,448 WARN  [org.apache.activemq.artemis.core.client] (Thread-8 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$3@3070595f)) AMQ212037: Connection failure has been detected: AMQ119014: Did not receive data from /192.168.1.82:51046 within the 60,000ms connection TTL. The connection will now be closed. [code=CONNECTION_TIMEDOUT]
2018-07-11 20:02:21,449 WARN  [org.apache.activemq.artemis.core.server] (Thread-8 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$3@3070595f)) AMQ222061: Client connection failed, clearing up resources for session b7be7d58-855c-11e8-91dd-6c626d5557a6
2018-07-11 20:02:21,449 WARN  [org.apache.activemq.artemis.core.server] (Thread-8 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$3@3070595f)) AMQ222107: Cleared up resources for session b7be7d58-855c-11e8-91dd-6c626d5557a6
2018-07-11 20:02:21,449 WARN  [org.apache.activemq.artemis.core.server] (Thread-8 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$3@3070595f))     AMQ222061: Client connection failed, clearing up resources for session b7becb79-855c-11e8-91dd-6c626d5557a6
2018-07-11 20:02:21,449 WARN  [org.apache.activemq.artemis.core.server] (Thread-8 (ActiveMQ-server-org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl$3@3070595f)) AMQ222107: Cleared up resources for session b7becb79-855c-11e8-91dd-6c626d5557a6

再过30秒后,我又收到一轮关于连接失败的错误消息:

2018-07-11 20:02:49,443 WARN  [org.apache.activemq.artemis.core.client] (Thread-1 (ActiveMQ-client-global-threads)) AMQ212037: Connection failure has been detected: AMQ119011: Did not receive data from server for org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection@5e696d4b[local= /192.168.1.27:39202, remote=/192.168.1.82:8080] [code=CONNECTION_TIMEDOUT]
2018-07-11 20:02:49,444 WARN  [org.apache.activemq.artemis.core.server] (Thread-1 (ActiveMQ-client-global-threads)) AMQ222095: Connection failed with failedOver=false
2018-07-11 20:02:49,446 WARN  [org.apache.activemq.artemis.core.server] (Thread-1 (ActiveMQ-client-global-threads)) AMQ222095: Connection failed with failedOver=false

请注意,我的STOMP客户端已连接到一个正常节点,并在“失败”框断开连接时继续向队列发送消息。

我的问题是:

  • 在90秒钟内,Artemis继续将消息传递到未插入的盒子中。
  • 即使在90秒钟之后,我也不知道如何让Artemis尝试将旧消息重新传递到另一个节点。
  • 我不明白为什么在60秒钟的第一轮连接错误后,它为何继续尝试将邮件传递到未插拔的盒子。
  • 设置重新分配延迟没有任何效果,尽管由于https://activemq.apache.org/artemis/docs/latest/clusters.html,我认为这很有用。

赞:

<address-setting name="jms.queue.TestQueue" redistribution-delay="0"/>
  • 当我重新插入网络电缆时,所有本应传递到故障节点的消息现在都已传递。

对于这个特定的队列,我不仅希望重新尝试发送到另一个节点,而且还希望消息确认超时触发此重新发送,否则,将触发750-1000ms的小连接ttl。如果将connection-ttl设置为偶数15000ms,则所有节点之间的所有连接(即使整个群集都运行良好)在15000ms之后也会引发错误。根据{{​​3}}上的文档,此参数为“网桥的TTL。此值应大于ping周期。”目前尚不清楚“ ping period”是什么参数,甚至还不清楚这种参数如何映射到Wildfly子系统配置。我假设在这里,将connection-ttl设置为15000:

<cluster-connection name="my-cluster" address="jms" connector-name="http-connector" connection-ttl="60000" retry-interval-multiplier="1.5" max-retry-interval="60000" discovery-group="dg-group1"/>

我完全可以接收和处理重复的消息;我认为JMSContext.DUPS_OK_ACKNOWLEDGE和redistribution-delay =“ 0”的组合至少可以解决它的重新交付部分。

我尝试了JMSContext.TRANSACTED并使用了JMSContext.commit()和JMSContext.rollback()。显然,当故障节点与集群的其余部分断开连接时,rollback()并不适用,但这是我看到的触发重新交付的唯一方法。

我现在正处在调整看似无数个配置参数的阶段,几乎没有影响。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我相信这里发生的是,reconnect-attempts的默认-1被用于集群连接,并且只要集群连接正尝试重新连接到故障节点,该节点的消息将保留在特殊的“存储转发”队列中。您应该能够将reconnect-attempts设置为-1以外的其他值,以便集群连接将放弃尝试重新连接的尝试,这时发送给其他节点的消息通常可以使用。