专栏名称: 分布式实验室
最专业的Docker文章,最权威的Docker新闻。关注容器生态圈的发展。
目录
相关文章推荐
51好读  ›  专栏  ›  分布式实验室

一次模拟简单秒杀场景的实践 Docker + Node.js + Kafka + Redis + MySQL

分布式实验室  · 公众号  · 后端  · 2017-02-05 08:00

正文

秒杀活动可以说在互联网上随处可见,从12306抢票,到聚划算抢购,我们生活的方方面面都可以看到秒杀的身影。秒杀的架构设计也是对于一个架构师架构设计能力的一次考验。本文的目的并不在于提供一个可以直接落地的设计方案,而是意在提供一个简单的方法,一个思路,使大家能够对于秒杀背后的一些设计有更感性的认识, 并且可以自己亲自动手实践一下。所有的配置及源码都在本文最后的GitHub repository中可以找到,或者点击阅读原文链接。

首先,先简单介绍下本文中会涉及到的一些组件,如下图所示:

JMeter:用JMeter来模拟秒杀活动中大量并发的用户请求

Seckill Service:基于Node.js使用Express实现的秒杀service,图中的步骤2,3,4都是在这个service中处理的

Redis:一个Redis的docker container,在其中保存一个名为counter的数据来表示当前剩余的库存大小

Kafka:一个Kafka的docker container,其实这里还有一个zookeeper的docker container,Kafka用ZooKeeper来存放一些元数据,在程序中并没有涉及到,所以也就不单独列出来说了。Seckill service在更新完Redis之后,会发送一条消息给Kafka表示一次成功的秒杀

Seckill Kafka Consumer:基于Node.js的Kafka consumer,会从Kafka中去获取秒杀成功的消息,处理并且存储到MySQL中

MySQL:一个MySQL的docker container,最终秒杀成功的请求都会对应着数据库表中的一条记录

环境搭建

安装JMeter

从官网下载一个JMeter的binary包,执行bin目录下的jmeter即可启动,启动后如下图新建一个名为Seckill的Thread Group,并且设置在5s内发起2000次并发请求。

在这个Thread Group下新建一个Http Request的Sampler并命名为Seckill,按下图配置host name,port number,http request method以及request path。

安装Redis、Kafka、ZooKeeper和MySQL

为了方便搭建环境,这几个组件会以docker container的形式启动。在此之前需要去Docker官网下载并安装Docker Engine,Docker Machine和Docker Compose。如果是在Windows或者Mac上,Docker官网提供Docker For Windows/Docker For Mac安装程序,可以很方便的把这3个组件安装好。

编写Docker Compose文件

创建一个Seckill项目文件夹,新建一个docker-compose.yml文件,内容如下:

配置文件中一共配置了4个services对应4个docker container,分别是ZooKeeper、Kafka、Redis以及MySQL。这里有两个地方需要设置成你实际环境的值,一个是Kafka配置下面的KAFKA_ADVERTISED_HOST_NAME字段,这个需要设置成本地机器的IP。另一个是MySQL配置下面的MYSQL_ROOT_PASSWORD,你可以设置成你想要的任何值。

创建好这个文件之后,就可以去命令行项目根目录中执行docker-compose up,docker engine就会把上面配置的这4个组件全部启动起来。

注意:在启动完之后,需要去Kafka容器中创建一个名为CAR_NUMBER的topic,去Redis容器中创建一个名为counter的计数器(设置值为100,代表库存初始值为100),去MySQL容器中创建一个名为seckill的数据表(包含一个自增长的ID自段和一个timestamp格式的date字段)。

代码片段

Seckill Service

seckill_kafka_consumer

这里的代码就比较简单了,会初始化一个kafka consumer监听CAR_NUMBER topic,对于新获取的消息会去MySQL的seckill表里插入一条记录。

操作步骤

结果

JMeter request results

 

Redis counter field

 

MySQL seckill table

可以看到,最后redis中的counter变成0,seckill数据表中会插入100条记录,没有发生超卖或者少卖的情况。当然在实际生产环境场景中,还有许多其它需要考虑的地方,希望此文可以起到一个抛砖引玉的作用,帮助大家更好的理解秒杀场景。

项目GitHub地址点击阅读原文链接,或者浏览器输入:https://github.com/geshenyi/MockSecKill