RabbitMQ-01- 简介
2021-09-20 21:12:22 # MQ

简介

MQ

Message Queue,即消息队列。消息指的是两个应用间传递的数据。数据的类型有很多种形式,可能只包含文本字符串,也可能包含嵌入对象。

“消息队列(Message Queue)”是在消息的传输过程中保存消息的容器。在消息队列中,通常有生产者和消费者两个角色。生产者只负责发送数据到消息队列,谁从消息队列中取出数据处理,他不管。消费者只负责从消息队列中取出数据处理,他不管这是谁发送的数据。

特点

业务无关。MQ具有普适性质,无需关注上层项目的模型、种类等因素,只需要做好消息分发即可。

FIFO。由于MQ本身的底层数据机构就是队列,所以具有FIFO性质。

容灾。对于消息队列而言,消息可以被持久化,即便没有将消息发出去或正在发送时遇到了不可预知的情况如断电,MQ依然可以在恢复服务后把之前的消息找到并重新发送。

性能。消息队列具有很高的吞吐量,进而可以提高系统的整体性能。

功能

系统解耦。如系统A,产出了数据\(dataA\),下游还有系统B,系统C,需要接收系统A的数据,如果仅仅通过调用系统A的对外接口,不易于升级系统,且可能导致等待时长变高,需要等会下游系统的返回才可以进行下一步。如果使用MQ,则只需要将消息发送到MQ中间件,至于谁需要这些消息,下游的系统自己就会去接收消息。

img

异步调用。假如存在调用链路\(A->B->C->D\)。由于每个调用都需要时间,整个链路完成可能需要\(2s\),但是实际上有很多事情可以异步完成,如点外卖过程中,用户下单后,需要调用支付模块进行付费,然后需要通知商户接单,同时也需要通知骑手,通知骑手的时候也需要调用骑手的智能匹配算法,还需要考虑距离,天气,商品库存等等。这一系列问题并不是用户下单时需要考虑的问题,这些后续步骤可以通过消息来异步的调用。而如果使用MQ,用户只需要付费,支付模块将消息发送给MQ,由MQ通知其他模块进行后续步骤。如果使用MQ,系统A发送数据到MQ,然后就可以返回响应给客户端,不需要再等待系统B、C、D的响应,可以大大地提高性能。对于一些非必要的业务,比如发送短信,发送邮件等等,就可以采用MQ。

img

流量削峰。有时系统的请求量突然上升,可能这只是系统的活动期间,其余时间流量比较正常,我们无需为这段时间额外扩容服务器。只需要先将消息存入MQ中,MQ会以系统正常的吞吐量处理。如果使用MQ,系统A不再是直接发送SQL到数据库,而是把数据发送到MQ,MQ短时间积压数据是可以接受的,然后由消费者每次拉取2000条进行处理,防止在请求峰值时期大量的请求直接发送到MySQL导致系统崩溃

img

RabbitMQ

开源、跨语言。不仅支持Java,还对Python,Ruby,PHP等其他服务端语言有很好的支持。

Erlang语言编写。性能好,通信能力强,延迟低,具有原生\(Scoket\)的性能。

应用广泛,许多互联网公司,如电商,外卖,打车等。

社区丰富,\(api\)丰富。

Rabbit MQ的实现

image-20210920214458593

\(Server\):服务

\(Connection\):与\(Server\)建立连接

\(Channel\):信道。几乎所有的操作都在信道上进行,客户端可以建立多个信道。

\(message\):消息。由\(properties\)\(bady\)组成。\(properties\)是对消息的一些描述,如延迟,优先级。\(body\)是消息的实体。

\(virual\quad host\):虚拟主机。实现了顶层隔离。同一个虚拟主机下,不能有重复的交换机和\(queue\)。比如有A项目,B项目,必须先指定把消息投递到哪个项目。

\(Exchange\):交换机。接收生产者的消息,然后根据指定的路由器去把消息转发到所绑定的队列上。

\(binding\):绑定交换机和队列。

\(routing \quad key\):路由键。路由规则,虚拟机可以用它来确定这个消息如何进行一个路由。

\(queue\):队列。消费者只需要监听队列来消费消息,不需要关注消息来自于哪个\(Exchange\)

消息流转过程

img

消息生产者连接到RabbitMQ Broker,创建connection,开启channel。

生产者声明交换机类型、名称、是否持久化等。

生产者发送消息,并指定消息是否持久化等属性和routing key。

exchange收到消息之后,根据routing key路由到跟当前交换机绑定的相匹配的队列里面。

消费者监听接收到消息之后开始业务处理。