集群WildFly 10域消息传递 [英] Clustered WildFly 10 domain messaging

查看:255
本文介绍了集群WildFly 10域消息传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have three machines located in different networks:

  • 作为主人
  • as-node-1
  • 作为节点2

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

In as-master I have WildFly as domain host-master and the two nodes have WildFly as domain host-slave each starting an instance in the full-ha server group. From the as-master web console I can see the two nodes in the full-ha profile runtime and if I deploy a WAR it gets correctly started on both nodes.

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

Now, what I'm trying to achieve is messaging between the two instances of the WAR, i.e. sending a message from a producer instance in as-node-1, consumers in all the nodes should receive the message.

这是我尝试的方法:在WildFly domain.xml中添加了一个主题:

This is what I tried: added a topic to WildFly domain.xml:

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

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

Create a JAX-RS endpoint to trigger a producer bound to the topic:

@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:

Create a MDB listening to the topic:

@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中看到日志.

But when I curl as-node-1/jms I see the log only in as-node-1, and when I curl as-node-2/jms I see the log only in as-node-2.

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

Shouldn't the message be delivered on all the nodes where the WAR is deployed? What am I missing?

推荐答案

由于我遇到了完全相同的问题,请在此处填写答案.

As I've come with the exactly same question - put the answer here.

是的,如果目的地是主题,则应该将消息传递到所有节点.

Yes, messages should be delivered to all nodes if a destination is a Topic.

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

With the default configuration ActiveMQ Artemis uses broadcast to discover and connect to other ActiveMQ instances on other nodes (within the same discovery-group):

<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"(在您的情况中可以的:")

Still need to ensure that a JNDI name for a jms-topic starts with the "jms" to match the address="jms" in the line above (what is OK in your case: "java:/jms/my-topic")

您的示例中让它在所有节点上都能正常运行的唯一遗漏是:
<cluster password="yourPassword" user="activemqUser"/>
(确保activemqUser用户必须先添加,例如使用addUser.sh脚本).

The only thing missed in your example to get it working on all nodes is :
<cluster password="yourPassword" user="activemqUser"/>
(for sure activemqUser user must be added earlier, e.g. with the addUser.sh script).

这使ActiveMQ实例可以相互通信.所谓的 Core Bridge 连接是在节点之间创建的.如 ActiveMQ手册所述:

This let ActiveMQ instances to communicate each other. So called Core Bridge connection is created between nodes. As stated in ActiveMQ manual :

..这是在后台透明完成的-您不必 为每个节点声明一个明确的网桥

..this is done transparently behind the scenes - you don't have to declare an explicit bridge for each node

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

If everything is OK then the bridge may be found in server.log: AMQ221027: Bridge ClusterConnectionBridge@63549ead [name=sf.my-cluster ...] is connected.

顺便说一句,如果目的地是 Queue ,则ActiveMQ不会将消息发送到其他节点,除非该消息不在本地使用.

Btw, if a destination is a Queue then ActiveMQ will not send a message to other nodes unless a message is not consumed locally.

P.s.如此处所示是指将事件分配到群集中所有节点的经典方法.

P.s. as answered here this refers to a classic approach to distribute an event to all nodes in a cluster.

这篇关于集群WildFly 10域消息传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆