文章目录
一、 初识MQ
1.1、 同步通讯和异步通讯
微服务间通讯有同步和异步两种方式:
- 同步通讯:就像打电话,需要实时响应。
- 异步通讯:就像发微信,不需要马上回复。
1.1.1、 同步通讯
我们之前在SpringCloud学习的Feign调用就属于同步方式,虽然调用可以实时得到结果,但存在下面的问题:
1.1.2、 异步通讯
异步调用常见实现就是事件驱动模式:
异步通讯的优势如下:
1.服务解耦(如果想要加新需求,直接让新需求模块订阅broker消息就好,与支付服务无关)
2.性能提升,吞吐量提高(只需要等待60ms,而同步方式需要等待每一个下游服务都处理完)
3.服务没有强依赖,不担心级联失败问题(例子:即使仓储服务挂掉,也不会发生像同步方式,支付服务一直等待的现象)
4.流量削峰(当请求量增大时(并发增大),将消息存到broker处,让下游服务有序进行)
实现下图的效果:
5.日志收集:将日志信息发送到消息队列,实现集中式的日志管理和统计分析。
1.2、 MQ优缺点对比
MQ (MessageQueue),中文是消息队列,字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。
1.2.1、 ActiveMQ
我们先看ActiveMQ。其实一般早些的项目需要引入消息中间件,都是使用的这个MQ,但是现在用的确实不多了,说白了就是有些过时了。我们去它的官网看一看,你会发现官网已经不活跃了,好久才会更新一次。
它的单机吞吐量是万级,一些小的项目已经够用了,但对于高并发的互联网项目完全不够看。
在高可用上,使用的主从架构的实现。
在消息可靠性上,有较低的概率会丢失数据。
综合以上,其实这个产品基本可以弃用掉了,我们完全可以使用RabbitMQ来代替它。
1.2.2、 RabbitMQ
RabbitMQ出现后,国内大部分公司都从ActiveMQ切换到了RabbitMQ,基本代替了activeMQ的位置。它的社区还是很活跃的。
它的单机吞吐量也是万级,对于需要支持特别高的并发的情况,它是无法担当重任的。
在高可用上,它使用的是镜像集群模式,可以保证高可用。
在消息可靠性上,它是可以保证数据不丢失的,这也是它的一大优点。
同时它也支持一些消息中间件的高级功能,如:消息重试、死信队列等。
但是,它的开发语言是erlang,国内很少有人精通erlang,所以导致无法阅读源码。对于大多数中小型公司,不需要面对技术上挑战的情况,使用它还是比较合适的。而对于一些BAT大型互联网公司,显然它就不合适了。
1.2.3、 RocketMQ
接下来我们来讨论一下我比较喜欢的RocketMQ,它是阿里开源的消息中间件,久经沙场,非常靠谱。
它支持高吞吐量,能达到10万级,能承受互联网项目高并发的挑战。
在高可用上,它使用的是分布式架构,可以搭建大规模集群,性能很高。
在消息可靠性上,通过配置,可以保证数据的绝对不丢失。
同时它支持大量的高级功能,如:延迟消息、事务消息、消息回溯、死信队列等等。
它非常适合应用于java系统架构中,因为它使用java语言开发的,我们可以去阅读源码了解更深的底层原理。
目前来看,它没有什么特别的缺点,可以支持高并发下的技术挑战,可以基于它实现分布式事务,大型互联网公司和中小型公司都可以选择使用它来作为消息中间件使用,如果我来做技术选型,我首选的中间件就是它。
1.2.4、 Kafka
kafka的吞吐量被公认为中间件中的翘楚,单机可以支持十几万的并发,相当强悍。
在高可用上同样支持分布式集群部署。
在消息可靠性上,如果保证异步的性能,可能会出现消息丢失的情况,因为它保存消息时是先存到磁盘缓冲区的,如果机器出现故障,缓冲区的数据是可能丢失的。
它的功能非常的单一,就是消息的接收与发送,因此不适合应用于许多场景。
它在行业内主要应用于大数据领域,使用它进行用户行为日志的采集和计算
。所以,如果没有大数据的需求,一般不会选择它
。
二、 RabbitMQ_基础
2.1、 为什么选择RabbitMQ
ActiveMQ
,性能不是很好,因此在高并发的场景下,直接被pass掉了。它的 Api 很完善,在中小型互联网公司可以去使用。kafka
,主要强调高性能,如果对业务需要可靠性消息的投递的时候。那么就不能够选择kafka了。但是如果做一些日志收集呢,kafka还是很好的。因为kafka的性能是十分好的。RocketMQ
,它的特点非常好。它高性能、满足可靠性、分布式事务、支持水平扩展、上亿级别的消息堆积、主从之间的切换等等。MQ的所有优点它基本都满足。但是它最大的缺点:商业版收费。因此它有许多功能是不对外提供的。
2.2、 RabbitMQ简介
RabbitMQ 是一个由 Erlang
语言开发的 AMQP 的开源实现。AMQP :Advanced Message Queue Potocal,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。RabbitMQ最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
2.3、 RabbitMQ架构
Broker
(服务器):即RabbitMQ Server,也叫Broker server,接收和分发消息的应用,保证数据能够按照指定的方式进行传输。Connection
(连接):Producer/Consumer 和 broker 之间的TCP
连接,在消息发送时必须要先建立与RabbitMQ服务器的连接。Channel
(信道):建立在Connection中,消息是基于Channel传递的,Channel之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销;如果每一次访问RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection的开销将是巨大的,效率也较低。VirtualHost
(虚拟主机):exchange/queue是属于某个VirtualHost的,VirtualHost属于某个用户的;VirtualHost可以分配用户在创建交换机或队列时可以指定其属于哪个虚拟主机,方便用户管理交换机和队列。Producer
(生产者): 消息的生产者,数据的发送方。消息生产者连接RabbitMQ服务器然后将消息投递到Exchange。Exchange
(交换机):生产者将消息发送到 Exchange(交换器),由 Exchange将消息路由到一个或多Queue 中(或者丢弃)。Exchange 并不存储消息。RabbitMQ 中的 Exchange 有direct
、fanout
、topic
、headers
四种类型,每种类型对应不同的路由规则。Queue
(队列):是RabbitMQ的内部对象,用于存储消息。消息消费者就是通过订阅队列来获取消息;RabbitMQ 中的消息都只能存储在Queue中,生产者生产消息并最终投递到Queue 中,消费者可以从 Queue 中获取消息并消费。多个消费者可以订阅同一个Queue,这时 Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。
2.4、 交换机类型
2.4.1、 Direct Exchange(直连交换机)
直连交换机的特点是消息队列通过routingKey与交换机进行绑定,相同的routingKey会获得相同的消息。一个队列可以通过多个不同的routingKey与交换机进行绑定。不同的队列也可以通过相同的routingKey绑定交换机。
2.4.2、 Fanout Exchange(扇出交换机)
扇出交换机的特点是类似于广播,只要队列与该类型的交换机绑定,所有发送到该交换机的信息都会被转发到所有与之绑定的队列,与routingKey无关。
2.4.3、 Topic Exchange(主题交换机)
应用范围最广的交换机类型,消息队列通过消息主题与交换机绑定。一个队列可以通过多个主题与交换机绑定,多个消息队列也可以通过相同消息主题和交换机绑定。并且可以通过通配符(*
或者#
)进行多个消息主题的适配。
消息主题的一般格式为xxx.xxx.xxx(x为英文字母,每个单词用英文句号隔开)。*通配符可以适配一个单词,#可以适配零个或者多个单词。
2.4.4、 Header Exchenge(头交换机)
与routingKey无关,匹配机制是匹配消息头中的属性信息。在绑定消息队列与交换机之前声明一个map键值对,通过这个map对象实现消息队列和交换机的绑定。当消息发送到RabbitMQ时会取到该消息的headers与Exchange绑定时指定的键值对进行匹配;如果完全匹配则消息会路由到该队列,否则不会路由到该队列。
匹配规则x-match有下列两种类型:
- x-match = all :表示
所有的键值对都匹配
才能接受到消息 - x-match = any :表示
只要有键值对匹配
就能接受到消息
引用:
1.Rabbitmq的四种类型交换机
2.5、 RabbitMQ工作模式
RabbitMQ官网地址:里面有介绍RabbitMQ的工作模式。
2.5.1、 Hello World
简单模式中表现为一个生产者对应一个消费者,生产者(Producer)生产消息发送到队列,消费者(Consumer)监听此队列,进行消息的消费;
2.5.2、 Work Queues
Work模式与Simple模式几乎是一模一样的,只不过我们在只有一个Producer和一个Consumer时习惯把这种模式称为Simple模式,而当一个Producer有多个Consumer时我们把这样的模式成为Work模式,因此Work模式和Simple模式的代码是一模一样的,只不过是多个Consumer监听同一个队列而已(一个队列下的Consumer是竞争关系);
2.5.3、 Publish/Subscribe
在发布订阅模式中,Producer发送消息到指定的Exchange中,由Exchange绑定不同的Queues,消费者依旧监听这些队列进行消费。
发布订阅模式重点强调的是fanout
类型的Exchange,发布订阅模式也叫分列模式;
需要注意的两点:
1、work、simple也会有交换机,他们使用的是默认的交换机
2、Exchange还可以绑定到另一个Exchange上
2.5.4、 Routing
发布订阅模式强调的是Fanout
类型的Exchange,Routing模式
则强调的是direct
类型的Exchange,Routing模式也叫直连模式;
如上图所示,如果消息的路由键是orange,则此消息只会到队列Q1上;如果消息的路由键为black或green,则此消息会到队列Q2上。实际工作中,90%都是使用的此模式。
2.5.5、 Topics
Topics模式也叫主题模式,相比于发布订阅模式,该模式下的Exchange在绑定Queues时可以指定的一定的通配符,这些通配符指定了路由的规则;
- 符号
#
:匹配零个或多个词。(0个或多个) - 符号
*
:匹配不多不少一个词。(必须是一个,0个不行)
2.5.6、 RPC
《RabbitMQ系列教程-第四章-06-RabbitMQ工作模式之RPC模式》
2.5.7、 Publisher Confirms
这部分比较复杂,放到后面介绍。