- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Docker + Nodejs + Kafka + Redis + MySQL搭建简单秒杀环境由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
秒杀活动可以说在互联网上随处可见,从12306抢票,到聚划算抢购,我们生活的方方面面都可以看到秒杀的身影。秒杀的架构设计也是对于一个架构师架构设计能力的一次考验。本文的目的并不在于提供一个可以直接落地的设计方案,而是意在提供一个简单的方法,一个思路,使大家能够对于秒杀背后的一些设计有更感性的认识, 并且可以自己亲自动手实践一下。所有的配置及源码都在本文最后的github repository中可以找到.
首先,先简单介绍下本文中会涉及到的一些组件,如下图所示:
jmeter:用jmeter来模拟秒杀活动中大量并发的用户请求 。
seckill service:基于nodejs使用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: 基于nodejs的kafka consumer,会从kafka中去获取秒杀成功的消息,处理并且存储到mysql中 。
mysql:一个mysql的docker container,最终秒杀成功的请求都会对应着数据库表中的一条记录 。
环境搭建 。
1 . 安装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 。
2 . 安装redis,kafka, zookeeper和mysql 为了方便搭建环境,这几个组件会以docker container的形式启动。在此之前需要去docker官网下载并安装docker engine,docker machine和docker compose。如果是在windows或者mac上,docker官网提供docker for windows/docker for mac安装程序,可以很方便的把这3个组件安装好.
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字段).
代码片段 。
1 . seckill service 。
第1-8行,引入了程序需要用到的对象,nodejs的mvc框架express, redis, kafka等 。
第10行,利用express提供的方法暴露出一个path为/seckill的post方法 。
第12行,定义了一个方法,在54行会调用 。
第13-22行,新建了一个redis client并且监听error事件 。
第23行,这行代码非常关键,它的作用是让redis cilent监视redis中的counter值,之后会启动一个事务,如果在事务提交的时候发现有其它client修改了counter值的话,就会放弃这个事务.
第24行,通过redis client的异步方法获取counter的值,因为redis的get操作是原子的,所以在这里不用担心有并发读写的问题.
第25-28行,判断返回的库存值是否大于0,如果大于0,通过client.multi()启动一个事务,通过decr()方法将counter值减1,最后通过exec()方法提交事务;如果小于0,则执行第47行,打印卖完了并且关闭redis client.
第29-46行,这里我们看一下multi.exec()中的这个回调方法。在前面我们已经使用watch对counter进行了监视。如果在事务提交过程中有其它client修改了counter值的话,回调方法中的replies参数就会是null,可以看到第29-31行,程序会打印“可能有冲突”并且再次调用fn方法重试。 如果replies的值不为null,就会使用kafka的producer发送一条message到car_number topic.
2 . seckill_kafka_consumer 。
这里的代码就比较简单了,会初始化一个kafka consumer监听car_number topic,对于新获取的消息会去mysql的seckill表里插入一条记录.
操作步骤 。
启动docker container 。
启动seckill_service 。
启动seckill_kafka_consumer 。
启动jmeter发送2000个并发请求 。
结果 jmeter request results 。
redis counter field 。
mysql seckill table 。
可以看到,最后redis中的counter变成0,seckill数据表中会插入100条记录,没有发生超卖或者少卖的情况。当然在实际生产环境场景中,还有许多其它需要考虑的地方,希望此文可以起到一个抛砖引玉的作用,帮助大家更好的理解秒杀场景.
项目github地址: mockseckill 。
原文链接:http://www.jianshu.com/p/c18e61d0726c 。
最后此篇关于Docker + Nodejs + Kafka + Redis + MySQL搭建简单秒杀环境的文章就讲到这里了,如果你想了解更多关于Docker + Nodejs + Kafka + Redis + MySQL搭建简单秒杀环境的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在使用以下dockerfile: FROM ubuntu:14.04 MAINTAINER xxx xxx # SSH RUN apt-get update && apt-get install
我运行了docker-compose build celery,(经过数小时的尝试,我的连接不良)成功了。 app Dockerfile的前80%是相同的,但不会重复使用缓存。从我可以浏览的内容来看,
我可以使用以下命令成功创建 Docker 注册表 v2 服务:docker service create 然后我使用 docker Push 将一些图像推送到该服务。 当我通过 curl localh
我正在尝试使用 gitlab 构建 CI,我从 docker 的 docker 镜像开始,我的前端存储库没有任何问题,但现在使用相同的 gitlab-ci 配置文件,我有此守护程序错误。 这是构建的输
用例: 我们在 Jenkins 中有几个“发布作业”build 和 push 应用程序的 Docker 镜像到 docker registry,更新各种文件中的项目版本,最后将发布标签推送到相应的 G
当我尝试构建我的 docker 文件时,docker 返回以下错误: [+] Building 0.0s (1/2)
docker-in-docker 的作者在此博客中建议不要将此图像用于 CI 目的: jpetazzo/Using Docker-in-Docker for your CI or testing en
我创建了一个 Dockerfile 来在 Docker 中运行 Docker: FROM ubuntu:16.04 RUN apt-get update && \ apt-get in
我尝试为 Docker 镜像定位一个特定标签。我怎样才能在命令行上做到这一点?我想避免下载所有图像,然后删除不需要的图像。 在 Ubuntu 官方版本中,https://registry.hub.do
我正在尝试在docker中运行docker。唯一的目的是实验性的,我绝不尝试实现任何功能,我只想检查docker从另一个docker运行时的性能。 我通过Mac上的boot2docker启动docke
docker-compose.yml version: "3" services: daggr: image: "docker.pvt.com/test/daggr:stable"
我有一个非常具体的开发环境用例。在一些代码中,我启动了一个容器来抓取页面并检索在容器中运行的服务(Gitlab)的 token 。 现在,我希望 Dockerize 运行它的代码。具体来说,类似: o
之前已经问过这个问题,但我不确定当时是否可以使用docker-compose文件完成docker堆栈部署。 由于最新版本支持使用compose将服务部署到堆栈,因此,我无法理解dab文件的值。 我检查
我在一次采访中被问到这个问题,但无法回答。也没有找到任何相关信息。 最佳答案 正如 Docker 文档中所述,Docker 注册表是: [...] a hosted service containin
有没有一种方法可以将具有给定扩展名的所有文件复制到Docker中的主机?就像是 docker cp container_name:path/to/file/in/docker/*.png path/o
我的日志驱动程序设置为journald。使用日志记录驱动程序时,daemon.json文件中的日志级别配置会影响日志吗?使用docker logs 时仅会影响容器日志? 例如,docker和journ
我最近开始使用Docker + Celery。我还共享了full sample codes for this example on github,以下是其中的一些代码段,以帮助解释我的观点。 就上下文
运行docker build .命令后,尝试提交构建的镜像,但收到以下错误 Step 12 : CMD activator run ---> Using cache ---> efc82ff1ca
我们有docker-compose.yml,其中包含Kafka,zookeeper和schema registry的配置 当我们启动docker compose时,出现以下错误 docker-comp
我是Docker的新手。是否可以在Docker Hub外部建立Docker基本镜像存储库?假设将它们存储在您的云中,而不是拥有DH帐户?谢谢。 最佳答案 您可以根据需要托管自己的注册表。可以在Depl
我是一名优秀的程序员,十分优秀!