群集的WildFly 10域名消息

时间:2017-08-10 10:38:21

标签: jms cluster-computing wildfly activemq-artemis

我有三台机器位于不同的网络中:

  • 作为主
  • 作为节点-1
  • 作为节点-2

在as-master中我将WildFly作为域主机 - 主机,并且两个节点都将WildFly作为域主机 - 从机,每个节点都在全ha服务器组中启动一个实例。在as-master Web控制台中,我可以看到full-ha配置文件运行时中的两个节点,如果我部署WAR,它将在两个节点上正确启动。

现在,我想要实现的是两个WAR实例之间的消息传递,即从as-node-1中的生产者实例发送消息,所有节点中的消费者都应该收到消息。 / p>

这就是我的尝试:向WildFly domain.xml添加了一个主题:

<jms-topic name="MyTopic" entries="java:/jms/my-topic"/>

创建JAX-RS端点以触发绑定到主题的生产者:

@Path("jms")
@RequestScoped
public class MessageEndpoint {

    @Inject
    JMSContext context;

    @Resource(mappedName = "java:/jms/my-topic")
    Topic myTopic;

    @GET
    public void sendMessage() {
         this.context.createProducer().send(this.myTopic, "Hello!");
    }

}

创建一个听取主题的MDB:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(
        propertyName = "destination",
        propertyValue = "java:/jms/my-topic"
    ),
    @ActivationConfigProperty(
        propertyName = "destinationType",
        propertyValue = "javax.jms.Topic")
    )
)
public class MyMessageListener implements MessageListener {

    private final static Logger LOGGER = /* ... */

    public void onMessage(Message message) {
        try {
            String body = message.getBody(String.class)
            LOGGER.info("Received message: " + body);
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }

}

但是当我curl as-node-1/jms时,我只在as-node-1中看到了日志,当我curl as-node-2/jms时,我只在as-node-2中看到了日志。

是否应该在部署WAR的所有节点上传递消息?我错过了什么?

1 个答案:

答案 0 :(得分:2)

当我提出完全相同的问题时 - 在这里提出答案。

是的,如果目的地是主题,则应将消息发送到所有节点。

使用默认配置ActiveMQ Artemis使用广播来发现并连接到其他节点上的其他ActiveMQ实例(在同一个发现组中):

<discovery-group name="dg-group1" jgroups-channel="activemq-cluster"/>
<cluster-connection name="my-cluster" discovery-group="dg-group1" connector-name="http-connector" address="jms"/>

仍然需要确保jms主题的JNDI名称以“ jms ”开头,以匹配上面一行中的address="jms"(在您的情况下可以正常:“ java:/jms/my-topic“)

您的示例中唯一让它在所有节点上运行的内容是:<cluster password="yourPassword" user="activemqUser"/>
(肯定activemqUser用户必须先添加,例如使用addUser.sh脚本。

这让ActiveMQ实例相互通信。在节点之间创建所谓的核心网桥连接。如ActiveMQ manual中所述:

  

..这是在幕后透明地完成的 - 你不必这样做   为每个节点声明一个显式桥接

如果一切正常,那么可以在server.log中找到网桥:AMQ221027: Bridge ClusterConnectionBridge@63549ead [name=sf.my-cluster ...] is connected.

顺便说一句,如果目的地是队列,那么除非本地没有消息,否则ActiveMQ不会向其他节点发送消息。

P.S。回答here这指的是将事件分发到集群中所有节点的经典方法。