简介
RabbitMQ是一个消息代理。它的工作就是接收和转发消息。你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处。在这个比喻中,RabbitMQ就扮演着邮箱、邮局以及邮递员的角色。
RabbitMQ和邮局的主要区别在于,它处理纸张,而是接收、存储和发送消息(message)这种二进制数据。
名词解释
Produce:生产者,即消息的制造者
Consume:消费者,即消息的使用者
Queue:MQ中的队列,所以消息都会从队列中排队进出,先入先出
Exchange:交换机,MQ中的调度器
连通基本步骤
Produce:
- 创建与MQ服务的连接
- 创建管道
- 创建交换机及类型(如果有则不创建)
- 创建队列(如果有则不创建)
- 往指定交换机扔消息
- 刷新缓存,保证消息成功丢出去(关闭连接)
Consume:
- 创建与MQ服务的连接
- 创建管道
- 创建交换机及类型(如果有则不创建)
- 创建队列(如果有则不创建)
- 绑定队列到交换机
- 从队列中获取消息
工作模式
- PTP(point to point)点对点
Produce生产消息体,使用匿名交换机(exchange=’’’),与消费者绑定相同的队列(队列名称一样),生产者生产一条消息,往MQ里扔一条,消费者消费一条数据。此模式生产者与消费者是一对一存在的。
- 工作队列
PTP模式的拓展,即N消费者的PTP模式。N个消费者同时监听同一个队列,同样使用默认交换机。其默认采用轮询的方式来分配哪个消费者消息哪条消息。我们可以通过添加消费者来处理消费过多的问题。
- 发布/订阅模式
此模式不再使用匿名交换机,而是自定义的交换机。交换机类型分为四种:直连交换机、扇形交换机、主题交换机、头交换机。此图为扇形交换机的例子,即发消息到所有与之绑定的队列。
生产者生产消息->交换机->绑定的队列->消费者
- 路由模式
此图为使用直连交换机的例子,当队列绑定交换机时设置一个绑定key,消息通过这个routing_key与绑定key的对应来决定该消息是否缓存到某队列中。
举例:消息绑定key为orange,消息传输过来的routing_key为orange,则该消息进Q1队列。消息绑定key为black,消息传输过来的routing_key为black,则该消息进Q2队列。
应用场景举例:应用系统将日志推送到日志消费者(C1为打印日志服务,C2为存储日志服务)。当下想根据日志级别来做不同的响应,C1的执行是不区分日志类型的,C2的执行则要根据日志类型区分出error级别的日志再进行存储(为了节省硬盘空间)
- 主题交换机模式
主题交换模式提供一种可匹配的路由,适用于更为复杂的应用场景。
匹配规则:
*代表一个单词
#代表一个或多个单词
routing_key推荐使用XX.XX.XX的书写格式。通过匹配则交换机分配到对应的列队中借消费者消费
知识点
- 多消费者模式下的调度方式
轮询。但假设有两个消费者C1,C2。奇数条消息进C1,偶数条消息进C2。如果C1比较慢的话,这样会造成C1的消息堆积,C2无所事事。此时可以设置prefetch_count=1,即表明同一时刻一个消费者不能发送超过一条消息,直到他已经对上条消息做成响应。
- 消息确认
在消费比较耗时的消息时,如果消费者执行到一半时挂掉,这时MQ是不知道的,并且此条消费被认为已经消费掉了,会造成消息丢失的情况。加入消息确认后,消息被拿走后MQ不会立即删除掉本条消息。消费者在消费消息成功后会向MQ发送一个ack确认标识表示已经消费完成,此时MQ将本条消息删除。如果消费者在消费过程中挂掉,消费超时后MQ会认为这个消费者联系不上了,会自动将本条消息发送给其它消费者。
- 消息持久化
没有消息持久化的MQ会在宕机后的重启丢失在先前在队列中缓存的消息。
durable=True即代表开启持久化。注:消息持久化并不保证消息百分百不会丢失,因为MQ在接受消息到持久化的过程中也是需要时间的,这段时间内挂掉,消息会丢失。可以在代码中加入事务控制来避免此情况。
- 临时队列
当我们创建队列时只想要随便创建一个队列,而不关心队列信息时,我们可以创建一个临时队列。同时队列名也可以是随机名,只需要在创建队列时不给定队列名参数即可。此外将exclusive=True设置后,消费者与MQ断开连接,这个临时队列则删除
- routing_key
生产者发送消息时所指定的队列信息。在使用匿名交换机时,routing_key为队列名;在使用具体交换机时,routing_key为与该交换机绑定的绑定名。
- 交换机类型
直连交换机 (direct):交换机会拿着消费的routing_key与其所有直接满足绑定名的绑定队列通信 。
扇形交换机 (fanout):交换机会给所有绑定该交换机的队列通信。
主题交换机 (topic):交换机会拿着消费的routing_key给所有满足匹配的绑定名的绑定队列通信。