⭐ 作者简介:码上言
⭐ 代表教程:Spring Boot + vue-element 开发个人博客项目实战教程
⭐专栏内容:个人博客系统
⭐我的文档网站:http://xyhwh-nav.cn/
RabbitMQ简介
官方网站:https://www.rabbitmq.com/
中文网站:https://rabbitmq.p2hp.com/
RabbitMQ 拥有数以万计的用户,是最受欢迎的开源消息代理之一。从T-Mobile 到Runtastic,RabbitMQ 在全球范围内用于小型初创公司和大型企业.
RabbitMQ 是轻量级的,易于在本地和云端部署。它支持多种消息传递协议。RabbitMQ 可以部署在分布式和联合配置中,以满足大规模、高可用性的要求.
RabbitMQ是一个消息代理。它的工作就是接收和转发消息。你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处。在这个比喻中,RabbitMQ就扮演着邮箱、邮局以及邮递员的角色。RabbitMQ和邮局的主要区别在于,它不是处理纸张,而是接收、存储和发送消息(message)这种二进制数据。
RabbitMQ
是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
AMQP
,即 Advanced Message Queuing Protocol(高级消息队列协议),是一个网络协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。2006年,AMQP规范发布。类比HTTP。2007年,Rabbit技术公司基于AMQP标准开发的RabbitMQ1.0发布。RabbitMQ采用Erlang 语言开发。
MQ是什么
MQ全称为Message Queue
,即消息队列。消息队列是在消息的传输过程中保存消息的容器。它是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦,多用于分布式系统之间进行通信。
- 在不使用MQ消息队列时,两个系统直接的通信通常使用的是远程调用的方式,如图:
-
在使用MQ之后,两个服务间的调用结构如下所示:
常见的MQ产品
-
Kafka:分布式消息系统,高吞吐量(大数据使用)
-
ActiveMQ:基于JMS
-
RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好
-
RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会
。。。。。。
各产品之间的性能比较
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
公司/社区 | Apache | Rabbit | 阿里巴巴 | Apache |
开发语言 | Java | Erlang | Java | Scala |
协议 | OpenWire,STOMP,XMPP,AMQP | AMQP,XMPP,SMTP,STOMP | 自定义 | 自定义协议,社区有封装的http协议 |
单机吞吐量 | 万级 | 万级 | 十万级 | 十万级 |
时效性 | 毫秒级 | 微秒级 | 毫秒级 | 毫秒级以内 |
可用性 | 高(主从架构) | 高(主从架构) | 非常高(分布式架构) | 非常高(分布式架构) |
功能特性 | 老产品,成熟度高,有较多的文档;各种协议支持较好 | 并发能力强,性能极其好,延迟低,社区活跃,管理界面丰富。 | 功能比较齐全,可扩展性比较好 | 只支持主要的MQ功能,在大数据领域应用广泛 |
中小型软件公司,建议选RabbitMQ。一方面,erlang语言天生具备高并发的特性,RabbitMQ的社区十分活跃,可以解决开发过程中遇到的bug,这点对于中小型公司来说十分重要。不考虑rocketmq和kafka的原因是中小型软件公司不如互联网公司,数据量没那么大,选消息中间件,应首选功能比较完备的。
大型软件公司,根据具体使用在rocketMq和kafka之间二选一。一方面,大型软件公司,具备足够的资金搭建分布式环境,也具备足够大的数据量。针对rocketMQ,大型软件公司也可以抽出人手对rocketMQ进行定制化开发,毕竟国内有能力改JAVA源码的人,还是相当多的。至于kafka,根据业务场景选择,如果有日志采集功能,肯定是首选kafka了。
MQ的使用条件说明
- 生产者不需要从消费者处获得反馈,引入消息队列之前的直接调用,其接口的返回值应该为空,这才让明明下层的动作还没做,上层却当成动作做完了继续往后走,即所谓异步成为了可能。(单向的数据流动)
- 可以容许有短暂时间的不一致性。
- 项目引入之后确实有问题解决,即解耦、提速、削峰这些方面的收益,超过加入MQ,管理MQ这些成本。
MQ的使用场景
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。主要分为以下4中应用场景。
应用解耦
解耦是消息队列要解决的最本质问题,系统的耦合性越高,容错性就越低,可维护性就越低。
场景说明:
该应用场景常用于电商系统中,如:用户下单后,订单系统需要通知库存系统。
- 传统模式
系统间耦合性太强,订单系统会直接调用库存系统的接口,进行库存减少操作。这样会有失败的风险:
- 假如库存系统无法访问,则订单减库存将失败,从而导致订单失败。
- 订单系统与库存系统耦合。
- 引入消息队列
引入消息队列后,订单系统和库存系统就不需要进行关联,通过消息队列进行处理。
- 订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功,请等待物流配送。
- 库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
- 假如:在下单时库存系统不能正常使用。也不影响正常下单。
- 在下单后,订单系统写入消息队列就不再关心其他的后续操作了,可以继续接收下一个订单任务了,实现订单系统与库存系统的应用解耦。
异步处理
应用场景如:用户注册发送短信,订单通知等场景。
例如:用户注册完成后,需要发送短信和邮件进行通知注册。
- 传统模式
采用串行或并行的方式进行短信或邮件的发送,在一些非必要的业务逻辑以同步的方式运行,太耗费时间。
- 串行
实现逻辑:用户将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。等这三个任务全部完成后,会将运行的结果返回给客户端。
- 并行
实现逻辑:将注册信息写入数据库成功后,将邮件和短信同时发送。然后等待任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。节省了一个短信或邮件发送的时间。
通过上述列举的图所示,假设发送短信和邮件耗时为100ms,写入数据库为50ms,在不考虑网络等其他开销的话,串行方式的时间为250ms,并行的时间可能是150ms。
则串行方式1秒内CPU可处理的请求量是4次(1000/250)。并行方式处理的请求量是7次(1000/150)。
- 使用消息队列
传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈,接下来引入消息队列,将不必要的业务逻辑进行异步处理。只需要将数据写入到MQ中,然后后续的未执行的事情交由MQ慢慢执行
用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,
使用消息队列的方式1秒内CPU可处理的请求量是20次(1000/50)
因此用户的响应时间可能是50毫秒。所以基于此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了5倍,比并行将近提高了3倍。
流量削锋
流量削锋(削峰填谷)也是消息队列中的常用场景,一般在秒杀或团抢活动、处理并发量大的时候使用比较广泛。
应用场景:秒杀活动,一般会因为流量过大,并发剧增,导致流量暴增,服务容易挂掉。
- 传统模式
将所有的请求直接访问到数据库,造成数据库直接连接异常,导致数据丢失。
- 加入消息队列
- 用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。
- 秒杀业务根据消息队列中的请求信息,再做后续处理。
在使用了MQ消息之后,假设消息限制消费的速度为1000,这样,即使在高峰期产生大量数据时,会被积压在MQ队列中,高峰就被“削”掉了,但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000,直到消费完积压的消息,这就叫做“填谷”。相当于一个缓冲区,让数据慢慢交给系统!
消息通讯
消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在消息通讯中。比如实现点对点消息队列,或者聊天室等。
-
点对点通讯
服务A和服务B使用同一队列,进行消息通讯。服务A只发送消息,服务B只负责接收消息。
- 聊天室通讯
例如QQ、微信聊天一样,服务A,服务B订阅同一主题,进行消息发布和接收。实现类似聊天室效果。