我有一个activemq配置,其中我有一个虚拟目的地和一个正常的主题
我想根据邮件头中的JMSType将所有JMS邮件路由到目标(VirtualTopic.Notifications)到2个队列(VirtualTopic.SMS,VirtualTopic.EMAIL)。
我希望正常的主题(VirtualTopic.gps)像往常一样工作。
这是我对activemq.xml的配置。这里创建了Consumer.SMS.VirtualTopic和Consumer.EMAIL.VirtualTopic。
<destinations>
<queue physicalName="Consumer.SMS.VirtualTopic" />
<queue physicalName="Consumer.EMAIL.VirtualTopic" />
</destinations>
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<compositeQueue name="VirtualTopic.Notifications" forwardOnly="false">
<forwardTo>
<filteredDestination selector="JMSType = 'SMS'" queue="Consumer.SMS.VirtualTopic"/>
<filteredDestination selector="JMSType = 'EMAIL'" queue="Consumer.EMAIL.VirtualTopic"/>
</forwardTo>
</compositeQueue>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
虽然从服务器端代码创建了使用者和主题(VirtualTopic.gps)。
private static MessageProducer getTopicProducer(String topicName) throws JMSException {
MessageProducer producer = topicProducers.get(topicName);
if (producer == null) {
logger.info("Creating message producer for Topic : {}", topicName);
Destination destination = session.createTopic(topicName);
List<String> queueNames = PropertyReader
.getPropertyStringList("jms.topic.consumer.list", JMSProducer.properties);
if (queueNames != null) {
for (String queueName : queueNames) {
Queue virtualQueue = session.createQueue(queueName);
MessageConsumer con = session.createConsumer(virtualQueue);
con.close();
}
}
producer = session.createProducer(destination);
topicProducers.put(topicName, producer);
}
return producer;
}
VirtualTopic.Notifications的所有消息都被路由到2个不同的队列,消费者可以从各个队列中接收消息
但问题是所有发送到VirtualTopic.gps的消息都被过滤掉了,消费者不能使用gps消息。
答案 0 :(得分:0)
以下示例显示如何设置元素 在XML配置中,以便在将消息发送到MY.QUEUE时 然后它真的被转发到物理队列FOO和主题 BAR。
<destinationInterceptors> <virtualDestinationInterceptor> <virtualDestinations> <compositeQueue name="MY.QUEUE"> <forwardTo> <queue physicalName="FOO" /> <topic physicalName="BAR" /> </forwardTo> </compositeQueue> </virtualDestinations> </virtualDestinationInterceptor> </destinationInterceptors>
默认情况下,订阅者无法直接使用消息 复合队列或主题 - 它只是一个逻辑构造。鉴于 上面的配置,订阅者只能消费来自FOO的消息 和BAR;但不是MY.QUEUE。可以更改此行为以实现 通过向a发送相同的消息来观察队列等用例 通知主题(电子窃听),通过设置可选设置 forwardOnly属性为false。
<compositeQueue name="IncomingOrders" forwardOnly="false"> <forwardTo> <topic physicalName="Notifications" /> </forwardTo> </compositeQueue>
发送到IncomingOrders的邮件将全部复制并转发到 通知,在放置在物理IncomingOrders之前 用户消费的队列。
看看http://activemq.apache.org/virtual-destinations.html
使用您的实际配置,您只能使用队列的短信&amp;电子邮件,如果您想使用通知,则需要设置 forwardOnly =“false”
更新: 试用此代码:
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ActiveMQMessageConsumer;
import org.apache.activemq.ActiveMQSession;
import org.apache.activemq.command.ActiveMQTextMessage;
public class SimpleSenderConsumerVirtualTopic {
public static void main(String[] args) throws JMSException {
Connection conn = null;
try {
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory();
conn = cf.createConnection( );
ActiveMQSession session = (ActiveMQSession) conn.createSession(false,
ActiveMQSession.AUTO_ACKNOWLEDGE);
ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer) session
.createConsumer(session.createQueue("Consumer.A.VirtualTopic.gps"));
MessageProducer producer = session.createProducer(session.createTopic("VirtualTopic.gps"));
conn.start();
ActiveMQTextMessage msg = (ActiveMQTextMessage) session.createTextMessage("VirtualTopic.gps test");
producer.send(msg);
msg = null;
while ((msg = (ActiveMQTextMessage) consumer.receive(5000)) != null) {
System.out.println("Received message is: " + msg.getText());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
}
}
}
}
}
并添加此内容:
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<compositeQueue name="VirtualTopic.Notifications" forwardOnly="false">
<forwardTo>
<filteredDestination selector="JMSType = 'SMS'" queue="Consumer.SMS.VirtualTopic"/>
<filteredDestination selector="JMSType = 'EMAIL'" queue="Consumer.EMAIL.VirtualTopic"/>
</forwardTo>
</compositeQueue>
<virtualTopic name=">" selectorAware="false" />
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
答案 1 :(得分:0)
非常感谢Hassen ..
添加此行<virtualTopic name=">" selectorAware="false" />
到activemq.xml就可以了。
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<compositeQueue name="VirtualTopic.Notifications"
forwardOnly="false">
<forwardTo>
<filteredDestination selector="JMSType = 'SMS'"
queue="Consumer.SMS.VirtualTopic" />
<filteredDestination selector="JMSType ='EMAIL'"
queue="Consumer.EMAIL.VirtualTopic" />
</forwardTo>
</compositeQueue>
<virtualTopic name=">" selectorAware="false" />
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>