消息队列之RabbitMQ

Posted 肝铁侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息队列之RabbitMQ相关的知识,希望对你有一定的参考价值。

一、什么是MQ?

MQ是message queue的缩写,本质上是个队列,FIFO先入先出原则,队列中存放的是message,是一种跨进程的通信机制,用于上下游传递信息。在互联网程序架构中,MQ是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了MQ以后,消息发送只需要依赖MQ,不用依赖于其他服务。

二、为什么要用MQ?

(一)流量消锋

如果我们的订单系统最多能够处理掉一万次订单,这个处理能力应付正常时段的下单是搓搓有余了,但是如果在高峰期,比如淘宝的双11活动,有超过一万次的下单操作,系统则是处理不了的,需要做出相应的限制机制。那么如果我们使用消息队列作为缓冲,我们可以取消这个限制,将一秒内下的订单分散成一段时间来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作,但是比起限制下单的体验要好得多。

(二)应用解耦

以电商为例,应用中由订单系统、库存系统、消息系统、支付系统等等,在用户创建订单以后,如果耦合的如上系统任何一个出现了故障,那么将导致下单功能异常。但是如果转变成消息队列的方式后,各个模块之间的依赖问题就会减少很多。比如如果下单的时候,消息系统出现了问题,需要一定的时间来修复,虽然消息系统出现了问题,但是其他模块是依旧可执行的,而消息系统需要发送的消息依旧存储在消息队列中,当消息系统修复好时,依旧可以成功发出对应的消息。

(三)异步处理

在传统模式中,订单系统调用支付系统,需要等待支付系统执行完毕后,返回执行结果,然后再进行支付系统的下一步操作,耦合度极高。但是使用消息队列,就可以解决这个问题,当订单系统调用支付系统后,支付系统开始执行,此时订单系统以后可以执行其他操作,当支付系统执行完毕后,会将返回结果放进消息队列中,再由消息队列转发给订单系统。

三、MQ的分类

(一)ActiveMQ

单机吞吐量万级,时效性ms级,可用性高,基于主从架构实现高可用性,消息可靠性较低的概率丢失数据。高吞吐量场景的使用较少。

(二)Kafka

为大数据而生的消息中间件,百万级TPS的吞吐量,再数据采集、传输、存储的过程中发挥着聚聚轻重的作用。单机写入TPS约在百万条/秒,最大的优点就是吞吐量高。时效性ms级,分布式,一个数据有多个副本,少数机器宕机不会丢失数据,不会导致不可用,消费者采用Pull的方式获取消息,消息有序。有Kafaka Web管理界面kafka-Manager。日志领域比较成熟,在大数据领域实时计算以及日志采集被大规模使用。
但是Kafka单机超过64个队列/分区,Load会发生明显的超高现象,队列越多,Load越高,发送消息的响应时间越长。使用短轮询的方式,实时性取决于短轮询的时间间隔,消费失败不支持重试。支持消费的顺序,但是一台代理宕机以后,就会产生消息乱序。

(三)RocketMQ

RocketMQ是出自阿里巴巴的开源产品,用JAVA语言实现,设计时参考的Kafka,并作出了一些改进。被阿里巴巴广泛应用在订单、交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。在阿里双11的活动中经历了多次考验,性能极佳。
单机吞吐量十万级,可用性高,分布式架构,消息可以做到0丢失,MQ功能较为完善,扩展性好,支持十亿级别的消息堆积,不会应为堆积导致性能下降。

(四)RabbitMQ

于2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。
使用erlang语言实现,由于其语言的高并发特性,性能较好,吞吐量万级,MQ功能计较完善,稳定易用跨平台,支持多种语言。

四、RabbitMQ

RabbitMQ是一个消息中间件,它接收并转达消息。将消息存储在RabbitMQ中,等待需要的服务去其中取对应的消息。主要用于消息的接收、存储以及转发。

(一)RabbitMQ后台管理界面

本文主要讲解RabbitMQ,它的安装在这里我们就不做过多介绍,网上一搜有很多教程。首先要下载erlang,配置好环境变量,然后下载RabbitMQ,配置好环境变量。配置完成后,启动sbin目录下的rabbitmq-server.bat,成功运行后,我们访问http://localhost:15672即可进入到管理界面。我们来看看它的管理界面:

(二)RabbitMQ的四大核心概念

1.生产者

产生数据时发送消息的角色。

2.交换机

一方面用来接收来自生产者的消息,另一方面它将消息推送到队列中。交换机必须确切地知道如何处理它接收地消息。是将消息丢弃还是推送到特定的队列,由交换机决定。

3.队列

队列是RabbitMQ内部使用的一种数据结构,尽管消息流经RabbitMQ和应用程序,但是他们只能存储在队列中。生产者将消息发送到一个队列,消费者就可以尝试从一个队列中接收数据。

4.消费者

消费者是一个等待接收消息的程序。生产者消费者和消息中间件大多时候不在同一机器上,同一个应用程序可以是生产者也可以是消费者。

(三)RabbitMQ的核心部分

1.RabbitMQ的六大模式

一、简单模式
二、工作模式
三、发布/订阅模式
四、路由模式
五、主题模式
六、发布/确认模式

2.RabbitMQ中的各名词介绍

①RabbitMQ工作原理

②Broker

接收和分发消息的应用,RabbitMQ Server就是Message Broker。

③Virtual host

当多个不同的用户使用同一个RabbitMQ Server提供服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchange/queue等。类似于网络中的namespace概念。

④Connection

publisher / consumer 和 broker之间的TCP连接。

⑤Channel

如果我们每一次访问RabbitMQ都建立一个Connection,那么在消息大量建立TCP Connection的开销将是巨大的,效率也很低。Channel实在connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯。channel有一个channel id,帮助客户端进和message broker识别channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立TCP connection的开销。

⑥Exchange

message到达broker的第一站,根据分发规则,匹配拆线呢表中的routing key,分发消息到queue中去。常见的交换机类型有:direct(point-to-point)直接交换机、topic(publish-subscribe)主题交换机、fanout(multicast)扇出交换机。

⑦Queue

消息最终被推送到这里等待消费者取走消费。

⑧Binding

exchange和queue之间的虚拟连接,binding中可以包含routing key,Binding信息被保存到exchange中的查询表中,用于message的分发数据。

3.死信队列

死信就是无法被消费的消息,一般来讲生产者将消息投递到Broker中以后就直接到队列里去了,然后消费者再从队列中取消息。但是在某些应用的特殊业务场景下,一些特殊的原因导致了队列中的某些消息无法被消费,这样的消息如果我们没有对其进行处理,就变成了死信,进而形成了死心队列。

为了保证数据不丢失,需要我们使用RabbitMQ的死信队列机制,当消息发生异常时,将消息存入死信队列中,等后续能够消费的时候再将消息从队列中拿出来消费。像下单成功以后在指定的时间内没有付款时,自动失效。

死信的来源:
一、消息TTL(存活时间)过期
二、队列达到最大长度,队列已经满了,无法再添加数据到队列中。
三、消息被拒绝(basic.reject 或 basic.nack)并且requeue=false

4.延迟队列

延迟队列的内部是有序的,最重要的就是它的演示属性了,演示队列中的元素就是希望在指定的时间到了以后才开始对消息进行处理。简单来说,演示队列就是用来存放需要在指定时间被处理的元素的队列。比如说订单在十分钟内未支付自动取消订单,比如说用户注册成功以后三天内没有登录我们就进行短信提醒。

以上是关于消息队列之RabbitMQ的主要内容,如果未能解决你的问题,请参考以下文章

消息队列之zeroMQ、rabbitMQ、kafka

Springboot与RabbitMQ上手之消息超时时间、队列消息超时时间(五)

消息队列之 RabbitMQ

转 消息队列之 RabbitMQ

快速入门分布式消息队列之 RabbitMQ(上)

SpringBoot之RabbitMQ的使用