热门标签 | 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已经挂掉了。


推荐阅读
  • 本文提供了 RabbitMQ 3.7 的快速上手指南,详细介绍了环境搭建、生产者和消费者的配置与使用。通过官方教程的指引,读者可以轻松完成初步测试和实践,快速掌握 RabbitMQ 的核心功能和基本操作。 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • Spring Boot使用AJAX从数据库读取数据异步刷新前端表格
      近期项目需要是实现一个通过筛选选取所需数据刷新表格的功能,因为表格只占页面的一小部分,不希望整个也页面都随之刷新,所以首先想到了使用AJAX来实现。  以下介绍解决方法(请忽视 ... [详细]
  • 阿里巴巴终面技术挑战:如何利用 UDP 实现 TCP 功能?
    在阿里巴巴的技术面试中,技术总监曾提出一道关于如何利用 UDP 实现 TCP 功能的问题。当时回答得不够理想,因此事后进行了详细总结。通过与总监的进一步交流,了解到这是一道常见的阿里面试题。面试官的主要目的是考察应聘者对 UDP 和 TCP 在原理上的差异的理解,以及如何通过 UDP 实现类似 TCP 的可靠传输机制。 ... [详细]
  • CentOS下ProFTPD的安装与配置指南
    本文详细介绍在CentOS操作系统上安装和配置ProFTPD服务的方法,包括基本配置、安全设置及高级功能的启用。 ... [详细]
  • 解决JavaScript中法语字符排序问题
    在开发一个使用JavaScript、HTML和CSS的Web应用时,遇到从SQLite数据库中提取的法语词汇排序不正确的问题,特别是带重音符号的字母未按预期排序。 ... [详细]
  • 从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ... [详细]
  • 深入理解:AJAX学习指南
    本文详细探讨了AJAX的基本概念、工作原理及其在现代Web开发中的应用,旨在为初学者提供全面的学习资料。 ... [详细]
  • flea,frame,db,使用,之 ... [详细]
  • 尽管Medium是一个优秀的发布平台,但在其之外拥有自己的博客仍然非常重要。这不仅提供了另一个与读者互动的渠道,还能确保您的内容安全。本文将介绍如何使用Bash脚本将Medium文章迁移到个人博客。 ... [详细]
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • 修复一个 Bug 竟耗时两天?真的有那么复杂吗?
    修复一个 Bug 竟然耗费了两天时间?这背后究竟隐藏着怎样的复杂性?本文将深入探讨这个看似简单的 Bug 为何会如此棘手,从代码层面剖析问题根源,并分享解决过程中遇到的技术挑战和心得。 ... [详细]
  • 本文详细介绍了Elasticsearch中的分页查询机制,包括基本的分页查询流程、'from-size'浅分页与'scroll'深分页的区别及应用场景,以及两者在性能上的对比。 ... [详细]
  • Level:  Medium题目描述:Givenanon-emptystringsandadictionarywordDictcontainingalistofnon-emptyw ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
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社区 版权所有