【问题标题】:Clustered WildFly 10 domain messaging集群 WildFly 10 域消息传递
【发布时间】:2018-01-19 01:45:04
【问题描述】:

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

  • 作为主人
  • 作为节点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的节点上传递吗?我错过了什么?

【问题讨论】:

    标签: jms cluster-computing wildfly activemq-artemis


    【解决方案1】:

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

    是的,如果目的地是一个主题,消息应该被传递到所有节点。

    使用默认配置,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"(在您的情况下可以:“@987654325 @")

    您的示例中唯一缺少的是:
    &lt;cluster password="yourPassword" user="activemqUser"/&gt;
    (当然activemqUser 用户必须更早添加,例如使用 addUser.sh 脚本)。

    这让 ActiveMQ 实例能够相互通信。在节点之间创建所谓的Core Bridge 连接。如ActiveMQ manual 所述:

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

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

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

    附:正如here 的回答,这是一种将事件分发到集群中所有节点的经典方法。

    【讨论】:

      猜你喜欢
      • 2016-06-23
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 2011-12-28
      • 1970-01-01
      相关资源
      最近更新 更多