Docker + Nodejs + Kafka + Redis + MySQL搭建簡單秒殺環境

2021-01-15 網易

  秒殺活動可以說在網際網路上隨處可見,從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條記錄,沒有發生超賣或者少賣的情況。當然在實際生產環境場景中,還有許多其它需要考慮的地方,希望此文可以起到一個拋磚引玉的作用,幫助大家更好的理解秒殺場景。

特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺「網易號」用戶上傳並發布,本平臺僅提供信息存儲服務。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關焦點

  • Apache+MySQL+Redis+nodejs
    Linux+Apache+MySQL+Redis+nodejscentos7.8apache(httpd-2.4.39)Mysql-5.7.29Redis-5.0.7nodejs(node-12.2.0)
  • 利用docker輕鬆搭建Redis-Cluster集群環境
    在這裡使用docker容器來搭建一套6節點(3主,3從)Redis-Cluster集群環境。環境準備作業系統版本:CentOS Linux release 7.6.1810 (Core)docker版本:19.03.13伺服器IP位址:192.168.112.136redis版本:5.0.9redis實例埠:8001--8006
  • Docker 搭建 Redis Cluster 集群環境
    使用 Docker 搭建 Redis Cluster,最重要的環節就是容器通信的問題,這一塊我們在之前的文章中已經給大家解決了《 》,本篇文章主要練習使用多個容器完成 Redis Cluster 集群環境的搭建,順便為學習 Docker Compose 鋪鋪路。
  • Docker 搭建 Redis Cluster 集群
    使用 Docker 搭建 Redis Cluster,最重要的環節就是容器通信的問題,這一塊我們在之前的文章中已經給大家解決了《 》,本篇文章主要練習使用多個容器完成 Redis Cluster 集群環境的搭建,順便為學習 Docker Compose 鋪鋪路。
  • Nodejs on Docker
    在本指南的第一部分,我們將用Node.js創建一個簡單的Web應用程式, 然後我們將為該應用程式建立一個Docker映像, 最後我們將運行這個鏡像作為一個容器。author": "First Last <first.last@example.com>", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": {
  • Canal+Kafka實現MySQL與Redis數據同步
    架構圖canal是一個偽裝成slave訂閱mysql的binlog,實現數據同步的中間件。上一篇文章《canal入門》我已經介紹了最簡單的使用方法,也就是tcp模式。下面演示Kafka的搭建,MySQL搭建大家應該都會,ZooKeeper、Redis這些網上也有很多資料參考。
  • Docker新手入門之六:Docker在生產環境中的使用實踐
    在之前的文章中,我們簡要介紹的Docker的一些簡單實踐。接下來,我們將在本文中進行類似內容的講解,不過相比而言,使用Docker部署的服務將會更加的複雜。搭建Jekyll框架的網站本文中我們將要構建的第一個應用是一個使用Jekyll框架的自定義網站。
  • 基於docker環境搭建redis-cluster集群(單機)
    集群配置名cluster-node-timeout 15000 超時時間cluster-announce-ip 172.18.0.>創建腳本creatDocker.shfor port in `seq 7001 7006`; do docker run -p ${port}:${port} -p 1${port}:1${port} --name redis-${port} \ -v /home/gmh/redis-cluster/${port}/conf/redis.conf:/
  • nodejs windows環境下搭建
    目前,Node.js是在前端開發中十分受歡迎,它是一套用來編寫高性能網絡伺服器的JavaScript工具包,官網中介紹:Node.js 是一個基於Chrome JavaScript 運行時建立的一個平臺, 用來方便地搭建快速的 易於擴展的網絡應用; Node.js 藉助事件驅動, 非阻塞I
  • 生產環境使用Apache Kafka和Redis的流架構
    使用Kafka開始進行有趣的項目的一種簡單方法是使用docker-compose,其設置類似於以下內容:version中的競爭條件(Zookeeper啟動速度比Kafka慢)導致Kafka服務無法啟動,必須使用docker-compose scale kafka=1重新啟動。
  • MySQL在Docker環境下運行基礎
    能快速的交付和部署高效的資源利用輕鬆的遷移擴展簡單的更新管理1.2.安裝docker 環境準備: Kernel 3.10+ (1)檢查系統的內核版本,返回的值大於3.10即可[root@ss30 ~] yum update安裝docker:
  • Windows環境下的Node.js環境搭建
    Node.js環境搭建1. 下載軟體訪問官方網站 nodejs.org/zh-cn選擇長期支持版下載。或者直接使用這裡提供的已經下載完成的版本。2.搭配git更好的使用Node.jsNode.js的常用命令node、npm都是在命令行下執行的,由於Windows自帶的命令提示符用起來不是很方便,推薦安裝git for windows來作為命令行使用。下載地址:git-scm.com/downloads選擇對應作業系統的版本。推薦選擇便攜版。
  • 你還在手動搭建環境嗎?
    老黑:小白呀,公司要做的這個新項目看見了嘛,給你一天的時間搭建基礎環境沒有問題吧?小白:沒問題、沒問題(麻痺的,又是oracle,kafka,redis……,還全部是集群,一天搞定個毛啊,玩我啊?)一天後……老黑:小白呀,環境搭建好了嗎?
  • Docker 搭建 nginx + mysql + php 開發環境全方面教學!
    下載頁面我的運行環境:運行環境下載安裝包並安裝後,菜單欄出現 Docker 的標識後,便可以開始搭建我們的環境了。5.6$ docker pull php:5.4-fpm$ docker pull nginx等待全部拉取完成後,使用 docker images 查看所有鏡像安裝 Mysql$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 33267:3306 -v ~/web/mysql/
  • Node.js 學習資料和教程(值得收藏)
    node+express搭建多人博客教程系列Node.js靜態文件伺服器實戰人人和微博登錄模塊的實現《京JS》會議 & V8上的JS優化滬 JS 國內講師的 PPT 收集給Node.js新手的7條小建議  模塊導航web伺服器框架最流行的web框架ExpressHomePage加裝渦輪,提速expressjs給 connect 的 static 模塊加上
  • 如何使用Docker容器化Node.js應用程式
    在本文中,我將告訴你如何使用Docker容器化你的node.js應用程式。在繼續之前,請確保你的計算機中已安裝Docker。在本教程中,我使用的是具有較少依賴關係的基本Node.js應用程式,但在你的項目中,你可能有一個高級的node.js應用,其依賴性比我的更多。
  • 在Node.js中使用MySQL&MySQL JavaScript客戶端
    以下5個簡單步驟告訴你如何在 Node 中使用 MySQL: 創建一個新項目:mkdir mysql-test && cd mysql-test 創建一個 package.json 文件:npm init -y 安裝mysql模塊: npm install mysql –save 創建一個app.js文件並將下面的代碼段複製進去
  • docker 快速搭建JAVA開發環境
    一、redis環境的創建 並創建了密碼:redis123456aB ,此時我們將容器的6379埠映射到本地的6379docker pull redis 34;redis123456aB&34;redis123456aB&按裝zookeeper鏡象docker run -d -p 2181:2181 -v /Users/zl/data/:/data/
  • 03.docker+redis搭建
    本文介紹docker搭建單機版的redis編寫Dockerfile文件FROM redisCMD ["redis-server", "/etc/redis/redis.conf"]編寫docker-compose.ymlversion
  • DockerCompose搭建RedisCluster集群
      切換至指定目錄 cd /usr/local/docker-redis/redis-cluster/  cat /usr/local/docker-redis/redis-cluster/637{1..3}/conf/redis.conf port 6371 requirepass 1234 masterauth