`

项目中使用消息队列的原因

阅读更多

为什么要使用消息队列       

      做过互联网企业级应用开发的同学们,不管是在大厂的还是在小厂的,都会知道或熟悉消息队列。那么,在做企业级应用开发的过程中,为啥需要用消息队列呢?下面是小弟在日常工作中整理出来的心得,希望能帮助有需要的同学。

      在正常的项目中使用消息队列,主要是为了以下三种场景:解耦,异步,削峰。下面分别针对这三种场景,做下简单的描述。

      1. 解耦

      在未使用消息队列之前的企业级应用开发的过程中,如果某个系统是产生关键数据的系统,那么其他的系统都会依赖这个系统去获取数据,如下图所示:

      A系统是产生关键数据的系统,所有系统都需要其进行提供数据,导致A系统与要提供数据系统产生耦合,系统拓展,其他系统的需求修改都会导致A系统产生修改。

      使用了消息队列,进行系统解耦以后,如下图所示:

       通过一个MQ,发布和订阅消息的Pub/Sub模型,A系统不需要去考虑要给谁发数据,不需要维护代码,不需要考虑调用方是否成功,失败或超时。这样,就将A系统和其他系统彻底解耦了。

       2. 异步

      如果一个用户发起了一个业务操作,需要几个系统间的一系列请求,同时每一个系统肯都存在一定的耗时。先看下未采用MQ的链路请求及耗时的情况,如下图所示:

       我们来计算一下,系统A先执行本地sql,然后调用系统B,接着调用系统C,最后调用系统D。四个步骤下来,一个请求全部完成,需要耗时的总时长是970ms。这样,用户在浏览器上发起了请求,等待1s,体验很差,用户难以接受。而且,一般的互联网企业,对用户的直接操作,一般要求是200ms以内完成,对用户几乎是无感知的。      

      使用了MQ后,可以利用MQ对不同的系统发送命令,进行异步操作,如下图所示:

      我们可以看到,系统A从收到用户的请求后,26ms内就有返回了,这对于用户而言,体验很好,一个请求26ms,就有返回了。

      3. 削峰

      这一点主要是针对在用户使用高峰期的时候,使用MQ作为cache,以防止MySql被打满,导致请求卡死。我们先来看下未使用MQ的情况,如下图所示:

从上图中的四点,我们可以看出,如果MySql被打死,整个系统就奔溃了,最后,就会导致用户没法使用整个系统了。这里说明一下,一般的MySql扛到每秒2000的请求,也就差不多了。如果每秒5000,有可能会直接把MySql打死。      

       使用MQ作为缓存以后,如下图所示:

高峰取时在MQ中进行大量请求积压,处理器按照自己的最大处理能力取请求量,等请求期过后再把它消耗掉。我们可以简单的计算下,假设每秒在MQ中堆积的消息是3000条,1分钟会堆积18万条消息,1小时会积压1000万条消息。系统A,一个多小时,差不多可以把1000万消息给处理掉,MQ也就没有消息的积压了。

 

消息队列有什么缺点

     1.系统的可用性降低:很多服务都依赖于MQ,一旦MQ故障,系统崩溃。

     2.系统变的复杂,序列考虑问题变多:发送消息重复,多了,乱序,丢掉。

     3.一致性问题:系统A给BCD发送,只有都成功才返回成功,结果BC成功,但是D失败,但是返回页面结果是成功。

 

每一个MQ都有什么异同和适用场景

ActiveMQ

       最早大家都用ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,单机吞吐量,万级,吞吐量比RocketMQ和Kafka要低了一个数量级,响应为ms级别,有较低的概率丢失数据。

 

RabbitMQ

       单机吞吐率万级,吞吐量比RocketMQ和Kafka要低了一个数量级,但是适合于中小型企业,因为自带了友好的监控和维护界面,社区相对比较活跃,几乎每个月都发布几个版本分,在国内一些互联网公司近几年用rabbitmq也比较多一些,但是问题也是显而易见的,RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重,同时语言在国内很少有人会。

 

RocketMQ

       单机吞吐量10万级,RocketMQ也是可以支撑高吞吐的一种MQ,topic可以达到几百,几千个的级别,吞吐量会有较小幅度的下降,这是RocketMQ的一大优势,在同等机器下,可以支撑大量的topic,可用性非常高,分布式架构,在阿里大规模应用过,有阿里品牌保障,日处理消息上百亿之多,可以做到大规模吞吐,性能也非常好,分布式扩展也很方便,源码是JAVA。

 

Kafka

      单机吞吐量10万级别,这是kafka最大的优点,就是吞吐量高。一般配合大数据类的系统来进行实时数据计算、日志采集等场景。topic从几十个到几百个的时候,吞吐量会大幅度下降。

 

      所以在同等机器下,kafka尽量保证topic数量不要过多。如果要支撑大规模topic,需要增加更多的机器资源,可用性非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用。

分享到:
评论

相关推荐

    php+redis实现消息队列功能示例

    个人理解在项目中使用消息队列一般是有如下几个原因: 把瞬间服务器的请求处理换成异步处理,缓解服务器的压力 实现数据顺序排列获取 redis实现消息队列步骤如下: 1).redis函数rpush,lpop 2).建议定时任务入队列 ...

    积分管理系统java源码-rabbitmq-demo:消息队列RabbitMQdemo

    消息队列简介 选择衡量指标: 1)服务性能 2)数据存储 3)集群架构 几种常见消息队列的对比: ActiveMQ 功能强劲但是并发性能不够好,不适用于高并发的复杂的项目。 架构模式: Kafka 刚开始是为了收集和传输日志,...

    C#开发基于FreeSql多库分布式事务、跨库查询、跨库分页查询、跨库增删改等功能实现源码+项目说明+sln.zip

    那么就决定使用`CAP(最终一致性事务)` 由于项目持续的改版,业务的实时性变得越来越高,基于消息队列的这种最终一致性或者说异步事务的方案 越来越不适合我们的项目,这时候就需要同步的事务方案,TCC/SAGE又没有...

    计算机软件项目设计方案(2020).docx

    技术实现事务管理、服务日志、统一异常处理,在远程服务调用中使用RPC Context实现上下文管理,持久化框架采用Hibernate、Mybatis双框架兼容设计,使用数据访问代理服务,实现分库分表环境下的透明数据访问。...

    rabbitmq-microservice-study:微服务中rabbitmq的使用

    1.rabbitMQ消息中间件(注意:安装mq之前先安装erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的) 2.Redis(这里redis的目的是保存消费次数) 二、Mq消息机制: 1、mq消息机制几个重要的组件: 1)、...

    springCloud

    AMQP,即Advanced message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。 ...

    基于Java+MySQL设计与实现的秒杀与抢购模型架构【100013279】

    4.使用Redis作为原子计数器(watch事务+decr操作),RabbitMQ作为消息队列记录用户抢购行为,MySQL做异步存储。 上述四个解决方案均使用了JMeter进行压力与性能测试(实验设置的是10秒内产生3000个请求),分析其...

    asp.net知识库

    也论该不该在项目中使用存储过程代替SQL语句 如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典信息 C#中利用GetOleDbSchemaTable获取数据库内表信息...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    目前市场业务中在产品以及其他项目的认证和检测方面存在诸多不便,用户需要实地考察并频繁与检测单位沟通,填写繁琐的纸质检测报告、当面送递样品,对于检测环节中存在的问题难以及时交互并处理。市场上相应的检测...

    kafka-retry:卡夫卡重试

    Kafka-重试机制和延迟队列介绍该项目旨在隔离重试机制和延迟队列的实现。 当我们想到一个容错系统时,我们... 基本思想是,当使用者执行集成并且由于不可用原因而失败时,他会为retry主题生成一条新消息。 此新消息应该

    携程基于Flink的实时特征平台

    依据项目的性能指标要求(latency,throughput等),在已有的实时计算平台:StormSparkflink进行选择1.2主要的开发运维过程:80%以上的作业需要用到消息队列数据源,但是消息队列为非结构化数据且没有统一的数据字典...

    计算机二级C语言考试题预测

    (23) 下列关于队列的叙述中正确的是(C) A. 在队列中只能插入数据 B. 在队列中只能删除数据 C. 队列是先进先出的线性表 D. 队列是先进后出的线性表 (24) 对建立良好的程序设计风格,下面描述正确的是(A) 注:P48 A. ...

Global site tag (gtag.js) - Google Analytics