热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RocketMQ在秒杀时的应用

目录一、RocketMQ是什么二、broker和nameserver2.1Broker2.2NameServer三、MQ在秒杀场景下的应用3.1利用MQ进行异步操作3.

目录

一、RocketMQ是什么

二、broker和nameserver

2.1 Broker

2.2 NameServer

三、MQ在秒杀场景下的应用

3.1 利用MQ进行异步操作

 3.2 削峰填谷

四、面试题

问1:任何一台 Broker 突然宕机了怎么办?那不就会导致 RocketMQ 里一部分的消息就没了吗?这就会导致 MQ 的不可靠和不可用,这个问题怎么解决?

问2:如果Broker宕了,NameServer是怎么感知到的?



一、RocketMQ是什么

消息中间件的发展:

第一代以ActiveMQ为代表,遵循JMS(java消息服务)规范                                                                                                 

第二代以RabbitMQ为代表是一个有Erlang语言开发的AMQP(高级消息队列协议)的开源实现                                               

第三代以kafka为代表,是一代高吞吐、高可用的消息中间件,以及RocketMQ

RocketMQ物理部署结构如下:

几个概念术语:

producer:消息生产者,生产者的作用就是将消息发送到 MQ,生产者本身既可以产生消息,如读取文本信息等。也可以对外提供接口,由外部应用来调用接口,再由生产者将收到的消息发送到 MQ

producer group: 生产者组,简单来说就是多个发送同一类消息的生产者称之为一个生产者组。

consumer : 消息消费者,简单来说,消费 MQ 上的消息的应用程序就是消费者

consumer group : 消费者组,和生产者类似,消费同一类消息的多个 consumer 实例组成一个消费者组.Consumer实例 的集合。

Topic : Topic 是一种消息的逻辑分类,比如说你有订单类的消息,也有库存类的消息,那么就需要进行分类,一个是订单 Topic 存放订单相关的消息,一个是库存 Topic 存储库存相关的消息。

Broker : Broker 是 RocketMQ 系统的主要角色,其实就是前面一直说的 MQ。Broker 接收来自生产者的消息,储存以及为消费者拉取消息的请求做好准备。

Message : Message 是消息的载体。一个 Message 必须指定 topic,相当于寄信的地址。Message 还有一个可选的 tag 设置,以便消费端可以基于 tag 进行过滤消息。

Tag : 标签可以被认为是对 Topic 进一步细化。一般在相同业务模块中通过引入标签来标记不同用途的消息。

Name Server : Name Server 为 producer 和 consumer 提供路由信息。

 

二、broker和nameserver

2.1 Broker

如下图,我们看看broker是什么,可以看到,每个broker都有一个或多个 Topic(Broker和Topic是多对多的关系),下图的MessageQueue是一个存放消息的队列,一边去存放消息,一边去消费消息。

2.2 NameServer

nameserver提供的路由功能,如下图,例如:

1.Broker 一开始是得向 NameServer注册的,注册的信息包括Broker的ip,Broker负责的消息的Topic,有多少个queue等。

2. 而Producer(生产者)则是会通过NameServer找到Broker,并向Broker中的消息队列(queue)放入消息,如果queue有多个,则会通过轮询的方式来放入消息。

3. 而Consumer(消费者)则是通过NameServer抓取信息,以Topic为单位抓取的,NameServer会返回对应Topic的Broker给Consumer,然后Consumer就可以去Broker上抓取对应的消息了。过程是,Consumer会对Broker上的两个queue分别建立长连接, 如果有消息的话,直接拉走,如果没有消息,Consumer就会长轮询等待,直到有消息放入queue。

4. 当Consumer消费完消息后,Consumer要回复一个信息给对应的queue,告诉queue该消息已经被消费,那么queue就会把该消息删除。

5. 当一个queue被多个Consumer消费的时候,就会出现同步问题,就会有一个锁竞争的问题,因此RocketMQ使用了以queue为单位,平均地分配到各个Consumer,即N个queue就对应N个Consumer,即一个queue就有一个Consumer。所以一个好的中间件,Consumer group中Consumer的数量应该近乎于跟对应的queue的数量相等。Consumer的数量若比queue的数量多,则会有Consumer消费不到消息,若比queue数量少,则会有一个Consumer消费多个消息。

 

三、MQ在秒杀场景下的应用

3.1 利用MQ进行异步操作

对于一个电商APP而言,每卖掉了一个商品,就要扣减掉商品的库存,而且一旦用户成功支付了,还需要将订单的状态更新成待发货。

在完成这些最核心的功能后,其实是有很多事情要做的,比如上图红色的部分。如果这些动作都以同步方式来完成,根据线上系统的一般统计,多个子步骤全部执行完毕,加起来大概需要1秒~2秒的时间。

有时候在高峰期并发量特别大,服务器的磁盘、IO、CPU的负载会很高,执行SQL语句的性能也会有所下降。因此有的时候甚至需要几秒钟的时间完成上述几个步骤。

那么影响是什么呢?

想象一下,如果你是一个用户,在支付完一个订单之后,界面上会有一个圈圈不停的旋转,让你等待好几秒之后才能提示支付成功。对用户来说几秒钟的时间,会让人非常不耐烦的!

所以首先针对子步骤过多、速度过慢、让用户支付之后等待时间过长的问题,就是订单系统亟需解决的问题!

而解决这个问题的一大利器就是消息中间件,英文全称“Message Queue”,简称MQ。

在引入消息中间件以后,系统A和系统B之间就由同步变为异步通信,而完成这样的一个核心概念就是“消息”

系统A发送消息给MQ后,就认为已经完成了自己的任务;然后系统B根据自己的情况,可能会在系统A投递消息到MQ之后的1秒内,也可能是1分钟之后,也可能是1小时之后,多长时间都有可能。

反正不管是多长时间后,系统B会根据自己的节奏从MQ里获取到一条属于自己的消息,再根据消息的指示完成自己的工作。 

在“异步调用”的整个过程中,系统A仅仅是发个消息到MQ,至于系统B什么时候获取消息,有没有获取消息,系统A是不管的。

举例来说:

在秒杀活动开始前,先把活动商品的库存从数据库中读到redis中,然后用户下单,是从redis中扣减库存的(而不是直接在数据库中扣减库存),然后给MQ发送一个扣减库存的消息,然后消费者在恰当的时候读取这个消息,并从数据库中进行扣减库存的操作。这时候redis的库存往往扣减得速度比数据库快一点,因为数据库是通过MQ异步去扣减的。意思就是说,数据库的库存什么时候去扣减其实是不急的,只要最后能扣减正确就行。

总结:

我们可以让订单系统仅仅完成最核心的功能,然后发送消息到MQ。比如需要进行减库存,就发送一个消息到库存消息队列中,然后库存系统从这个MQ里获取消息再进行处理就可以,把这些很耗时的步骤慢慢执行,从而也实现了系统之间的解耦

在双11大促活动的时候,同样可以让瞬间涌入的大量下单请求到MQ里去排队,然后让订单系统在后台慢慢的获取订单,以数据库可以接受的速率完成操作,避免瞬间请求量过大击垮数据库。


 3.2 削峰填谷

MQ 除了可以使用异步的方式实现系统间的解耦,更可以在双 11 这样的秒杀活动中,通过削峰填谷的方式,处理瞬时间涌入的大量请求。

什么是削峰填谷?

削峰填谷本身是电力行业的概念,电力企业通过必要的技术和管理手段,降低电网的高峰负荷,提高低谷负荷,平滑负荷曲线,提高负荷率,保证电网的稳定运行。

假设一个应用,它能够每秒处理 1000 个请求。如果在第一秒接收到 2000 个请求,而接下来的两秒都没有请求到达。

(1)在第一秒被 2000 个请求直接压垮;

(2)假设第一秒没有被压垮,它在这一秒时间内只能处理 1000 请求,第二第三秒却完全空闲,浪费了系统资源。

红色的部分是超出系统处理能力的部分,可以把红色的那部分消息平摊到后面空闲时去处理,这样既可以保证系统负载处在一个稳定的水位,又可以尽可能地处理更多消息。

针对秒杀的场景,上游发起高并发的下单操作,由于下游处理能力有限,两端速度不匹配。此时我们引入 MQ 可以对流量进行缓冲,并实现削峰填谷。

上游速度很快,每秒发起五万个请求也没关系,它只管往 MQ 中发。下游系统虽然每秒只能处理 1000 个请求,但它完全可以 follow 自己的节奏,每隔一段时间,主动拉取若干条信息,实施限流的效果,保护自身。

3.3  秒杀大闸

为了解决秒杀令牌在活动一开始无限制生成(因为主要用户不停地访问,就会不停地创建令牌),影响系统的性能,提出了秒杀大闸的解决方案;

活动开始前,把预设的令牌数量放到redis中,然后活动开始后,用户调用秒杀接口生成令牌时,生成一个令牌,把redis中的令牌数量减一,直到减为0则不再发放令牌。

主要是为了限制令牌的个数,使其不会无限被生成。


四、面试题

问1:任何一台 Broker 突然宕机了怎么办?那不就会导致 RocketMQ 里一部分的消息就没了吗?这就会导致 MQ 的不可靠和不可用,这个问题怎么解决?

答:

RocketMQ的解决思路是Broker主从架构以及多副本策略。

Master收到消息后会同步给Slave,这样一条消息就不止一份了,Master宕机了还有slave中的消息可用,保证了MQ的可靠性和高可用新。

 

问2:如果Broker宕了,NameServer是怎么感知到的?

答:

Broker会定时(30s)向NameServer发送心跳

然后 NameServer会定时(10s)运行一个任务,去检查一下各个Broker的最近一次心跳时间,如果某个Broker超过120s都没发送心跳了,那么就认为这个Broker已经挂掉了。


推荐阅读
  • 使用WinForms 实现 RabbitMQ RPC 示例
    本文通过两个WinForms应用程序演示了如何使用RabbitMQ实现远程过程调用(RPC)。一个应用作为客户端发送请求,另一个应用作为服务端处理请求并返回响应。 ... [详细]
  • 历经两个月,他成功斩获阿里巴巴Offer
    经过两个月的努力,一位普通的双非本科毕业生最终成功获得了阿里巴巴的录用通知。 ... [详细]
  • 优化Flask应用的并发处理:解决Mysql连接过多问题
    本文探讨了在Flask应用中通过优化后端架构来应对高并发请求,特别是针对Mysql 'too many connections' 错误的解决方案。我们将介绍如何利用Redis缓存、Gunicorn多进程和Celery异步任务队列来提升系统的性能和稳定性。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 本文介绍了如何在三台CentOS 7.5虚拟机上通过Docker部署RabbitMQ集群,包括环境准备、容器创建、集群配置及故障处理等内容。 ... [详细]
  • 在 CentOS 7 上部署和配置 RabbitMQ 消息队列系统时,首先需要安装 Erlang,因为 RabbitMQ 是基于 Erlang 语言开发的。具体步骤包括:安装必要的依赖项,下载 Erlang 源码包(可能需要一些时间,请耐心等待),解压源码包,解决可能出现的错误,验证安装是否成功,并将 Erlang 添加到环境变量中。接下来,下载 RabbitMQ 的 tar.xz 压缩包,并进行解压和安装。确保每一步都按顺序执行,以保证系统的稳定性和可靠性。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 深入解析Hadoop的核心组件与工作原理
    本文详细介绍了Hadoop的三大核心组件:分布式文件系统HDFS、资源管理器YARN和分布式计算框架MapReduce。通过分析这些组件的工作机制,帮助读者更好地理解Hadoop的架构及其在大数据处理中的应用。 ... [详细]
  • RabbitMQ消息分发策略与确认机制
    本文详细介绍了RabbitMQ的消息分发轮询机制以及消息确认(Message Acknowledgment)功能,通过实例演示了如何确保消息可靠传递。 ... [详细]
  • RabbitMQ 核心组件解析
    本文详细介绍了RabbitMQ的核心概念,包括其基本原理、应用场景及关键组件,如消息、生产者、消费者、信道、交换机、路由键和虚拟主机等。 ... [详细]
  • 本文总结了近年来在实际项目中使用消息中间件的经验和常见问题,旨在为Java初学者和中级开发者提供实用的参考。文章详细介绍了消息中间件在分布式系统中的作用,以及如何通过消息中间件实现高可用性和可扩展性。 ... [详细]
  • Spring Boot + RabbitMQ 消息确认机制详解
    本文详细介绍如何在 Spring Boot 项目中使用 RabbitMQ 的消息确认机制,包括消息发送确认和消息接收确认,帮助开发者解决在实际操作中可能遇到的问题。 ... [详细]
  • 本文提供了 RabbitMQ 3.7 的快速上手指南,详细介绍了环境搭建、生产者和消费者的配置与使用。通过官方教程的指引,读者可以轻松完成初步测试和实践,快速掌握 RabbitMQ 的核心功能和基本操作。 ... [详细]
author-avatar
Cyndi_lidi_816
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有