[英]Message driven bean does not receive message from other nodes in the cluster
I have a Wildfly 23 cluster with two nodes (node-1, node-2) running the standalone-full-ha profile.我有一个 Wildfly 23 集群,其中有两个节点(node-1、node-2)运行着standalone-full-ha 配置文件。 The two cluster nodes boot and communicate with each other correctly (as far as I can judge).
两个集群节点正确启动并相互通信(据我所知)。
My intention is to send a JMS message on a topic from node-1 and have message driven beans (MDB) on node-1 and node-2 consume this message.我的意图是从节点 1 发送关于主题的 JMS 消息,并让节点 1 和节点 2 上的消息驱动 bean (MDB) 使用此消息。
The MDB code: MDB 代码:
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destinationLookup",
propertyValue = "java:/jms/topic/myTopic"),
@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")
})
public class ClusteredEventListener implements MessageListener {
@Override
public void onMessage(final Message message) {
// consume message
}
}
The message publisher code:消息发布者代码:
import java.io.Serializable;
import javax.annotation.Resource;
import javax.ejb.Startup;
import javax.enterprise.context.ApplicationScoped;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
@Startup
@ApplicationScoped
public class ClusteredEventSender {
@Resource(lookup = "java:/jms/topic/myTopic")
private Topic topic;
@Resource(mappedName = "java:/ConnectionFactory")
private TopicConnectionFactory connectionFactory;
public void broadcast(final Serializable event) {
try {
try (TopicConnection connection = this.connectionFactory.createTopicConnection()) {
try (TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE)) {
try (MessageProducer messageProducer = session.createPublisher(this.topic)) {
final ObjectMessage message = session.createObjectMessage(event);
messageProducer.send(message);
}
}
}
} catch (final JMSException e) {
log.error("Could not broadcast event to topic: " + event, e);
}
}
}
Snippet from standalone.xml:来自standalone.xml的片段:
<subsystem xmlns="urn:jboss:domain:messaging-activemq:13.0">
<server name="default">
...
<jms-topic name="myTopic" entries="java:/jms/topic/myTopic"/>
...
</server>
</subsystem>
Outcome is that the messages are only consumed on the node that generated them.结果是消息仅在生成它们的节点上使用。 The other node does not receive any message.
另一个节点没有收到任何消息。
Experiments实验
I experimented by using java:jboss/exported/jms/RemoteConnectionFactory
with durable subscripitions, unique clientID
and subscriptionName
for each node and a user "jmsuser", and using a topic in java:jboss/exported ( java:jboss/exported/jms/topic/myTopic
), changing/extending the annotations on the MDB as follows: I experimented by using
java:jboss/exported/jms/RemoteConnectionFactory
with durable subscripitions, unique clientID
and subscriptionName
for each node and a user "jmsuser", and using a topic in java:jboss/exported ( java:jboss/exported/jms/topic/myTopic
),更改/扩展 MDB 上的注释如下:
...
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "java:jboss/exported/jms/topic/myTopic"),
@ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
@ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "subscription-${jboss.node.name}"),
@ActivationConfigProperty(propertyName = "clientID", propertyValue = "node-${jboss.node.name}"),
@ActivationConfigProperty(propertyName = "connectionFactoryLookup", propertyValue = "java:jboss/exported/jms/RemoteConnectionFactory"),
@ActivationConfigProperty(propertyName = "user", propertyValue = "jmsuser"),
@ActivationConfigProperty(propertyName = "password", propertyValue = "jmsuser")
...
Note: The "jmsuser" was added using the batch script add-user.bat in the wildfly/bin directory.注意:“jmsuser”是使用 wildfly/bin 目录中的批处理脚本 add-user.bat 添加的。 It has been assigned the role "guest".
它已被分配角色“客人”。 The guest role has been extended regarding durable queues.
关于持久队列,来宾角色已扩展。 The property replacement in annotations (to make the
${jboss.node.name}
in clientID
and subscriptionName
work) has been activated in standalone.xml:注释中的属性替换(使
clientID
和subscriptionName
中的${jboss.node.name}
工作)已在standalone.xml 中激活:
<subsystem xmlns="urn:jboss:domain:ee:6.0">
...
<annotation-property-replacement>true</annotation-property-replacement>
...
</subsystem>
...
<subsystem xmlns="urn:jboss:domain:messaging-activemq:13.0">
<server name="default">
...
<security-setting name="#">
...
<role name="guest" delete-non-durable-queue="true"
create-non-durable-queue="true"
delete-durable-queue="true"
create-durable-queue="true"
consume="true"
send="true" />
...
</security-setting>
...
<jms-topic name="myTopic" entries="java:jboss/exported/jms/topic/myTopic"/>
...
</server>
</subsystem>
...
The amended message publisher code:修改后的消息发布者代码:
public class ClusteredEventSender {
@Resource(lookup = "java:jboss/exported/jms/topic/myTopic")
private Topic topic;
@Resource(lookup = "java:jboss/exported/jms/RemoteConnectionFactory")
private TopicConnectionFactory connectionFactory;
public void broadcast(final Serializable event) {
try {
try (TopicConnection connection = this.connectionFactory.createTopicConnection("jmsuser", "jmsuser")) {
try (TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE)) {
try (MessageProducer messageProducer = session.createPublisher(this.topic)) {
final ObjectMessage message = session.createObjectMessage(event);
messageProducer.send(message);
}
}
}
} catch (final JMSException e) {
log.error("Could not broadcast event to topic: " + event, e);
}
}
}
Experiments outcome: The connection to the RemoteConnectionFactory works, but nevertheless the behaviour remains the same as before.实验结果:与 RemoteConnectionFactory 的连接有效,但行为仍与以前相同。
My questions are: How can a publish / subscribe using JMS / ActiveMQ be implemented in a Wildfly cluster?我的问题是:如何在 Wildfly 集群中实现使用 JMS/ActiveMQ 的发布/订阅? What does the message driven bean look like, and how are the messages to be sent?
消息驱动 bean 是什么样子的,消息是如何发送的? What configuration is needed?
需要什么配置?
Thanks to @ehsavoie's hint we managed to solve the problem.感谢@ehsavoie 的提示,我们设法解决了这个问题。 Solution in short:
简而言之,解决方案:
java:jboss/exported/jms/topic/myTopic
or java:jboss/exported/jms/RemoteConnectionFactory
is not necessary.java:jboss/exported/jms/topic/myTopic
myTopic 或java:jboss/exported/jms/RemoteConnectionFactory
。 Neither are any @ActivationConfigProperty
-Entries for subscriptionName
, clientId
, user
or password
. subscriptionName
、 clientId
、 user
或password
的任何@ActivationConfigProperty
-Entries 也不是。 All experiments described in the question were a dead end.jms-connection-factory="java:jboss/DefaultJMSConnectionFactory"
to the <default-bindings>
in our standalone.xml everything worked as expected. jms-connection-factory="java:jboss/DefaultJMSConnectionFactory"
添加到我们的standalone.xml 中的<default-bindings>
一切都按预期工作。 Those two little rascals slipped away during setup. Thus, the relevant standalone.xml snippets are:因此,相关的standalone.xml 片段是:
<cluster password="something else than CHANGE ME!!"/>
and和
<default-bindings ... jms-connection-factory="java:jboss/DefaultJMSConnectionFactory" ... />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.