RabbitMQ---基础概念

    1.什么是消息中间件?

    消息(Message)是指在应用间传送的数据。这些数据可以为文本字符、JSON串、或者内嵌对象。

    消息中间件(Message Queue Middleware,简称MQ)是指利用高效可靠的消息传递机制来进行平台间的通信,通过数据通信来达成分布式系统的集成。

    2.消息中间件的传递模型

    2.1.点对点(P2P,Point-To-Point)模式

    2.2.发布/订阅(Pub/Sub)模式

    2.消息中间件的作用

    2.1.解耦:比如购买商品,下单完成后紧接着需要物流发货,如果这两个流程放在同一个系统会造成业务逻辑链特长,这时就会考虑将下单和物流发货设计成两个服务,服务间通过接口或者消息中间间来进行通信,如下图所示。

RabbitMQ---基础概念

    2.2.冗余(存储):消息中间件具有消息持久化的能力,如果消费端速度赶不上生产者发送消息的速度,这时消息可以被持久化到中间件的服务上,等待消费者慢慢消费,生产者端不会阻塞,加大了系统吞吐量。

    另外如果消费者服务端宕机,由于消息中间件具有消息堆积能力,生产者端仍然可以将消息发送给中间件,不会受到任何影响,等消费者服务重启后,这时可以再从中间件获取消息消费。

    最后MQ为了保证消息的可靠性,防止消息丢失,消息中间件提供了消息确认机制,只有消费端明确给MQ发送消息成功消费的讯号后,MQ才会删除该消息。在未接收到消费讯号前,会一直存储在MQ上。

    2.3.流量削峰:最常见的是在秒杀场景中,用户购买商品完整的流程可能包含:下单、扣库存、发短信、发红包、物流配送,如果整个流程在一个事务或者说线程中执行完,那执行时间是很长的,再加上在秒杀高并发的场景下,服务器压力大,这个时间可能更长。如何优化?消息中间件,如下图所示:

RabbitMQ---基础概念

    加入消息中间件后,下单完成后,该事务内只需要在发送四条消息分别给库存服务,短信服务,红包服务,物流服务,然后就可以给客户端响应了,这样减短了整个事务链的长度,增加了系统吞吐量。

    2.4.可恢复性:当平台一部分服务失效时,不会影响到整个系统。消息中间件降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入消息中间件中的消息仍然可以在系统恢复后进行处理。

    2.5.缓冲:由于MQ有消息堆积能力,在生产端和消费端之间的MQ服务就可以作为缓冲层来降低消费端的压力,比如在秒杀场景中,给前端服务加入MQ后,高并发的请求过来后只需要将请求转化为消息投递到MQ后,就可以响应信息了,而消费者这边可以按照本身服务器的负载能力去消息队列中获取消息消费。

    2.6.异步通信:在很多时候应用不想也不需要立即处理消息,消息中间件提供了异步处理机制,允许应用把消息投递到中间件中,然后消费端在需要的时候慢慢处理。

    3.RabbitMQ简介

    RabbitMQ是采用Erlang语言实现AMQP(Advance Message Queuing Protocol,高级消息队列协议)协议的消息中间件,它最初起源于金融系统,用于在分布式系统中转发消息。

    4.RabbitMQ的特点

  • 可靠性:RabbitMQ使用一些机制来保证可靠性,如持久化、传输确认以及发布确认等。
  • 灵活的路由:在消息进入队列之前,通过交换器来路由消息。对于典型的路由功能,RabbitMQ已经提供了一些内置的交换器来实现自己的交换器。
  • 扩展性:多个RabbitMQ节点可以组成一个集群,也可以根据实际业务情况动态的扩展集群中节点。
  • 高可用性:队列可以在进群中的机器上设置镜像,使得在部分节点出现问题的情况下队列依然可用。
  • 多种协议:RabbitMQ除了原生支持AMQP协议,还支持STOMP、MQTT等多种消息中间件协议。
  • 多语言客户端:RabbitMQ几乎支持所有的常用语言,比如Java、Python、Ruby、PHP、C#、JavaScript等。
  • 管理界面:RabbitMQ提供了一个简单易用,但功能齐全的用户界面,使得用户可以监控和管理消息、集群中的节点等。
  • 插件机制:RabbitMQ提供了丰富的插件,以实现从多方面进行扩展,同时我们还可以编写自己的插件。

    4.RabbitMQ相关概念

    RbbitMQ整体上市一个生产者和消费者模型,主要负责接收消息、存储消息、转发消息。

    RabbitMQ的整体模型架构如图所示:

    RabbitMQ---基础概念

    Message:消息,消息一般包含两个部分:消息体(Payload)和标签(Label)。在实际应用中,消息体一般是一个带有业务逻辑结构的数据,比如Json字符串,当然也可以进一步对消息体进行序列化。消息的标签是用来表述这条消息的,比如一个交换器名称和一个路由键。

    Producer:生产者,就是投递消息的一方。生产者创建消息,然后发布到RabbitMQ中。

    Consumer:消费者,就是接收消息的一方。

    Broker:消息中间件的服务节点。对于RabbitMQ来说,一个RabbitMQ Broker可以看作一个RabbitMQ服务节点或者服务实例。大多数情况下也可以将一个RabbitMQ Broker看作一台RabbitMQ服务器。

    Queue:队列,是RabbitMQ的内部对象,用于存储消息。RabbitMQ中的所有消息都只能存储在队列中,这一点跟Kafka这种消息中间件相反,Kafka将消息存储在topic(主题)这个逻辑层面,而相对应的队列逻辑只是topic实际存储文件中的位移标识。

    RabbitMQ的生产者生产消息并通过交换机和路由键最终投递到队列中,消费者可以从队列中获取消息并消费。多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin,即轮训)给多个消费者进行处理,而不是每个消息都收到所有的消息。

    RabbitMQ不支持队列层面的广播消费,如果需要广播消费,需要进行二次开发。

    Exchange:交换器。它是用来接收生产者传递的消息,然后通过指定的路由键将消息路由到对应的一个或多个队列中,如果路由不到,或许会返回给生产者,或者直接丢弃。

    RabbitMQ中的交换器有四种类型,不同的类型有着不同的路由策略。四种协议分别为:fanout、direct、topic、headers。AMQP协议里还提到另外两种类型:System和自定义,这里不予描述。

  • fanout:它会将所有发送到该交换器的消息路由到所有与该交换器绑定的队列中fanout 交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。fanout 类型转发消息是最快的。
  • direct:
  • topic:
  • headers:

    RoutingKey:路由键。生产者将消息发送给交换器的时候,一般会指定一个RoutingKey,用来指定这个消息的路由规则。

    Binding:绑定。RabbitMQ中通过路由键将交换器与队列关联起来,然后将他们绑定在一起,Binding就是将他们绑定在一起的路由规则。

    Connection:网络连接,比如一个TCP连接。客户端(生产者和消费者)和服务端(RabbitMQ Broker)创建网络连接Connection,基于Connection进行通信。

    Channel:信道,多路复用连接中的一个单独的双向通信数据流通道。信道是建立在真实的TCP连接内地虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。

    Connection可以用来创建多个Channel实例,但是Channel实例不能在线程间共享,应用程序应该为每个线程开辟一个Channel。多线程共享Channel实例是非线程安全的。

    Virtual Host:虚拟主机。每一个RabbitMQ服务器都能创建虚拟的消息服务器,我们称之为虚拟主机(Virtual Host),简称vhost。每一个vhost本质上是一个独立小型RabbitMQ服务器,拥有自己独立的队列、交换器及绑定关系等,并且它拥有自己独立的权限。vhost就像是虚拟机与物理服务器一样,它们在各个实例减提供逻辑上的分离。,为不同程序安全保密的运行数据,它既能将同一个RabbitMQ中的众多客户区分开,又可以避免队列和交换器等命名冲突。Vhost之间是绝对隔离的。如果在使用RabbitMQ达到一定规模的时候,建议用户对业务功能、场景进行归类区分,并为之分配独立的vhost。RabbitMQ默认创建的vhost为“/”。

    5.AMQP协议介绍

    RabbitMQ是AMQP协议的Erlang实现,当然RabbitMQ还支持STOMP、MQTT等协议,所以RabbitMQ的模型架构和AMQP协议是一样的。生产者(Producer)将消息(Message)发送给交换器(Exchange),交换器和队列(Queue)通过绑定建(BingingKey)绑定,当生产者发送消息时所携带的路由键(RoutingKey)和绑定键相匹配时,消息即被存入相应的队列之中,消费者可以订阅相应的队列来获取消息。

    上面提到的RabbitMQ中的交换器、交换器类型、绑定、路由键等都是遵循AMQP协议中相应的概念。

    AMQP协议本身包含三层。

  • Module Layer:位于协议最高层,主要定义了一些供客户端调用的命令,客户端可以利用这些命令实现自己的业务逻辑。例如Queue.Declare命令声明一个队列或者使用Basic.Consume订阅消费一个队列中的消息。
  • Session Layer:位于中间层,主要负责将客户端的命令发送给服务器,再将服务端的应答返回给客户端,主要为服务端和客户端之间的通信提供可靠性同步机制和错误处理。
  • Transport Layer:位于最底层,主要传输二进制数据流,提供帧的处理、信道复用、错误检测、数据表示等

    AMQP协议是一个通讯协议,是应用层的协议,AMQP是通过协议命令进行交互的。

  

    

转载于:https://my.oschina.net/u/3765527/blog/1826813