Jan*_*ert 13 rabbitmq federation spring-amqp rabbitmq-shovel
我有三个客户端,每个客户端都有自己的RabbitMQ实例,我有一个应用程序(让我们称之为appA),它有自己的RabbitMQ实例,三个客户端应用程序(app1,app2,app3)想要在appA上使用服务.
appA上的服务需要RPC通信,app1,app2和app3每个都有一个booking.request队列和一个booking.response队列.

使用铲子插件,我可以将所有booking.request消息从app1-3转发到appA:
Shovel1
virtualHost=appA,
name=booking-request-shovel,
sourceURI=amqp://userForApp1:password@app1-server/vhostForApp1
queue=booking.request
destinationURI=amqp://userForAppA:password@appA-server/vhostForAppA
queue=booking.request
setup another shovel to get booking requests from app2 and app3 to appA in the same way as above.
Run Code Online (Sandbox Code Playgroud)
现在appA将响应预订请求.响应队列,我需要在rabbitMQ-appA上的预订响应消息回到app1,app2或app3上的正确booking.response队列,但不是所有人 - 如何在rabbitMQ-appA上设置一个铲子/联合队列,它会将响应转发回正确的rabbitMQ(app1,app2,app3),这些兔子期望在他们自己的booking.response队列中得到响应?
所有这些应用程序都使用spring-amqp(如果相关的话)另外,我可以在Spring中设置一个rabbitMQ模板,它可以监听多个rabbitMQ队列,并从每个队列中消耗掉.
从文档中,这是典型的消费者的样子:
<rabbit:listener-container connection-factory="rabbitConnectionFactory">
<rabbit:listener queues="some.queue" ref="somePojo" method="handle"/>
</rabbit:listener-container>
Run Code Online (Sandbox Code Playgroud)
是否可以指定多个连接工厂,即使连接工厂属于同一个RabbitMQ实例,也只是指定不同的vhost:

更新:
基于Josh的回答,我有多个连接工厂:
<rabbit:connection-factory
id="connectionFactory1"
port="${rabbit.port1}"
virtual-host="${rabbit.virtual1}"
host="${rabbit.host1}"
username="${rabbit.username1}"
password="${rabbit.password1}"
connection-factory="nativeConnectionFactory" />
<rabbit:connection-factory
id="connectionFactory2"
port="${rabbit.port2}"
virtual-host="${rabbit.virtual2}"
host="${rabbit.host2}"
username="${rabbit.username2}"
password="${rabbit.password2}"
connection-factory="nativeConnectionFactory" />
Run Code Online (Sandbox Code Playgroud)
然后我将使用SimpleRoutingConnectionFactory来包装两个连接工厂:
<bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.SimpleRoutingConnectionFactory">
<property name="targetConnectionFactories">
<map>
<entry key="#{connectionFactory1.virtualHost}" ref="connectionFactory1"/>
<entry key="#{connectionFactory2.virtualHost}" ref="connectionFactory2"/>
</map>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
现在,当我声明我的rabbitMQ模板时,我会将它指向SimpleRoutingConnectionFactory而不是单个连接工厂:
<rabbit:template id="template" connection-factory="connectionFactory" />
Run Code Online (Sandbox Code Playgroud)
...然后使用模板,因为我通常会使用它...
<rabbit:listener-container
connection-factory="connectionFactory"
channel-transacted="true"
requeue-rejected="true"
concurrency="${rabbit.consumers}">
<rabbit:listener queues="${queue.booking}" ref="TransactionMessageListener" method="handle" />
</rabbit:listener-container>
Run Code Online (Sandbox Code Playgroud)
//并从两个rabbitMQ实例中消耗消息
......而且......
@Autowired
private AmqpTemplate template;
template.send(getExchange(), getQueue(), new Message(gson.toJson(message).getBytes(), properties));
Run Code Online (Sandbox Code Playgroud)
//并且消息发布到两个队列
我对么?
看看org.springframework.amqp.rabbit.connection.AbstractRoutingConnectionFactory.它允许您为不同的vhost或不同的rabbitmq实例创建多个连接工厂.我们将它用于多租户rabbitmq应用程序.
已经有一段时间了,但是如果您使用 Spring,您可以根据需要创建任意数量的连接工厂,并使用它们自己的配置(主机、用户/通行证、虚拟主机等),就像您所做的那样:
@Bean
@Primary
public ConnectionFactory amqpConnectionFactory1() {
final CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("...");
connectionFactory.setUsername("...");
connectionFactory.setPassword("...");
connectionFactory.setVirtualHost("...");
return connectionFactory;
}
@Bean
public ConnectionFactory amqpConnectionFactory2() {
final CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
// ...
return connectionFactory;
}
Run Code Online (Sandbox Code Playgroud)
你的兔子管理/模板是这样的:
@Bean
@Primary
public RabbitAdmin rabbitAdmin1() {
return new RabbitAdmin(amqpConnectionFactory1());
}
@Bean
public RabbitAdmin rabbitAdmin2() {
return new RabbitAdmin(amqpConnectionFactory2());
}
// ...
@Bean
@Primary
public RabbitTemplate rabbitTemplate1() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(amqpConnectionFactory1());
// ...
return rabbitTemplate;
}
@Bean
public RabbitTemplate rabbitTemplate2() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(amqpConnectionFactory2());
// ...
return rabbitTemplate;
}
Run Code Online (Sandbox Code Playgroud)
@Primary请注意,如果您未明确通知 Spring 不知道选择哪一个主 bean,则您必须提供标签来启用一个主 bean name。
拿到手后,只需将它们正常地沿着您的组件注入即可:
@Autowired
private RabbitTemplate template;
// ...
@Autowired
@Qualifier("rabbitTemplate2") // Needed when want to use the non-primary bean
private RabbitTemplate template;
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!:)
| 归档时间: |
|
| 查看次数: |
3467 次 |
| 最近记录: |