一、命名规范
1.Queue设计
- A生产消息,指定由B消费,这样的话就定义一个队列。
- A生产消息,由B和C共同消费,因B和C都为多个节点,故系统定义为两个不同队列,虽然消息是相同的。
- A和B生产消息,由C消费,可定义一个队列,也可定义两个队列。为便于区分消息生产者和消费者,定义消息队列名为生产者模块简称_消息参数_消费者模块简称,按照此思路,此种场景也需定义两个队列。
如示例,队列名与队列ID一致:
2.Exchange设计
如示例,交换机exchange命名以消费方BasicDev01与交换机ID保持一致,路由key为队列名_key
3.Message 设计
消息类型根据异常推进机制和实际业务分成三类:
- 同步调用异常重发机制。此场景发生在客户端同步调用服务端时出现异常,客户端生产消息推送至MQ服务器,自身消费此消息并重发同步接口调用服务端。此场景下生产者和消费者为同一模块。以支付工具调用银行网关1000接口为例,队列名称即为Payt_Bgate1000Request_Payt;
- 同步返回异步重发机制。此场景发生在客户端同步调用服务端,服务端同步返回响应后同时发送异步通知。服务端推送消息至MQ服务器,由客户端消费该消息并进行业务逻辑处理。以支付工具调用银行网关1000接口,银行网关响应1000消息为例,队列名称即Bgate_Bgate1000Response_Payt。
- 异步推送机制。此场景为最普通的MQ应用,双方处理能力不对等及处理时效性要求不高场景。以银行网关交易成功后异步通知清分系统为例,消息编号为1000,队列名称即为Bgate_Clr1000Message_Clr。
按照上文所例,消息内容分成三类:
- 系统简称+接口编号+Request;
- 系统简称+接口编号+Response;
- 系统简称+接口编号+Message;
按照上文所例,消息绑定的交换机命名以消费模块命名,如消息队列Bgate_Bgate1000Response_Payt,则交换机为Payt。
二、命令使用
1.【推荐】消息发送
消息发送时,如果存在并发的情况,尽量使用sendDataToMQByRoutingKey 方法进行消息发送,不要使用sendDataToMQ 方法。
- 【推荐】禁用命令
消息发送时,如果存在并发的情况,禁止使用 producer.setRoutingKey()方法
三、XML配置
1.【推荐】权限隔离
RabbitMQ 可以虚拟消息服务器 virtualHost, 每个virtualHost 相当于一个独立的RabbitMQ消息服务器,每个virtualHost 是相互隔离的 exchange 、message、queue 互不相通。
正例:不相干的业务采用vitualHost做隔离。
2.【推荐】消息,队列,交换机声明
要保证消息不丢失,需要做到三点
- 消息是持久化
- 队列是持久化
- 交换机是持久化
其次要注意队列,交换机什么是否自动删除,排他性设置等。
- 消息声明
消息需要设置成持久化的发送方式,在Spring整合RabbitMQ默认是持久发送模式的。
DeliveryMod 设置为2时,消息持久化
- 队列持久化声明
声明队列持久化设置 durable=“true”
队列不自动删除 auto-delete=“false” 这里不自动删除的意思是,即使没有任何消费者订阅该队列,队列也不会删除,如果设置成true,当没有消费者订阅队列时,队列删除。exclusive=“false”设置成false是指不排他,不同连接都可见,如果是true,只对首次声明他的连接可见,并且在连接断开时自动删除,并且及时设置了auto-delete=“false”也会自动删除。但是同一个连接的不同信道(Channel)可以访问同一个创建的排他队列。
交换机声明
交换机声明需要声明持久 durable=”true”
不自动删除auto-delete=”false”设置成false 表示的不自动删除,但是如果设置成true 表示自动删除。这里自动删除的意思是:当队列或者交换器都与之解绑,交换机会自动删除,不能认为是客户端与之断开来连接,交换机删除。
3.【建议】多个连接时交换机和队列的声明
需要使用spring-rabbit-1.2.xsd
不同的ConnectionFactory 设置有不同ID的rabbit:admin
声明队列和交换机,需要制定哪个 rabbit:admin
队列声明
交换机声明
4.【推荐】