RabbitMQ教程 入门指南 原理解析分析

MQ: Message Queue, 消息队列。
开发者谈起名Rabbit:像兔子那样行动迅捷,而又拥有超强的繁殖力。

类比忆:消息 - 信件, 生产者 - 寄信者,消费者 - 收信人,Queue - 邮局,Exchange - 邮递员/邮箱。

RabbitMQ是一个实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的消息队列服务,用Erlang语言的。主要职责:接收、存储和转发消息。交换机模型。

特点:提供了基于存储和转发(A发送消息时,接收消息的B甚至不需要在线,防止A等待B阻塞)的应用程序之间的异步数据发送,即应用程序彼此不直接通信,而是与作为中介的消息中间件通信。消息中间件提供了有保证的消息发送,应用程序开发人员无须了解远程过程调用(RPC)和网络通信协议的细节。

消息队列中间件的作用

  • 解耦:在项目启动之初来预测将来会碰到什么需求是极其困难的。消息中间件在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口,这允许你独立地扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束即可。
  • 冗余(存储):有些情况下,处理数据的过程会失败。消息中间件可以把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。在把一个消息从消息中间件中删除之前,需要你的处理系统明确地指出该消息已经被处理完成,从而确保你的数据被安全地保存直到你使用完毕。
  • 扩展性:因为消息中间件解耦了应用的处理过程,所以提高消息入队和处理的效率是很容易的,只要另外增加处理过程即可,不需要改变代码,也不需要调节参数。
  • 削峰:在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果以能处理这类峰值为标准而投入资源,无疑是巨大的浪费。使用消息中间件能够使关键组件支撑突发访问压力,不会因为突发的超负荷请求而完全崩溃。
  • 可恢复性:当系统一部分组件失效时,不会影响到整个系统。消息中间件降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入消息中间件中的消息仍然可以在系统恢复后进行处理。
  • 顺序保证:在大多数使用场景下,数据处理的顺序很重要,大部分消息中间件支持一定程度上的顺序性。
  • 缓冲:在任何重要的系统中,都会存在需要不同处理时间的元素。消息中间件通过一个缓冲层来帮助任务最高效率地执行,写入消息中间件的处理会尽可能快速。该缓冲层有助于控制和优化数据流经过系统的速度。
  • 异步通信:在很多时候应用不想也不需要立即处理消息。消息中间件提供了异步处理机制,允许应用把一些消息放入消息中间件中,但并不立即处理它,在之后需要的时候再慢慢处理。

消息队列中间件的应用场景(不只是RabbitMQ)

  • 异步处理:在注册服务的时候,如果同步串行化的方式处理,让存储数据、邮件通知等挨着完成,延迟较大,采用消息队列,可以将邮件服务分离开来,将邮件任务之间放入消息队列中,之间返回,减少了延迟,提高了用户体验
  • 应用解耦:电商里面,在订单与库存系统的中间添加一个消息队列服务器,在用户下单后,订单系统将数据先进行持久化处理,然后将消息写入消息队列,直接返回订单创建成功,然后库存系统使用拉/推的方式,获取订单信息再进行库存操作
  • 流量削锋:秒杀活动中,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。
    服务器在接收到用户请求后,首先写入消息队列。这时如果消息队列中消息数量超过最大数量,则直接拒绝用户请求或返回跳转到错误页面;
    秒杀业务根据秒杀规则读取消息队列中的请求信息,进行后续处理
  • 日志处理:Kalfka消息中间件

消息队列的使用过程

类比忆:消息 - 信件, 生产者 - 寄信者,消费者 - 收信人,Queue - 邮局(邮路),Exchange - 邮递员/邮箱。

寄信人不能自己把信寄出到邮路,而必须交给邮递员处理。标签信息就是信封上写的寄信的路由信息,如果邮递员不能找到怎么寄出,他可以把信丢掉或者还给寄信人。

1、客户端连接到消息队列服务器,打开一个channel。
2、客户端声明一个exchange,并设置相关属性。
3、客户端声明一个queue,并设置相关属性。
4、客户端使用routing key,在exchange和queue之间建立好绑定关系。
5、客户端投递消息到exchange。
6、exchange接收到消息后,就根据消息的key和已经设由binding,进行消息路里,将消息投递到一个或多个队列里

ps:通过durable参数来进行exchang、queue、消息持久化

交换机模型:

几个概念说明:

Broker:简单来说就是消息队列服务器实体。
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
Producer:消息生产者,就是投递消息的程序。
Consumer:消息消费者,就是接受消息的程序。
Channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。

RabbitMQ交换机

RabbitMQ包含四种不同的交换机(邮箱)类型:

  • Fanout

    它会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。

  • Direct

    direct类型的交换器路由规则也很简单,它会把消息路由到那些Bindingkey和RoutingKey完全匹配的队列中。

  • Topic

    前面讲到direct类型的交换器路由规则是完全匹配BindingKey和Routingkey,但是这种严格的匹配方式在很多情况下不能满足实际业务的需求。topic类型的交换器在匹配规则上进行了扩展,它与direct类型的交换器相似,也是将消息路由到BindingKey和RoutingKey相匹配的队列中,但这里的匹配规则有些不同,它约定:

    • RoutingKey为一个点号“.”分隔的字符串(被点号“.”分隔开的每一段独立的字符串称为一个单词),如"com.rabbitmg.client"、“java.util.concurrent”、“com.hidden.client”;BindingKey和RoutingKey一样也是点号“.”分隔的字符串;

    • Bindingkey中可以存在两种特殊字符串“*”和“#",用于做模糊匹配,其中*用于匹配一个单词,“#”用于匹配多规格单词(可以是零个)。

  • Headers

    Headers类型的交换器不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。在绑定队列和交换器时制定一组键值对,当发送消息到交换器时,RabbitMQ会获取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配则消息会路由到该队列,否则不会路由到该队列。headers类型的交换器性能会很差,而且也不实用,基本上不会看到它的存在。

BindingKey

沿用本章开头的比喻,交换器相当于投递包裹的邮箱,Routingkey相当于填写在包裹上的地址,BindingKey相当于包裹的目的地,当填写在包裹上的地址和实际想要投递的地址相匹配时,那么这个包裹就会被正确投递到目的地,最后这个目的地的“主人”-队列可以保留这个包裹。如果填写的地址出错,邮递员不能正确投递到目的地,包裹可能会回退给寄件人,也可能被丢弃。

  • 在使用绑定的时候,其中需要的路由键是BindingKey。涉及的客户端方法如:channel.exchangeBind,channel.queueBind,对应的AMQP命令(详情参见
    2.2节)为Exchange.Bind,Queue.Bind.
  • 在发送消息的时候,其中需要的路由键是RoutingKey。涉及的客户端方法如channel.basicPublish,对应的AMOP命令为Basic.Publish.

猜你喜欢

转载自blog.csdn.net/whichard/article/details/87863829