如何在集群环境中设置wildfly jms消息以正确地在同一组中传递消息?
我已经找到了activeMq的属性,它可以解决此问题here,但是现在我不知道如何将其应用于wildfly的jms子系统。如何设置队列或Mdb在独占模式下工作?
我试图通过jms生产者将标志设置为“ exclusive?= true”,例如:
@Inject
private JMSContext context;
@Resource(mappedName = "java:/jms/queue/TestQueue?consumer.exclusive=true")
private Queue testQueue;
public void pushToQueue(String messagePayload, String messageGroup) {
try {
Message message = context.createTextMessage(messagePayload);
message.setStringProperty("JMSXGroupID", messageGroup);
context.createProducer().send(processQueue, message);
} catch (JMSException e) {
e.printStackTrace();
}
以及其他类似方式:
@Resource(name="DefaultJMSConnectionFactory")
private ConnectionFactory connectionFactory;
try {
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession();
Queue queue = session.createQueue("TestQueue?consumer.exclusive=true");
Message message = session.createTextMessage(messagePayload);
session.createProducer(queue).send(message);
} catch (JMSException e) {
e.printStackTrace();
}
在Mdb方面:
@MessageDriven(name = "queueMDB", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/queue/TestQueue?consumer.exclusive=true"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "5"),
})
public class ConsumerMdb implements MessageListener {
...
}
一切都没有成功。在这种情况下,我无法将字符串pf队列名称解析为URl参数,而是整个字符串表示队列名称(或JNI名称)
比起尝试使用'ActiveMQQueue'类来创建队列对象(该对象实现javax.jms.Destination的接口) 代码:
public void pushToQueue(String messagePayload, String messageGroup) {
try {
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession();
ActiveMQQueue queue = new ActiveMQQueue("TestQueue?consumer.exclusive=true");
//ActiveMQQueue queue = new ActiveMQQueue("jms.queue.TestQueue");
Message message = session.createTextMessage(messagePayload);
session.createProducer(queue).send(message);
} catch (JMSException e) {
e.printStackTrace();
}
}
在队列名称可能不同的情况下:
ActiveMQQueue queue = new ActiveMQQueue("TestQueue");
ActiveMQQueue queue = new ActiveMQQueue("TestQueue?consumer.exclusive=true");
ActiveMQQueue queue = new ActiveMQQueue("java:/jms/queue/TestQueue");
ActiveMQQueue queue = new ActiveMQQueue("jms.queue.TestQueue");
也成功了。我遇到了InvalidDestinationException:
12:54:12,959 ERROR [stderr] (default task-37) javax.jms.InvalidDestinationException: Not an ActiveMQ Artemis Destination:queue://TestQueue
12:54:12,959 ERROR [stderr] (default task-37) at org.apache.activemq.artemis.jms.client.ActiveMQSession.createProducer(ActiveMQSession.java:293)
12:54:12,959 ERROR [stderr] (default task-37) at org.apache.activemq.artemis.ra.ActiveMQRASession.createProducer(ActiveMQRASession.java:1082)
12:54:12,959 ERROR [stderr] (default task-37) at si.teletech.test.eecluster.ejb.queue.Producer.pushToQueue(Producer.java:67)
12:54:12,960 ERROR [stderr] (default task-37) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
12:54:12,960 ERROR [stderr] (default task-37) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
12:54:12,960 ERROR [stderr] (default task-37) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
12:54:12,960 ERROR [stderr] (default task-37) at java.lang.reflect.Method.invoke(Method.java:498)
12:54:12,960 ERROR [stderr] (default task-37) at org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52)
12:54:12,960 ERROR [stderr] (default task-37) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
12:54:12,960 ERROR [stderr] (default task-37) at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:509)
12:54:12,960 ERROR [stderr] (default task-37) at org.jboss.as.weld.interceptors.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:90)
...
但是在例外情况下,我注意到队列名称已正确解析,没有URL参数。“ Destination:queue:// TestQueue”。
答案 0 :(得分:0)
好吧,我自己以某种方式解决了它。我需要集群式单例交付。它的工作方式类似于独家消费者。 Mdb bean部署在群集服务器的所有节点上,但只有一个处于活动状态(消耗消息)。万一节点发生故障,Mdb将在链中的下一个节点上启动(即故障转移)。
@MessageDriven(name = "queueMDB", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "TestQueue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "maxSession", propertyValue = "5"),
})
@ClusteredSingleton
public class ConsumerMdb implements MessageListener {
// your mdb implementation
}
参考:https://docs.jboss.org/author/display/WFLY10/Message+Driven+Beans+Controlled+Delivery