rabbitmq配置,用于接收使用单个队列和许多侦听器在模式上过滤的消息

时间:2015-03-27 12:49:30

标签: spring rabbitmq spring-amqp

我有这个要求将消息推送到单个队列但在多个地方(java类)接收它们。

为此我使用了主题交换并将其绑定到一个队列,该队列根据不同的模式接收消息。现在,当我尝试在另一端接收它们时,listener-container将消息发送给两个侦听器,而不是根据决定的模式将它们分叉。

我已附上配置及以下代码以便快速查看

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

    <rabbit:connection-factory id="connectionFactory" host="localhost" username="guest" password="guest" />

    <rabbit:admin connection-factory="connectionFactory" />

    <rabbit:template id="pgTemplate" connection-factory="connectionFactory" exchange="PG-EXCHANGE"/>

    <rabbit:queue id="pgQueue" />

    <rabbit:topic-exchange id="pgExchange" name="PG-EXCHANGE">
        <rabbit:bindings>
            <rabbit:binding queue="pgQueue" pattern="pg"></rabbit:binding>
            <rabbit:binding queue="pgQueue" pattern="txn"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>

    <bean id="pgReceiver" class="com.pg.mq.service.impl.MessageReceiver"/>
    <bean id="txnReceiver" class="com.pg.mq.service.impl.MessageReceiver"/>

    <rabbit:listener-container id="ListenerContainer" connection-factory="connectionFactory">
        <rabbit:listener ref="pgReceiver" queues="pgQueue" method="handleMessage"/>
        <rabbit:listener ref="txnReceiver" queues="pgQueue" method="handleMessage"/>
    </rabbit:listener-container>

</beans>

讯息发件人

public String pushMessagePG(Object object) {
        if(object != null && object instanceof Rabbit)
            pgTemplate.convertAndSend("pg", object); // send
        return null;
    } 

讯息接收者

PG RECEIVER

public void handleMessage(Rabbit message) {
        System.out.println("inside Message Receiver");
        System.out.println("Listener received message----->" + message);
    }

TXN RECEIVER

public void handleMessage(Rabbit message) {
        System.out.println("inside TXN Message Receiver");
        System.out.println("Listener received message----->" + message);
    }

致电代码

Sender sender = (Sender) context.getBean("messageSender");
        for(int i = 0; i < 30; i++) sender.pushMessagePG(new Rabbit(5));
        Thread.sleep(2000);
        for(int i = 0; i < 30; i++) sender.pushMessageTXN(new Rabbit(2));

1 个答案:

答案 0 :(得分:3)

很抱歉,但您对AMQP规范了解不多。

  1. 消息由routingKey
  2. 发送到交换机
  3. routingKeypatterntopic-exchange
  4. 绑定了队列。
  5. 只有单个使用者才能从队列中收到消息。
  6. AMQP中没有像distribution这样的机制。我的意思是类似于JMS中的Topic概念。
  7. topic-exchange将消息放入routingKey与绑定pattern匹配的所有队列。
  8. article以最佳方式描述。

    由于您为两个模式绑定了相同的队列,因此所有消息都放在同一个队列中。

    来自其他消费者的是队列,只是队列。他们对routingKey一无所知。

    由于您有两个同一队列的侦听器,因此它们都可以处理来自该队列的消息并且它独立于routingKey并不奇怪。

    你真的应该为不同的模式使用不同的队列。或者考虑使用Spring Integration及其Message Routing权限。对于该情况,您可以使用标准AmqpHeaders.RECEIVED_ROUTING_KEY(Spring Integration)标头。