RabbitMQ使用详解
RabbitMQ:企业级消息队列,遵循AMQP协议,基于Erlang语言开发,在可靠性、易用性和高可用等方面都比较优秀的一个消息中间件。在互联网项目中,常见用途:
- 服务之间的业务解耦,避免发布时互相影响
- 异步数据处理,以快速返回应答,包括日志的收集和业务的处理
- 流量控制,避免瞬间突发数据影响到下游处理
传统意义上的队列,是一种数据结构,只是先进先出的一个模块而已,
而AMQP协议定义了如下两种角色和三个功能模块:
- 消息生产者Publisher角色:只负责发布消息,不关心消息给谁了
- 消息消费者Consumer角色:负责接收和处理消息
- Exchange:接收生产者发布的消息,并根据规则转发给Queue
- Queue:存储消息,并等待消费者过来接收处理
- Binding:定义Exchange和Queue之前的关联,以及消息转发规则RoutingKey
so,正确的使用RabbitMQ的方式,是要进行如下5个步骤的:
1. 创建一个Exchange
2. 创建一个Queue
3. 创建一个Binding,把Exchange和Queue关联起来
4. 应用程序A给Exchange发布消息
5. 应用程序B从Queue监听消息并处理
注意:Exchange和Queue之间可以添加多个绑定,例如:
1. 一个Exchange绑定到一个Queue
2. 一个Exchange绑定到多个Queue
3. 多个Exchange绑定到一个Queue
4. 一个Exchange多次绑定到一个Queue,RoutingKey不同
进阶概念:
Exchange、Queue和Binding,在创建时会有一些参数,这些参数指示了工作方式的不同,常用如下:
Exchange类型:
Exchange有4种类型fanout、direct、topic、headers(第4种本文不作介绍)
- fanout:广播类型,该Exchange收到的所有消息,会转发给绑定到它的所有Queue,即使设置了转发规则RoutingKey也不生效,因此该种类型的性能是最高的。
- direct:该Exchange会根据转发规则RoutingKey进行精确匹配,把消息转发给完全匹配RoutingKey的Queue。
- topic:该Exchange会根据转发规则RoutingKey进行模糊匹配,把消息转发给匹配RoutingKey的Queue,模糊匹配支持和#,其中匹配一个词,#匹配一个或多个词。—-注意:RabbitMQ中,模糊匹配必须以小数点分隔,如test.* 或test.*.abc或test.#或test.#.abc,不支持 test*,也不支持test.*abc
Exchange常用参数:
durable:是否持久化,如果设置为false,在RabbitMQ重启后,该Exchange会消失,需要重新创建。
autoDelete:是否自动删除,如果设置为true,并且绑定了Queue或其它Exchange,那么在最后一个取消绑定事件后,该Exchange会自动删除自己。
internal:如果设置为true,该Exchange将不能用于接收生产者消息,只能用于绑定到其它Exchange。
alternate-exchange:配置值为另一个Exchange,当该Exchange收到的消息,无法转发(没有匹配的route)时,会转发到配置的这个Exchange
Queue常用参数:
durable:是否持久化,如果设置为false,在RabbitMQ重启后,该Queue会消失,需要重新创建。
autoDelete:是否自动删除,如果设置为true,并且有消费者成功连接,那么在最后一个消费者取消连接后,该Queue会自动删除自己。
x-expires:闲置时长,毫秒,如果达到闲置时长,该Queue会自动删除自己,闲置表示:没有消费者连接、没有重新定义、没有调用过basic.get,注:可以与autoDelete共用。
x-message-ttl:消息生存时长,毫秒,如果指定时间内入队的消息没有被消费,那么该消息会被抛弃。
x-max-length:处于ready状态的消息最大个数,消息数超过该数量时,会删除最早入队的消息,以保证新消息入队。
x-max-length-bytes:同上,只是单位变成了消息占用空间字节数。
x-max-priority:该Queue支持的消息优先级数,例如设置为10,表示支持0~10共11个优先级,数字越大优先级越高,越优先投递,默认为0,注:非必要情况不建议使用优先级,会导致额外的CPU、内存和磁盘消耗和额外的Erlang进程。
x-dead-letter-exchange:设置了messageTtl时,过期的死信会转发到这个Exchange。
x-dead-letter-routing-key:对应x-dead-letter-exchange的转发规则,如果未设置,将使用死信本身的routingKey。
持久化简述:
RabbitMQ支持3个级别的持久化:Exchange、Queue、Message,
所以如果要确保已进入MQ的消息不丢失,那么要在这3个对象上都设置持久化。
场景示例:
一个Exchange多次绑定到一个Queue,RoutingKey不同的使用场景:
做的一个配置中心,给其它项目添加和读取配置用,不同项目之前的配置有些要隔离,有些有共用,
比如a项目和b项目都有个配置叫DbConstr,存储数据库连接串,但是value不同;a和b的公司名要共用,可以:
定义一个direct类型的Exchange:Exg1
a项目定义一个QueueA,跟Exg1做2次绑定:bind Exg1 RoutingKey:key.0 和 bind Exg1 RoutingKey:key.a
b项目定义一个QueueB,跟Exg1做2次绑定:bind Exg1 RoutingKey:key.0 和 bind Exg1 RoutingKey:key.b
发布公共消息时,消息的RoutingKey为:key.0
发布a项目的消息时,消息的RoutingKey为:key.a
发布b项目的消息时,消息的RoutingKey为:key.b