多connect-factory时配置exchange, queue需使用declared-by
背景:
项目中需要监听多个rabbitmq
服务器或者发消息到多个rabbitmq
服务器,项目启动报错。结果如下:
|
|
问题原因:从错误来看,大概意思是重复声明了“exchange”。研究了下spring-rabbit中“exchange”的配置。
基本信息:
Broker
:简单来说就是消息队列服务器实体,可以把一个rabbitmq server当作一个broker。
vhost
虚拟主机:一个broker里可以开设多个vhost,用作不同用户的权限分离,也可以把他看作明名空间。vhost之间相互完全隔离,不同Vhost之间无法共享Exchange和Queue。(如果不指定vhost,默认是”/“)
Exchange
:Exchange是属于Vhost的。同一个vhost不能有重复的Exchange名称(这个就是错误原因)。
Channel
:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。
项目配置
|
|
rabbit:connection-factory
在spring-rabbit
中,管理消息协商器(broker)连接的核心组件是ConnectionFactory
这个接口。 ConnectionFactory
提供了 org.springframework.amqp.rabbit.connection.Connection
(com.rabbitmq.client.Connection
的包装类)实例的连接与管理。
CachingConnectionFactory
:是ConnectionFactory
的在Spring AMQP中唯一实现,它创建一个连接代理,使程序可以共享连接。
Connection
提供一个createChannel
的方法。CachingConnectionFactory
的实现能支持channels
的缓存,并且能根据区分是事务性或非事务性各自独立。同时,CachingConnectionFactory
也提供hostname
的构造函数,并且可以设置username
、password
、setChannelCacheSize
等方法。CachingConnectionFactory
默认channel cache
大小为1,如果想改变可以用setChannelCacheSize
设置 channel-cache-size
的大小。
rabbit:template
Spring AMQP提供了一个发送和接收消息的操作模板类AmqpTemplate
。 AmqpTemplate它定义包含了发送和接收消息等的一些基本的操作功能。RabbitTemplate
是AmqpTemplate的一个实现。
RabbitTemplate
支持消息的确认与返回,为了返回消息,RabbitTemplate
需要设置mandatory
属性为true,并且CachingConnectionFactory
的publisherReturns
属性也需要设置为true。返回的消息会根据它注册的RabbitTemplate.ReturnCallback setReturnCallback
回调发送到给客户端,一个RabbitTemplate
仅能支持一个ReturnCallback
。
为了确认Confirms消息, CachingConnectionFactory
的publisherConfirms
属性也需要设置为true,确认的消息会根据它注册的RabbitTemplate.ConfirmCallback setConfirmCallback
回调发送到给客户端。一个RabbitTemplate
也仅能支持一个ConfirmCallback
.
messageConverter
AmqpTemplate 定义提供了各种发送和接收委拖给MessageConverter
转化对象消息的方法。MessageConverter
本身比较简单,它提供了消息对象的转化,可将object转化成Message 对象,或者将Message 对象转化成Object对象。它提供了默认的SimpleMessageConverter
实现,以及第三方的MessageConverter
,如Jackson2JsonMessageConverter
,MarshallingMessageConverter
等,来处理消息与对象之间的转换。
rabbit:admin
当CachingConnectionFactory
缓存模式是CHANNEL
时(默认的), RabbitAdmin
实现会在同一个ApplicationContext
中自动延迟声明 Queues
,Exchanges
和 Bindings
.
默认情况下,所有queues
, exchanges
,和bindings
都可通过应用程序上下文中所有RabbitAdmin
实例来声明(设置了auto-startup="true"
).
从1.2版本开始,可以有条件地声明元素.当程序连接了多个brokers
,并需要在哪些brokers
上声明特定元素时,特别有用.
默认情况下,如果没有提供declared-by
(或是空的), auto-declare
属性则为true,那么所有RabbitAdmin
将声明对象(只要admin的auto-startup
属性为true,默认值)
错误原因:在这个例子中RabbitAdmin有2个,并且
exchange‘lamia.live.start' 没有提供
declared-by声明。故此,该
exchange被这2个
RabbitAdmin都声明了一次。而且刚好这2个RabbitAdmin使用的是同一个服务器上面的同一个
vhost. 同一个
vhost不能有重复的
Exchange`名称。所以,项目启动报错。
正确姿势
在exchange
和queue
上面加上declared-by
.
|
|