Spring Boot(十三)RabbitMQ安装与集成

 

一、前言

RabbitMQ是一个开源的消息代理软件(面向消息的中间件),它的核心作用就是创建消息队列,异步接收和发送消息,MQ的全程是:Message Queue中文的意思是消息队列。

1.1 使用场景

  1. 削峰填谷:用于应对间歇性流量提升对于系统的“破坏”,比如秒杀活动,可以把请求先发送到消息队列在平滑的交由系统去处理,当访问量大于一定数量的时候,还可以直接屏蔽后续操作,给前台的用户友好的显示;

  2. 延迟处理:可以进行事件后置,比如订单超时业务,用户下单30分钟未支付取消订单;

  3. 系统解耦:消息队列也可以帮开发人员完成业务的解耦,比如用户上传头像的功能,最初的设计是用户上传完之后才能发帖,后面有增加了经验系统,需要在上传头像之后增加经验值,到后来又上线了金币系统,上传头像之后可以增加金币,像这种需求的不断升级,如果在业务代码里面写死每次该业务代码是很不优雅的,这个时候如果使用消息队列,那么只需要增加一个订阅器用于介绍用户上传头像的消息,再执行经验的增加和金币的增加是非常简单的,并且在不改动业务模块业务代码的基础上可以轻松实现,如果后期需要撤销某个模块了,只需要删除订阅器即可,就这样就降低了系统开发的耦合性;

1.2 为什么使用RabbitMQ?

现在市面上比较主流的消息队列还有Kafka、RocketMQ、RabbitMQ,它们的介绍和区别如下:

Kafka: 是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache定级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。

RabbitMQ: 是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。

RocketMQ: 是阿里开源的消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。

简单总结: Kafka的性能最好,适用于对消息吞吐量达,对消息丢失不敏感的系统;RocketMQ借鉴了Kafka并提高了消息的可靠性,修复了Kafka的不足;RabbitMQ性能略低于Kafka,并实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的标准,有非常好的稳定性。

支持语言对比

  • RocketMQ 支持语言:Java、C++、Golang
  • Kafka 支持语言:Java、Scala
  • RabbitMQ 支持语言:C#、Java、Js/NodeJs、Python、Ruby、Erlang、Perl、Clojure、Golang

1.3 RabbitMQ特点

RabbitMQ的特点是易用、扩展性好(集群访问)、高可用,具体如下:

  • 可靠性:持久化、消息确认、事务等保证了消息的可靠性;
  • 伸缩性:集群服务,可以很方便的添加服务器来提高系统的负载;
  • 高可用:集群状态下部分节点出现问题依然可以运行;
  • 多语言支持:RabbitMQ几乎支持了所有的语言,比如Java、.Net、Nodejs、Golang等;
  • 易用的管理页面:RabbitMQ提供了易用了网页版的管理监控系统,可以很方便的完成RabbitMQ的控制和查看;
  • 插件机制:RabbitMQ提供了许多插件,可以丰富和扩展Rabbit的功能,用户也可编写自己的插件;

1.4 RabbitMQ基础知识

在了解消息通讯之前首先要了解3个概念:生产者、消费者和代理。

生产者:消息的创建者,负责创建和推送数据到消息服务器;

消费者:消息的接收方,用于处理数据和确认消息;

代理:就是RabbitMQ本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色。

(一)消息发送原理

首先你必须连接到Rabbit才能发布和消费消息,那怎么连接和发送消息的呢?

你的应用程序和Rabbit Server之间会创建一个TCP连接,一旦TCP打开,并通过了认证,认证就是你试图连接Rabbit之前发送的Rabbit服务器连接信息和用户名和密码,有点像程序连接数据库,使用Java有两种连接认证的方式,后面代码会详细介绍,一旦认证通过你的应用程序和Rabbit就创建了一条AMQP信道(Channel)。

信道是创建在“真实”TCP上的虚拟连接,AMQP命令都是通过信道发送出去的,每个信道都会有一个唯一的ID,不论是发布消息,订阅队列或者接收消息都是通过信道完成的。

(二)为什么不通过TCP直接发送命令?

对于操作系统来说创建和销毁TCP会话是非常昂贵的开销,假设高峰期每秒有成千上万条连接,每个连接都要创建一条TCP会话,这就造成了TCP连接的巨大浪费,而且操作系统每秒能创建的TCP也是有限的,因此很快就会遇到系统瓶颈。

如果我们每个请求都使用一条TCP连接,既满足了性能的需要,又能确保每个连接的私密性,这就是引入信道概念的原因。

(三)RabbitMQ名称解释

ConnectionFactory(连接管理器): 应用程序与Rabbit之间建立连接的管理器,程序代码中使用;

Channel(信道): 消息推送使用的通道;

Exchange(交换器): 用于接受、分配消息;

Queue(队列): 用于存储生产者的消息;

RoutingKey(路由键): 用于把生成者的数据分配到交换器上;

BindingKey(绑定键): 用于把交换器的消息绑定到队列上;

看到上面的解释,最难理解的路由键和绑定键了,那么他们具体怎么发挥作用的,请看下图:

1.5 交换器分类

RabbitMQ的Exchange(交换器)分为四类:

  • direct(默认)
  • headers
  • fanout
  • topic

其中headers交换器允许你匹配AMQP消息的header而非路由键,除此之外headers交换器和direct交换器完全一致,但性能却很差,几乎用不到,所以我们这里不做解释。

1.5.1 direct交换器

direct为默认的交换器类型,也非常的简单,如果路由键匹配的话,消息就投递到相应的队列,如下图:

1.5.2 fanout交换器

fanout有别于direct交换器,fanout是一种发布/订阅模式的交换器,当你发送一条消息的时候,交换器会把消息广播到所有附加到这个交换器的队列上。

注意: 对于fanout交换器来说routingKey(路由键)是无效的,这个参数是被忽略的。

1.5.3 topic交换器

topic交换器运行和fanout类似,但是可以更灵活的匹配自己想要订阅的信息,这个时候routingKey路由键就排上用场了,使用路由键进行消息(规则)匹配。

topic路由器的关键在于定义路由键,定义routingKey名称不能超过255字节,使用“.”作为分隔符,例如:com.mq.rabbit.error。

匹配规则

匹配表达式可以用“*”和“#”匹配任何字符,具体规则如下:

  • “*”匹配一个分段(用“.”分割)的内容;
  • “#”匹配所有字符;

例如发布了一个“cn.mq.rabbit.error”的消息:

能匹配上的路由键:

  • cn.mq.rabbit.*
  • cn.mq.rabbit.#
  • #.error
  • cn.mq.#
  • #

关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信