RabbitMq入门简介

MQ

Message Queue,即消息队列,可以认为是存储消息的管道,用来做消息传输。

消息队列是应用间的通信方式。通过消息中间件,发送端在发送消息后可以立即返回,由中间件确保消息的可靠传递。发送端和接收端可以都不知道对方的存在,达到解耦。

使用MQ的场景的类比:信件的邮寄,它有以下特征:

  • 发信人把信件放入邮箱。
  • 邮局收件人从邮箱收取信件,邮局接收后运送到目的地,再派邮差把邮件送出去。
  • 收信人从邮差处接收信件。

三个主要的过程中,发信人和收信人就类似于消息队列中的生产者(Producer)和消费者(Consumer),邮箱、邮局、邮差合称为消息代理(Broker)。

信件在MQ中称为消息(Message),可以是字符串文本或者二进制数据。

当前各大电商平台的秒杀活动中,MQ就可以用于处理峰值流量。也可以把任务拆解,异步处理对时延要求不高的服务。

常用的MQ包括:

  • RabbitMQ
  • Kafka
  • ActiveMQ
  • RocketMQ
  • ZeroMQ

关于几种常用MQ的优缺点对比,可以参考消息队列Kafka、RocketMQ、RabbitMQ的优劣势比较

本文主要介绍RabbitMQ。

RabbitMQ

RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。AMQP(Advanced Message Queue Protocol)高级消息队列协议,它是应用层协议的一个开放标准,为面向消息的中间件设计。

消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

优点:

  • 由erlang编写,性能较好,天生支持高并发
  • 吞吐量到万级,MQ功能比较完备
  • 健壮、稳定、易用、跨平台、支持多种语言、文档齐全
  • 开源提供的管理界面很好用
  • 社区活跃度高;

缺点:

  • erlang开发,源码不易理解,不利于做二次开发和维护
  • RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重
  • 需要学习比较复杂的接口和协议,学习和维护成本较高
基本术语

消息中间件的功能大致可以抽象为下图所示的过程。

在这里插入图片描述

生产者创建消息,消息被发布在队列中,最后消费者从队列中使用数据。

具体到 RabbitMQ,其内部逻辑大概如下图所示。

在这里插入图片描述

其中,

  • Publisher,消息的生产者,也是一个向交换器发布消息的客户端应用程序。
  • Exchange,交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
  • Binding,绑定,将Exchange与Queue关联起来。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
  • Queue,消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
  • Connection,网络连接,比如一个TCP连接。
  • channel,信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。
  • Message,消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
  • Consumer,消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。
  • Virtual Host,虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。
  • Broker,表示消息队列服务器实体。

RabbitMQ 具有如下特性:

  • Message acknowledgment(消息确认)

要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执后才将该消息从Queue中移除;如果RabbitMQ没有收到回执并检测到消费者的RabbitMQ连接断开,则RabbitMQ会将该消息发送给其他消费者(如果存在多个消费者)进行处理。

这是为了防止在消费者取出消息后,在处理过程中崩溃时导致的消息丢失。

只要连接没有断开,不存在timeout概念,一个消费者处理消息时间再长也不会导致该消息被发送给其他消费者,除非它的RabbitMQ连接断开。

注意,如果处理完业务逻辑后,没有发送回执给RabbitMQ,这将会导致严重的bug——Queue中堆积的消息会越来越多,消费者重启后会重复消费这些消息并重复执行业务逻辑。pub模型没有ack。

  • Message durability(消息持久化)

为了防止RabbitMQ服务崩溃导致的消息丢失,可以将Queue与Message都设置为可持久化的(durable),这样可以保证绝大部分情况下我们的RabbitMQ消息不会丢失。

但是当RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时RabbitMQ服务器就断电了,仍然会丢失数据。这个问题可以应用事务来解决。

  • Prefetch count(预取数量)

默认情况下,当多个消费者使用同一个Queue中的消息时,Queue会按顺序把消息均等分配到多个消费者。这里,如果某个消费者处理的任务总是非常耗时,另一个消费者分配的任务非常简单时,就会导致资料浪费。

通过设置prefetchCount来限制Queue每次发送给每个消费者的消息数,比如我们设置prefetchCount=1,则Queue每次给每个消费者发送一条消息,消费者处理完这条消息后Queue会再给该消费者发送一条消息。

  • routing key(路由键)

生产者总是将消息发送到Exchange,这里将指定一个routing key,由Exchange将根据路由规则将消息路由到一个或多个Queue中(或者丢弃)。

routing key需要与Exchange Type及binding key联合使用才能最终生效。

在Exchange Type与binding key固定的情况下,生产者就可以在发送消息给Exchange时,通过指定routing key来决定消息流向哪里。

RabbitMQ为routing key设定的长度限制为255 bytes。

  • Binding key(绑定键)

在绑定(Binding)Exchange与Queue的同时,一般会指定一个binding key。

在绑定多个Queue到同一个Exchange的时候,这些Binding允许使用相同的binding key。

binding key 并不是在所有情况下都生效,它依赖于Exchange Type,比如fanout类型的Exchange就会无视binding key,而是将消息路由到所有绑定到该Exchange的Queue。

  • Exchange Types(交换器类型)
    • direct,把消息路由到binding key与routing key完全匹配的Queue中
    • topic,与direct类型的Exchage相似,但匹配规则允许模糊匹配。其中,routing key为一个句点号“. ”分隔的字符串,binding key中可以存在两种特殊字符“”与“#”,用于做模糊匹配,其中“”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)
    • headers,Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配,一般不常用。
    • fanout,把所有发送到该Exchange的消息路由到所有与它绑定的Queue中,类似于广播

各类型的图示如下:

  1. direct

在这里插入图片描述
在这种场景中,

  • Exchange的类型为direct,绑定了Q1和Q2两个队列
  • Q1的绑定键为orange,Q2为black和green

如果生产者使用路由键 orange ,Q1会收到消息,如果使用路由键 black 或者 green,Q2会收到消息,其他任何消息都会被丢弃。

当然,两个队列可以设置为同一个绑定键,这里符合的消息会同时路由到两个队列,这跟Fanout的类型是一致的。

  1. topic

在这里插入图片描述
在这种场景中,Q1绑定了*.orange.*,Q2绑定了 ..rabbit 和 lazy.#。翻译成白话就是:

  • Q1会接收所有中间为orange的消息(假设共3个字段)
  • Q2会接收所有以 rabbit 结尾和以 lazy 开头的消息

当生产者使用:

  • quick.orange.rabbit 时,两个队列都会收到消息。
  • lazy.orange.elephant,同上。
  • lazy.pink.rabbit,Q2收到,且只收到一次。
  • quick.brown.fox,丢弃
  1. fanout

在这里插入图片描述
在这种场景中,生产者的所有消息被路由到所有队列中。

参考资料

RabbitMQ Introduction
消息队列之 RabbitMQ
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值