为什么需要消息队列

在说明什么是消息队列前,先来了解一下为什么需要使用消息队列,它解决了什么问题,不能为了用而用。

MQ 的应用场景有很多,耳熟能详的是的是:系统解耦、异步处理和流量削峰。除此之外,还有延迟通知、分布式事务、顺序消息、流式处理等等。

解耦

消息队列可以实现系统应用之间的解耦,那什么是解耦呢,先来看一个场景。

有一个系统A需要发送数据到BCD三个系统中,通过接口调用的方式,如下图

在平常开发中,我们会在A系统代码中调用BCD系统所提供的接口,当某日需求需要增加或者删除一个接口,那么我们需要增加或者删除相应的代码,如果需要频繁的修改,想到这种场景我的心态都要炸了。而且各种服务耦合在一起,不出现问题还好,一旦某个系统出现问题,就会影响整个业务流程,如果在相应的位置上进行try catch,那就相当于埋了颗炸弹,说不定什么时候,砰的一下就会被炸飞。

那使用消息队列后会怎样呢,来看下图

引入消息队列后,A系统将产生数据发送到MQ,当BCD系统需要使用A系统提供的数据时直接从MQ消费即可,如果新增或者删除系统时,不需要在修改A系统中的代码,直接从MQ消费或者取消消费即可,这样处理它不香吗。

异步处理

为了不影响用户的体验,系统需要尽可能快的响应给用户。试想一下,如果每次操作用户都需要等待1-2秒,那你这是在挑战用户,你当用户是Hello Kitty吗。如下图

在不使用MQ时,在进行操作时,需要等待所有的系统都处理完相应的业务后,才能返回响应给用户,当引入MQ后,如果A系统发送消息至MQ队列中需要 3 ms,那么总时长位 2 + 3 = 5 ms,这对用户而言,点击按钮后5 ms后就直接返回,这简直是非一般的感觉,怎一个爽字了的!

**消息队列被用于实现服务的异步处理。**这样做的好处是:

  • 可以更快地返回结果;
  • 减少等待,自然实现了步骤之间的并发,提升系统总体的性能。

流量削峰

在系统中,已经使用消息队列实现了部分工作的异步处理,但还面临一个问题:如何避免过多的请求压垮系统?一般情况下,每秒并发请求数量不多,系统可以正常的提供服务。如果某个时间段内,每秒并发请求数量突然暴增,系统无法处理,会导致系统崩溃,那么用户也就无法使用系统了。

那引入MQ后,是如何避免这样情况的发生呢,先看下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MFFEetTU-1625401913388)(assets\流量削峰.png)]

引入MQ后,用户的请求都写入到MQ中。假设A系统每秒最多处理 2K 个请求,而某个时间段内的请求为 6K 个,那么先将 6K个请求写入到 MQ中,然后A系统从MQ中慢慢拉取请求,不要超过自己每秒最大请请求数据即可,这这样即使在高峰期也能避免系统崩溃,而发生损失。

有什么问题

硬币是有两面的,引入MQ解决很多问题,那它又带来了什么问题呢,

  • 系统可⽤性降低

系统引⼊的外部依赖越多,越容易挂掉。本来 A 系统调⽤ BCD 三个系统的接⼝就好了,没啥问题,但偏偏加个 MQ 进来,万⼀ MQ 挂了咋整,MQ ⼀挂,不仅整套系统崩溃的,你也就崩溃?所以要保证消息队列的⾼可⽤

  • 系统复杂度提⾼

硬⽣⽣加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性?

  • ⼀致性问题

A 系统处理完了直接返回成功了,都以为这个请求就成功了;但是问题是,要是 BCD三个系统中,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?这时候数据就不⼀致了。

总结一下:

  • 如何保证消息的高可用
  • 如何保证消息消费的幂等性
  • 如何处理消息丢失问题
  • 如何保证消息的顺序性
  • 如何解决消息积压
  • 如何保持数据一致性

如何选择消息队列

在软件开发中,每个软件系统都是独一无二的,不可能使用一套方法解决所有问题。同理,在消息队列的技术选型上,并不存在说哪个消息队列就是最好的,只有最适合的。

不同的消息队列在功能和特性方面各有优劣,但是在选型的时候要有一个最低标准,来保证其在开发中正常的使用。

首先产品是开源的,不然当我们使用过程遇到一个影响业务的Bug,无法通过修改代码来修复。

其次产品是今年来比较流行的并且社区活跃度比较高的,之所以这样是因为有很多Bug已经被其他人修复了,而且在使用过程中遇到的一些问题,很容易在网上搜到其解决方案。

另外,流行的产品与周边生态系统会有比较好的集成和兼容。

最后,作为一款及格的消息队列产品,必须具备的几个特性包括:

  • 消息的可靠传递:确保不丢消息;
  • Cluster:支持集群,确保不会因为某个节点宕机导致服务不可用,当然也不能丢消息;
  • 性能:具备足够好的性能,能满足绝大多数场景的性能要求。

目前在市面上比较主流的消息队列中间件主要有,Kafka、RocketMQ、RabbitMQ、ActiveMQ 等这几种。

RabbitMQ

RabbitMQ 是使用一种比较小众的编程语言:Erlang 语言编写的,它最早是为电信行业系统之间的可靠通信设计的,也是少数几个支持 AMQP 协议的消息队列之一。

RabbitMQ :轻量级、迅捷,“开箱即用的消息队列”。也就是说,RabbitMQ 是一个相当轻量级的消息队列,非常容易部署和使用。

RabbitMQ 一个比较有特色的功能是支持非常灵活的路由配置,和其他消息队列不同的是,它在生产者(Producer)和队列(Queue)之间增加了一个 Exchange 模块,你可以理解为交换机。

这个 Exchange 模块的作用和交换机也非常相似,根据配置的路由规则将生产者发出的消息分发到不同的队列中。路由的规则也非常灵活,甚至你可以自己来实现路由规则。

RabbitMQ 的客户端支持的编程语言大概是所有消息队列中最多的,如果系统是用某种冷门语言开发的,那多半可以找到对应的 RabbitMQ 客户端。

RabbitMQ 存在的几个问题。

第一个问题是,RabbitMQ 对消息堆积的支持并不好,在它的设计理念里面,消息队列是一个管道,大量的消息积压是一种不正常的情况,应当尽量去避免。当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。

第二个问题是,RabbitMQ 的性能上,根据官方给出的测试数据综合日常使用的经验,依据硬件配置的不同,它大概每秒钟可以处理几万到十几万条消息。其实,这个性能也足够支撑绝大多数的应用场景了,不过,如果应用对消息队列的性能要求非常高,那不要选择 RabbitMQ。

最后一个问题是 RabbitMQ 使用的编程语言 Erlang,这个编程语言不仅是非常小众的语言,如果你想基于 RabbitMQ 做一些扩展和二次开发什么的,建议慎重考虑一下可持续维护的问题。

RocketMQ

RocketMQ 是阿里巴巴在 2012 年开源的消息队列产品,后来捐赠给 Apache 软件基金会,2017 正式毕业,成为 Apache 的顶级项目。它有着不错的性能,稳定性和可靠性,具备一个现代的消息队列应该有的几乎全部功能和特性,并且它还在持续的成长中。

RocketMQ 对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,如果应用场景很在意响应时延,那应该选择使用 RocketMQ。

RocketMQ 的性能比 RabbitMQ 要高一个数量级,每秒钟大概能处理几十万条消息。

RocketMQ 的一个劣势是,作为国产的消息队列,相比国外的比较流行的同类产品,在国际上还没有那么流行,与周边生态系统的集成和兼容程度要略逊一筹。

Kafka

Kafka 最早是由 LinkedIn 开发,目前也是 Apache 的顶级项目。Kafka 最初的设计目的是用于处理海量的日志。

在早期的版本中,为了获得极致的性能,在设计方面做了很多的牺牲,比如不保证消息的可靠性,可能会丢失消息,也不支持集群,功能上也比较简陋,这些牺牲对于处理海量日志这个特定的场景都是可以接受的。这个时期的 Kafka 甚至不能称之为一个合格的消息队列。随后的几年 Kafka 逐步补齐了这些短板,当下的 Kafka 已经发展为一个非常成熟的消息队列产品,无论在数据可靠性、稳定性和功能特性等方面都可以满足绝大多数场景的需求。

Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域,几乎所有的相关开源软件系统都会优先支持 Kafka。

Kafka 使用 Scala 和 Java 语言开发,设计上大量使用了批量和异步的思想,这种设计使得 Kafka 能做到超高的性能。Kafka 的性能,尤其是异步收发的性能,是三者中最好的,但与 RocketMQ 并没有量级上的差异,大约每秒钟可以处理几十万条消息。

ActiveMQ

ActiveMQ 是最老牌的开源消息队列,是十年前唯一可供选择的开源消息队列,目前已进入老年期,社区不活跃。无论是功能还是性能方面,ActiveMQ 都与现代的消息队列存在明显的差距,它存在的意义仅限于兼容那些还在用的爷爷辈儿的系统。

总结

消息队列(一)为什么需要消息队列相关推荐

  1. activeMQ - 消息重发策略和DLQ死信队列

    2019独角兽企业重金招聘Python工程师标准>>> 1:死信队列简介 DLQ-死信队列(Dead Letter Queue)用来保存处理失败或者过期的消息. 出现以下情况时,消息 ...

  2. 用户请求队列化_分布式消息队列选型分析

    高并发架构是成为架构师的必修课,而消息队列,则是王冠上最闪亮的那颗明珠!能否驾驭消息队列这款高并发神器,亦成为架构师的试金石.本文将从队列本质.技术选型两个方面,给大家整理下个人心得,希望能对大家有所 ...

  3. RabbitMQ中的虚拟主机、交换机、消息队列、绑定、消息

    虚拟主机(virtual host ) 虚拟地址,用于进行逻辑隔离,最上层的消息路由,一个 virtual host 里面可以有若干个 exchange 和 queue,但是里面不能有相同名称的 ex ...

  4. 何为消息队列,为何使用消息队列,有什么消息队列插件

    一.什么叫消息队列 MQ(Message Quene) : 翻译为 消息队列,通过典型的 生产者和消费者模型,生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息.因为消息的生产和消费都是异步 ...

  5. linux 消息对lie_Linux进程间通信之消息队列总结

    一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构(消息队列.信号量或共享存储段)都用一个非负整数的标识符( i d ...

  6. Kafka是什么,JMS是什么,常见的类JMS消息服务器,为什么需要消息队列(来自学习笔记)

    1.Kafka是什么  Apache Kafka是一个开源消息系统,由Scala写成.是由Apache软件基金会开发的一个开源消息系统项目.  Kafka最初是由LinkedIn开发,并于2011 ...

  7. php redis微信发红包,高阶篇二 使用Redis队列发送微信模版消息

    # 高阶篇二 使用Redis队列发送微信模版消息 > 此命令行执行任务的方法类比较复杂 他需要命令行运行才会有效 > 命令行源码以及创建方法 参见上节 https://www.kanclo ...

  8. php监听mq消息,客户端监听服务端获取rabbitmq消息队列,rabbitmq有消息的时候客户端刷新页面才能获取到消息,监听没起到作用,请求各位大神指点迷津...

    header("Content-Type:text/html;charset=utf-8"); use Workerman\Worker; require_once __DIR__ ...

  9. tp5 mysql实现消息队列_TP5系列 | Queue消息队列

    消费信息如下ThinkPHP5 Queue消息队列 优点 1.Queue内置了 Redis,Database,Topthink ,Sync这四种驱动,本文使用Redis驱动 2.Queue消息队列适用 ...

  10. 消息队列面试 - 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

    消息队列面试 - 如何保证消息不被重复消费? 面试题 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性? 面试官心理分析 其实这是很常见的一个问题,这俩问题基本可以连起来问.既然是消费消息, ...

最新文章

  1. C#机房重构-总结(二)
  2. 【NLP】大模型时代,我们真的不再需要分词了吗?
  3. 获取java异常堆栈信息_Java 实例 - 获取异常的堆栈信息
  4. GNU/CPIO 学习小结
  5. 专题突破一之分块——Untitled Problem II,Balanced Lineup,[ioi2009]Regions
  6. 转载 | pymysql.err.InterfaceError: (0, ‘‘)解决办法
  7. C#中打开设计视图时报未将对象引用设置到对象的实例
  8. thumbnailator 一个好用的图像处理工具集
  9. 基于深度学习的青菜病害区域图像语义分割与定位
  10. 书单|互联网企业面试案头书之架构师篇
  11. 具有免校准和带漏电检测功能的计量芯片HLW8112
  12. win7计算机不显示dvd,win7系统不显示光驱盘符的解决方法
  13. js采集图片批量下载
  14. 如何选择crm客户管理系统
  15. Zoned-Storage - 对ZNS块设备进行基准测试
  16. Python3.7安装Geenlet
  17. 传感器实验——LCD显示小车状态
  18. 银赛电气降低电气开关火灾危险性
  19. Java之IO,BIO,NIO,AIO知多少?
  20. Windows网络编程 — UDP完成端口的实现

热门文章

  1. Android-Bitmap优化
  2. Qt获取OpenGL版本
  3. day02-移动web(空间转换)
  4. 大众点评超详细爬虫系列3
  5. excel 计算机beep,Beep语句有什么用??
  6. pytest之fixture参数化
  7. 如何安全的Include文件
  8. HTML5 input属性
  9. turbine java_Spring Cloud之服务监控turbine的示例
  10. 数据集中存储,保护数据安全的图形工作站方案——HC12远程图形工作站