2

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

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

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

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

这是我尝试过的:向 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 的所有节点上传递吗?我错过了什么?

4

1 回答 1

2

因为我提出了完全相同的问题 - 把答案放在这里。

是的,如果目的地是Topic ,则消息应该被传递到所有节点。

使用默认配置 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-topic 的 JNDI 名称以“ jms ”开头以匹配address="jms"上面一行中的(在您的情况下可以:“ java:/jms/my-topic”)

在您的示例中,让它在所有节点上工作的唯一遗漏是:(
<cluster password="yourPassword" user="activemqUser"/>
确保activemqUser必须更早添加用户,例如使用 addUser.sh 脚本)。

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

..这是在幕后透明地完成的——你不必为每个节点声明一个明确的网桥

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

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

此处回答的 Ps这是指将事件分发到集群中所有节点的经典方法。

于 2018-01-18T13:19:56.710 回答