消息队列应用场景介绍

一、什么是队列

队列(Queue)是一种常见的数据结构,其最大的特点就是先进先出(First In First Out),作为最基础的数据结构,队列应用很广泛。比如火车站排队买票等等。可以用下图表示队列:

其中a1、a2、an表示队列中的数据。数据从队尾入队列,然后从队头出队列。

二、什么是消息队列

消息队列(Message Queue)是一种使用队列(Queue)作为底层存储数据结构,可以用于解决不同进程与应用程序之间通讯的分布式消息容器,也可以称为消息中间件。

目前比较常用的消息队列有ActiveMQ、RabbitMQ、Kafka、RocketMQ、Redis等。

消息队列和队列有什么区别呢?

唯一的区别在于入队列的时候称为生产者,出队列的时候称为消费者。

三、消息队列应用场景

消息队列应用场景非常广泛,下面我们列举比较常见的几个场景

1、分布式场景

1.1、异步处理

一般我们写的程序都是按照顺序执行的(即同步的方式)。比如电商系统中订单的例子,其执行顺序如下:

用户提交订单。订单完成以后增加积分。发生积分变动的短信通知。

可以用下面的流程图表示:

如果按照上面的顺序执行,假如每个服务都需要花费一秒,那么客户端就要花费3秒的时间。对于用户来说,3秒的时间显然是不能忍受的,那么我们该如何解决呢?我们可以使用异步的方式来解决这个问题,看下面一张流程图:

按照这种方式,积分服务和短信服务使用线程异步的方式进行操作,那么客户端只需要花费1秒的时间就可以完成了。但是,这种异步的方式会带来另外的问题:并发量降低。因为积分服务和短信服务都需要在订单服务里面开启线程,开启的线程多了,会导致客户端访问订单服务的并发量降低,可能导致客户端提交订单的实际时间会超过1秒钟。那么如何解决异步带来的问题呢?那就是使用消息队列,看下面的流程图:

在上面的流程中,我们增加了一个消息队列的角色,首先由客户端提交订单,然后把订单写入到消息队列,积分服务和短信服务同时去消费消息队列里面的消息,这种方式不需要订单服务在额外的开启异步线程,客户端可以实现真正的耗时1秒。

1.2、应用解耦

我们还是以电商系统为例进行讲解,先看下面的流程图:

上图的业务逻辑:客户端发起一个创建订单的请求,创建订单的时候,我们要先获取库存,然后在去扣减库存,这样订单系统和库存系统就形成了非常紧密的依赖关系。假如这时候库存系统发生了宕机,由于订单系统依赖于库存系统,这时候订单系统将不能使用。那么如何解决呢?

看下面使用消息队列的流程图:

在上面的流程中,我们加入了消息队列。首先客户端发起创建订单的请求,订单的消息写入到消息队列里面,然后库存系统去消息队列里面订阅消息,最后异步的去更新库存系统。如果库存系统发生了宕机,由于订单系统不直接依赖于库存系统,所以订单系统可以正常的响应客户端的请求。这样就实现了应用解耦。

1.3、流量削峰

对于高并发的系统来说,在访问高峰时,突发的流量就像洪水般涌向应用系统,尤其是一些高并发写操作,随时会导致数据库服务器瘫痪,无法继续提供服务。

而引入消息队列则可以减少突发流量对应用系统的冲击。消费队列就像“水库”一样,拦截上游的洪水,削减进入下游河道的洪峰流量,从而达到减免洪水灾害的目的。

在这方面最常见的例子就是秒杀系统,一般秒杀活动瞬间流量很高,如果流量全部涌向秒杀系统,会压垮秒杀系统,通过引入消息队列,可以有效缓冲突发流量,达到“削峰”的作用。

我们使用秒杀的场景来描述流量削峰,先看下面一张流程图:

在上面的流程中,我们把秒杀服务称为上游服务,订单服务、库存服务、余额服务统称为下游服务。客户端发起秒杀的请求,秒杀服务收到客户端发送的请求以后,创建订单,修改库存,扣减余额,这是秒杀的基本业务场景。

假如下游服务只能同时处理1000个并发请求,上游服务可以处理10000个并发请求,而客户端发起了10000个请求,超出了下游服务可以处理的并发量,所以会导致下游服务发生宕机。这时就可以加入消息队列来解决宕机的问题。看下面加入消息队列的流程图:

我们在上面的流程图中加入了消息队列,描述服务接收到客户端发送的10000个请求以后,把所有的请求都写入到消息队列中,然后下游服务去订阅消息队列里面的秒杀请求,然后在去执行自己的业务逻辑操作。

我们举个简单的例子,上游服务还是能处理10000个并发请求,下游服务还是只能处理1000个并发请求,那么这时候我们在消息队列里面会允许存1000个并发请求。上游的秒杀服务接收到10000个并发请求,而消息队列里面只能存1000个请求,多余的请求就不会存入到消息队列里面,直接返回给客户端提示“系统繁忙,请稍后!”。这就是所谓的流量削峰场景。这是由下游服务可以处理的并发量决定的。由于下游服务只能处理1000个并发请求,所以消息队列里面只能存1000个秒杀,多余的秒杀请求全部返回客户端提示。这样就保证了下游服务的正常响应,不会导致下游服务发生宕机,提高了系统的可用性。

2、日志场景

优化日志传输

为了程序的健壮性,我们一般会在程序中添加各种记录日志的功能,比如错误日志、操作日志等等,看下面一张流程图:

上面的流程图是同步记录日志的流程。使用同步记录日志的流程,会使得整个流程花费的时间增多,而且也会容易造成业务系统宕机(如果数据库损坏了,向数据库记录日志的操作将会产生错误)。我们可以使用消息队列的方式优化日志的传输。看下面的流程图:

加入了消息队列以后,可以缩短系统花费的时间,而且也可以达到应用系统解耦的功能。

3、及时通讯场景

聊天室

消息队列最主要功能是收发消息,其内部有高效的通讯机制,因此非常适合用于消息通讯。

我们可以基于消息队列开发点对点的聊天系统,也可以开发广播系统,用于将消息广播给大量接收者。

到此这篇关于消息队列应用场景的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • asp.net通过消息队列处理高并发请求(以抢小米手机为例)

    网站面对高并发的情况下,除了增加硬件, 优化程序提高以响应速度外,还可以通过并行改串行的思路来解决.这种思想常见的实践方式就是数据库锁和消息队列的方式.这种方式的缺点是需要排队,响应速度慢,优点是节省成本. 演示一下现象 创建一个在售产品表 CREATE TABLE [dbo].[product]( [id] [int] NOT NULL,--唯一主键 [name] [nvarchar](50) NULL,--产品名称 [status] [int] NULL ,--0未售出 1 售出 默认为0

  • 深入理解redis分布式锁和消息队列

    最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存不同,利用的是redis可设置key的有效时间和redis的BRPOP命令. 分布式锁 由于目前一些编程语言,如PHP等,不能在内存中使用锁,或者如Java这样的,需要一下更为简单的锁校验的时候,redis分布式锁的使用就足够满足了. redis的分布式锁其实就是基于setnx方法和redis对key可设置有效时间的功能来实现的.基本用法比较简单. public boolean tryLock(String loc

  • RabbitMQ .NET消息队列使用详解

    本文实例为大家分享了RabbitMQ .NET消息队列使用方法,供大家参考,具体内容如下 首先下载安装包,我都环境是win7 64位: 去官网下载 otp_win64_19.0.exe  和rabbitmq-server-3.6.3.exe安装好 然后开始编程了: (1)创建生产者类: class Program { private static void Main() { //建立RabbitMQ连接和通道 var connectionFactory = new ConnectionFacto

  • 使用 Redis 流实现消息队列的代码

    在介绍了 Redis 流的基本功能之后, 现在是时候使用这些功能来构建一些实际的应用了. 消息队列作为流的典型应用之一, 具有非常好的示范性, 因此我们将使用 Redis 流的相关功能构建一个消息队列应用, 这个消息队列跟我们之前使用其他 Redis 数据结构构建的消息队列具有相似的功能. 代码清单 10-1 展示了一个具有基本功能的消息队列实现: 代码最开头的是几个转换函数, 它们负责对程序的相关输入输出进行转换和格式化: MessageQueue 类用于实现消息队列, 它的添加消息.移除消息

  • C#调用RabbitMQ实现消息队列的示例代码

    前言 我在刚接触使用中间件的时候,发现,中间件的使用并不是最难的,反而是中间件的下载,安装,配置才是最难的. 所以,这篇文章我们从头开始学习RabbitMq,真正的从头开始. 关于消息队列 其实消息队列没有那么神秘,我们这样想一下,用户访问网站,最终是要将数据以HTTP的协议的方式,通过网络传输到主机的某个端口上的. 那么,接收数据的方式是什么呢?自然是端口监听啦. 那消息队列是什么就很好解释了? 它就是端口监听,接到数据后,将数据排列起来. 那这件事,我们不用中间件能做吗? 当然能做啦,写个T

  • Python进程间通信Queue消息队列用法分析

    本文实例讲述了Python进程间通信Queue消息队列用法.分享给大家供大家参考,具体如下: 进程间通信-Queue Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信. 1. Queue的使用 可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息列队程序,首先用一个小实例来演示下Queue的工作原理: 代码如下: #coding=utf-8 from multiprocessing import Queue #初始化一个

  • RabbitMQ延迟队列及消息延迟推送实现详解

    这篇文章主要介绍了RabbitMQ延迟队列及消息延迟推送实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给支付系统,通知支付系统将款打给商家,这个过程持续七天,就是使用了消息中间件的延迟推送功能. 12306 购票支付确认页面.我们在选好票点击确定跳转的页面中往往都会有倒计时,代表着 3

  • .net msmq消息队列实例详解

    本文为大家分享了.net msmq消息队列实例代码,供大家参考,具体内容如下 1.msmq消息队列windows环境安装 控制面板---->程序和功能---->启用或关闭Windows程序---->Microsoft Message Queue(MSMQ)服务器 选中如图所示功能点击"确认"进行安装,安装好后可在 "计算机管理"中进行查看 2.创建消息队列实体对象 /// <summary> /// 消息实体 /// </summ

  • .NetCore利用BlockingCollection实现简易消息队列

    消息队列现今的应用场景越来越大,常用的有RabbmitMQ和KafKa. 我们用BlockingCollection来实现简单的消息队列. BlockingCollection实现了生产者/消费者模式,是对IProducerConsumerCollection<T>接口的实现.与其他Concurrent集合一样,每次Add或Take元素,都会导致对集合的lock.只有当确定需要在内存中创建一个生产者,消费者模式时,再考虑这个类. MSDN中的示例用法: using (BlockingColle

  • 使用MQ消息队列的优缺点详解

    前言 公司的项目一直都是在使用MQ的,但是由于使用的功能很简单,所以一直都是知其然不知其所以然,作为一个程序猿有必要了解每一个使用的技术,为什么使用它?它的优点是什么?缺点是什么?等等... 使用mq的好处 解耦与复用 系统A要发送一个消息到多个系统,如果此时每增加一个系统,系统A都需要通过修改源码来增加接口,此时耦合非常高,但是如果中间使用消息队列的话,系统只需要发送一次到消息队列,别的系统就能复用该信息,当增加或删除系统调用接口的时候,不需要额外的更新代码. 异步 用户调用一个接口的时候,可

随机推荐