ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

消息队列:基础概念篇

2022-01-21 17:03:47  阅读:124  来源: 互联网

标签:请求 队列 系统 业务 概念 MQ 消息


前言

接下来我在写一些技术类科普的文章,大致会以who(它是谁)、why(为什么)、how(怎么做)的写作方向来向大家介绍说明,因为我认为这样子介绍说明思路会比较明确,也能够更快学会一项新技能,个人拙见,写得不好、不对的地方,还望大家赐教。

Who|什么是消息队列(MQ)

在计算机科学中,消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的资料,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。[1]

一个 WIMP 环境像是 Microsoft Windows,借由优先的某些形式(通常是事件的时间或是重要性的顺序)来存储用户产生的事件到一个 事件贮列 中。系统把每个事件从事件贮列中传递给目标的应用程序。

​ —维基百科

MQ(Message Queue)消息队列,是基础数据结构中“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。

​ —百度百科

简单来说,就是排队的意思,先进先出。

Why|为什么用MQ

查个题外话,我认为使用一项新技术的时候,我们要综合考虑该技术的利弊性、维护性、成本性,而不是盲目跟随主流,自己的业务产品不管三七二十一都使用最新的技术,也得根据项目的实际情况来最终决定。

回归主题,存在即合理,它的主要的三大应用场景:应用解耦、异步消息、流量削峰,除此之外,还有延迟通知、分布式事务、顺序消息、流式处理等等。下面我主要细说下它的三大应用场景。

应用解耦

一个业务需要多个模块共同实现,或者一条消息有多个系统需要对应处理,只需要主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。

举个例子,有个业务场景,我有三个系统,分别是A、B、C系统,大致业务是,A系统操作完具体业务,会分别调用B跟C的接口。

传统做法

正常情况,我们会直接在A系统的代码里面写上对B、C系统的接口请求。如下图

在这里插入图片描述

可能存在问题:

1、假设其中一个系统因为不确定因素导致宕机了,这时候是不是整个业务都走不下去了

2、假设业务突然又需要增加调用一个D系统,或者去除C系统的调用,那是不是代码又要重新改一次

3、改任何一个系统的代码,都要小心翼翼的

因此根据以上几点,我们可以明显看出应用系统之间的耦合度很高,没有很独立的思想,所以就需要引用MQ来作为中间件来降低它们之间的耦合度。

MQ做法

A系统就产生一条数据发送到MQ,这时候BCD系统哪个需要这个数据就自行去消费即可,如果又新增或减少好几个应用系统,只需要在去消费或者取消消费。

在这里插入图片描述

由此可见,这样子A系统是不是很独立了,压根就不需要管BCD系统会出现什么异常情况,A系统的代码也不再需要重新维护。

异步处理

主业务执行结束后从属业务通过MQ,异步执行,减低业务的响应时间,提高用户体验。

举个例子,有个预约挂号的业务,病人挂号成功后,需要发送短信通知跟微信通知

传统做法

假设都正常执行,用户挂号操作调用挂号系统接口耗时200ms,然后在调用短信接口200ms,再调用微信通知接口200ms,那这样子加起来一共就要600ms,这是正常情况,假如出现某个接口很耗时,那这样子就很影响用户体验了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AfpiJsvW-1642755230477)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220121144534818.png)]

MQ做法

挂号系统接口是必须的,还是200ms,然后挂号系统在产生消息到MQ花费3ms,短信接口跟微信系统到时候在自行消费,那响应速度一下子变成快了近2倍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-44PXNAi3-1642755230481)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220121152801920.png)]

流量削峰

高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。

举个例子,A系统每天都风平浪静的,每秒平均的并发量也才50个,但是有一天,在某个时间段,突然每秒的并发请求量激增到6K+,假如该系统的数据库是用mysql,每秒执行6K+条的SQL。正常的mysql数据库能够抗住每秒2k条的执行语句,一下子到6k+,会直接导致数据库崩溃,从而导致系统也崩溃了。

传统做法

在这里插入图片描述

MQ做法

引用 MQ,直接将全部的请求(每秒 6k+) 个请求写入 MQ,因为我们的A系统最大的承载量是每秒2k个请求,所以每次从MQ中慢慢拉取,一次就拉取2k请求,不超过自己系统的最大请求量就行了。这样子,即使在高峰的请求量,也不用在怕A系统会崩溃。虽然在高峰期的时候,这些请求可能堆积在MQ中有几十万甚至几百万条,但是只要一过高峰期,从MQ每秒2k条的拉取执行,很快也会被消化完毕的。

在这里插入图片描述

MQ有什么优缺点

东西都是有两面性的。优点就不用说了吧,就是上面说的那些,下面我们来说说有哪些缺点跟需要考虑的问题

  • 系统可⽤性降低

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

  • 系统复杂度提⾼

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

  • ⼀致性问题

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

总结一下:

  • 如何保证消息的高可用

  • 如何保证消息消费的幂等性

  • 如何处理消息丢失问题

  • 如何保证消息的顺序性

  • 如何解决消息积压

  • 如何保持数据一致性

How|怎么用MQ

目前市场常见的消息队列产品主要有ActiveMQ、RabbitMQ、RocketMQ、Kafka等。

那么怎么选择一款符合自己产品的MQ就很关键了。下面有个对比分享做参考。

特性ActiveMQRabbitMQRocketMQKafka
开发语言JavaErlangJavaScala&Java
客户端支持语言Java、C、C++、Python、PHP、Pert、.net等几乎支持所有常用语言Java、C++官方支持Java,但是开源社区有常用语言版本
单机吞吐量万级,比 RocketMQ、Kafka 低一个数量级同 ActiveMQ10 万级,支撑高吞吐10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topictopic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性ms 级微秒级,这是 RabbitMQ 的一大特点,延迟最低ms 级延迟在 ms 级以内
可用性高,基于主从架构实现高可用同 ActiveMQ非常高,分布式架构非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据基本不丢经过参数优化配置,可以做到 0 丢失同 RocketMQ
功能支持MQ 领域的功能极其完备基于 erlang 开发,并发能力很强,性能极好,延时很低MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

综上,各种对比之后,有如下建议:

  • ActiveMQ最为老牌MQ,现在用的人不多,社区也不太活跃,所有不推荐
  • 中小企业,并发量不是很大的,追求稳定,RabbitMQ是首选
  • Java首选RocketMQ,毕竟阿里出品,向大厂看齐
  • 大数据领域的用 Kafka 是业内标准的,社区活跃度很高

标签:请求,队列,系统,业务,概念,MQ,消息
来源: https://blog.csdn.net/shaojiayong/article/details/122615974

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有