Spring和RabbitMQ如何声明和使用队列?

时间:2012-01-25 09:12:07

标签: java spring rabbitmq amqp

我正在开发一个使用Spring和RabbitMQ的Web项目。这是一个基本系统,主节点向Slave节点发送任务(使用直接交换),Slave节点使用简单队列响应Master。

新的奴隶可能随时来去,所以他们使用匿名队列。也可以有多个主节点,在这种情况下,每个节点都有自己的回复队列。当主服务器向从服务器发送任务时,该任务包含发送它的主服务器的应答队列的名称。使用AmqpTemplate发送消息。

我正在使用XML配置所有这些,这是我到目前为止所做的:

对于奴隶:

<!-- Message listener -->
<bean id="taskListener" class="tgi.docgen.amqp.TypedListener" />
  <bean id="slave" class="tgi.docgen.node.Slave" />
    <bean id="handler" class="tgi.docgen.task.TaskHandler" />

<!-- Rabbit infrastructure -->
<!-- Slave reading queue, bound to the exchange -->
<rabbit:queue id="receiveQueue" auto-delete="true" durable="false" />

<!-- Master -> Slave exchange -->
<rabbit:direct-exchange name="docgenExchange" auto-delete="true" durable="false">   
    <rabbit:bindings>
        <rabbit:binding queue="receiveQueue" />
    </rabbit:bindings>
</rabbit:direct-exchange>

<!-- taskListener bean listens to the queue -->
<rabbit:listener-container connection-factory="rabbitFactory">
    <rabbit:listener queues="receiveQueue" ref="taskListener" />
</rabbit:listener-container>

对于主人:

<!-- Message listener -->
<bean id="taskListener" class="tgi.docgen.amqp.TypedListener" />
  <bean id="master" class="tgi.docgen.node.Master">
      <property name="docgenExchange" value="???" />
      <property name="receiveQueue" value="???" />
  </bean>

<!-- Rabbit infrastructure -->
<!-- Anonymous reception queue -->
<rabbit:queue id="receiveQueue" auto-delete="true" durable="false" />

<!-- Master -> Slave exchange -->
<rabbit:direct-exchange name="docgenExchange" auto-delete="true" durable="false" />

<!-- taskListener listens to reception queue -->
<rabbit:listener-container connection-factory="rabbitFactory">
    <rabbit:listener queues="receiveQueue" ref="taskListener" />
</rabbit:listener-container>

这就是我想知道的事情

1)如何避免在两个XML配置文件中重复交换的名称? Master项目依赖于Slave项目,因此我可以轻松地在它们之间共享配置,但我不知道如何提取交换名称并在两个文件中使用它。

2)正如我所说,Master会将任务发送到交换机,并且必须在任务中写下其回复队列的名称。如何在Master bean中注入队列名称和交换?那就是:我如何在上面的配置文件中分别用“docgenExchange”替换两个???和匿名回复队列的生成名称?

1 个答案:

答案 0 :(得分:0)

那不是Spring Integration 2吗?

无论如何,我几天前为自己做了一个“概念证明”,正是你想要存档的东西。见https://github.com/knalli/task-worker

关于你的第一个问题:嗯,这取决于你。这取决于你究竟想要什么。我认为在两个项目中都没有问题 - 项目主服务器和项目从服务器 - 中央队列的名称。当然,这不应该是硬编码,而是配置选项。并且您可以为两个运行程序提供相同的外部属性,这些外部属性将用作Spring配置上下文中的Property Placeholder Bean。

第二个有点奇怪:也许你有一个旧的例子或者这是Spring Ingegration 1.x ..我不知道。无论如何:您不需要提供回复名称。因为如果您使用AMPQ Gateway Beans,这将由Spring Integration自动处理。

我引用了守护进程的入站AMQP网关配置的配置端口(这是您的“奴隶”):

<int-amqp:inbound-gateway 
    connection-factory="connectionFactory" 
    request-channel="requestChannel"
    reply-channel="replyChannel" 
    error-channel="errorChannel"
    queue-names="${rabbitmq.queue}"/>

每个提到的频道 - requestChannel,replyChannel,errorChannel - 只能通过简单的方式在Spring Integration Context中注册

 <int:channel id="requestChannel"/>

对于AMQP - 意味着Message Broker配置 - 除了<rabbit:queue>项之外不需要更多配置部分。

此外,我使用Java注释将消息连接到服务接口(@Gateway)和服务类(@ServiceActivator)。这大大减少了配置。