SpringBoot開發案例從0到1構建分散式秒殺系統

来源:https://www.cnblogs.com/smallSevens/archive/2018/05/16/9043277.html
-Advertisement-
Play Games

前言 ​最近,被推送了不少秒殺架構的文章,忙裡偷閑自己也總結了一下互聯網平臺秒殺架構設計,當然也借鑒了不少同學的思路。俗話說,脫離案例講架構都是耍流氓,最終使用SpringBoot模擬實現了部分秒殺場景,同時跟大家分享交流一下。 秒殺場景 秒殺場景無非就是多個用戶在同時搶購一件或者多件商品,專用辭彙 ...


前言

​最近,被推送了不少秒殺架構的文章,忙裡偷閑自己也總結了一下互聯網平臺秒殺架構設計,當然也借鑒了不少同學的思路。俗話說,脫離案例講架構都是耍流氓,最終使用SpringBoot模擬實現了部分秒殺場景,同時跟大家分享交流一下。

秒殺場景

秒殺場景無非就是多個用戶在同時搶購一件或者多件商品,專用辭彙就是所謂的高併發。現實中經常被大家喜聞樂見的場景,一群大媽搶購打折雞蛋的畫面一定不會陌生,如此場面讓服務員大姐很無奈,趕上不要錢了。

業務特點

  • 瞬間高併發、電腦旁邊的小哥哥、小姐姐們如超市哄搶的大媽一般,瘋狂的點著滑鼠
  • 庫存少、便宜、稀缺限量,值得大家去搶購,如蘋果腎,小米粉,錘子粉(理解萬歲)

用戶規模

用戶規模可大可小,幾百或者上千人的活動單體架構足以可以應付,簡單的加鎖、進程內隊列就可以輕鬆搞定。一旦上升到百萬、千萬級別的規模就要考慮分散式集群來應對瞬時高併發。

秒殺架構

架構層級

  • 一般商家在做活動的時候,經常會遇到各種不懷好意的DDOS攻擊(利用無辜的吃瓜群眾奪取資源),導致真正的我們無法獲得服務!所以說高防IP還是很有必要的。

  • 搞活動就意味著人多,接入SLB,對多台雲伺服器進行流量分發,可以通過流量分發擴展應用系統對外的服務能力,通過消除單點故障提升應用系統的可用性。

  • 基於SLB價格以及靈活性考慮後面我們接入Nginx做限流分發,來保障後端服務的正常運行。

  • 後端秒殺業務邏輯,基於Redis 或者 Zookeeper 分散式鎖,Kafka 或者 Redis 做消息隊列,DRDS資料庫中間件實現數據的讀寫分離。

優化思路

  • 分流、分流、分流,重要的事情說三遍,再牛逼的機器也抵擋不住高級別的併發。

  • 限流、限流、限流,畢竟秒殺商品有限,防刷的前提下沒有絕對的公平,根據每個服務的負載能力,設定流量極限。

  • 緩存、緩存、緩存、儘量不要讓大量請求穿透到DB層,活動開始前商品信息可以推送至分散式緩存。

  • 非同步、非同步、非同步,分析並識別出可以非同步處理的邏輯,比如日誌,縮短系統響應時間。

  • 主備、主備、主備,如果有條件做好主備容災方案也是非常有必要的(參考某年錘子的活動被攻擊)。

  • 最後,為了支撐更高的併發,追求更好的性能,可以對伺服器的部署模型進行優化,部分請求走正常的秒殺流程,部分請求直接返回秒殺失敗,缺點是開發部署時需要維護兩套邏輯。

分層優化

  • 前端優化:活動開始前生成靜態商品頁面推送緩存和CDN,靜態文件(JS/CSS)請求推送至文件伺服器和CDN。
  • 網路優化:如果是全國用戶,最好是BGP多線機房,減少網路延遲。
  • 應用服務優化:Nginx最佳配置、Tomcat連接池優化、資料庫配置優化、資料庫連接池優化。

全鏈路壓測

  • 分析需壓測業務場景涉及系統
  • 協調各個壓測系統資源並搭建壓測環境
  • 壓測數據隔離以及監控(響應時間、吞吐量、錯誤率等數據以圖表形式實時顯示)
  • 壓測結果統計(平均響應時間、平均吞吐量等數據以圖表形式在測試結束後顯示)
  • 優化單個系統性能、關聯流程以及整個業務流程

整個壓測優化過程就是一個不斷優化不斷改進的過程,事先通過測試不斷發現問題,優化系統,避免問題,指定應急方案,才能讓系統的穩定性和性能都得到質的提升。

代碼案例

可能秒殺架構原理大家都懂,網上也有不少實現方式,但大多都是文字的描述,告訴你如何如何,什麼加鎖、緩存、隊列之類。但很少全面有的案例告訴你如何去做,既然是從0到1,希望以下代碼案例可以幫助到你。當然最終落實到生產,還有很長的路要走,要根據自己的業務進行編碼,實施並部署。

你將會在代碼案例中學到以下知識(不定期補充):

  • 如何大家SpringBoot微服務
  • ThreadPoolExecutor線程池的使用
  • ReentrantLock和Synchronized的使用場景
  • 資料庫鎖機制(悲觀鎖、樂觀鎖)
  • 分散式鎖(RedissLock、Zookeeper)
  • 進程內消息隊列(LinkedBlockingQueue、ArrayBlockingQueue、ConcurrentLinkedQueue)
  • 分散式消息隊列(Redis、Kafka)

代碼結構:

├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─itstyle
│  │  │          └─seckill
│  │  │              │  Application.java
│  │  │              │  
│  │  │              ├─common
│  │  │              │  ├─api
│  │  │              │  │      SwaggerConfig.java 
│  │  │              │  │      
│  │  │              │  ├─config
│  │  │              │  │      IndexController.java  
│  │  │              │  │      
│  │  │              │  ├─dynamicquery   
│  │  │              │  │      DynamicQuery.java
│  │  │              │  │      DynamicQueryImpl.java
│  │  │              │  │      NativeQueryResultEntity.java
│  │  │              │  │      
│  │  │              │  ├─entity   
│  │  │              │  │      Result.java
│  │  │              │  │      Seckill.java
│  │  │              │  │      SuccessKilled.java
│  │  │              │  │      
│  │  │              │  ├─enums
│  │  │              │  │      SeckillStatEnum.java
│  │  │              │  │      
│  │  │              │  ├─interceptor
│  │  │              │  │      MyAdapter.java
│  │  │              │  │      
│  │  │              │  └─redis
│  │  │              │          RedisConfig.java
│  │  │              │          RedisUtil.java
│  │  │              │          
│  │  │              ├─distributedlock
│  │  │              │  ├─redis
│  │  │              │  │      RedissLockDemo.java
│  │  │              │  │      RedissLockUtil.java
│  │  │              │  │      RedissonAutoConfiguration.java
│  │  │              │  │      RedissonProperties.java
│  │  │              │  │      
│  │  │              │  └─zookeeper
│  │  │              │          ZkLockUtil.java
│  │  │              │          
│  │  │              ├─queue
│  │  │              │  ├─jvm
│  │  │              │  │      SeckillQueue.java
│  │  │              │  │      TaskRunner.java
│  │  │              │  │      
│  │  │              │  ├─kafka
│  │  │              │  │      KafkaConsumer.java
│  │  │              │  │      KafkaSender.java
│  │  │              │  │      
│  │  │              │  └─redis
│  │  │              │          RedisConsumer.java
│  │  │              │          RedisSender.java
│  │  │              │          RedisSubListenerConfig.java
│  │  │              │          
│  │  │              ├─repository
│  │  │              │      SeckillRepository.java
│  │  │              │      
│  │  │              ├─service
│  │  │              │  │  ISeckillDistributedService.java
│  │  │              │  │  ISeckillService.java
│  │  │              │  │  
│  │  │              │  └─impl
│  │  │              │          SeckillDistributedServiceImpl.java
│  │  │              │          SeckillServiceImpl.java
│  │  │              │          
│  │  │              └─web
│  │  │                      SeckillController.java
│  │  │                      SeckillDistributedController.java
│  │  │                      
│  │  ├─resources
│  │  │  │  application.properties
│  │  │  │  logback-spring.xml
│  │  │  │  
│  │  │  ├─sql
│  │  │  │      seckill.sql
│  │  │  │      
│  │  │  ├─static
│  │  │  └─templates
│  │  └─webapp

思考改進

  • 如何防止單個用戶重覆秒殺下單?
  • 如何防止惡意調用秒殺介面?
  • 如果用戶秒殺成功,一直不支付該怎麼辦?
  • 消息隊列處理完成後,如果非同步通知給用戶秒殺成功?
  • 如何保障 Redis、Zookeeper 、Kafka 服務的正常運行(高可用)?
  • 高併發下秒殺業務如何做到不影響其他業務(隔離性)?

碼雲下載:從0到1構建分散式秒殺系統,脫離案例講架構都是耍流氓

可供參考

企業雲解析DNS

Nginx學習之負載均衡

Nginx學習之緩存配置

Nginx學習之HTTP/2.0配置

Nginx學習之如何防止流量攻擊

SpringBoot開發案例之整合Kafka實現消息隊列


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JavaScript介紹 JavaScript是運行在瀏覽器端的腳步語言,JavaScript主要解決的是前端與用戶交互的問題,包括使用交互與數據交互。 JavaScript是瀏覽器解釋執行的,前端腳本語言還有JScript(微軟,IE獨有),ActionScript( Adobe公司,需要插件)等 ...
  • 先上解決辦法: $(#formid #inputid).val("") 將這個代碼放在提交按鈕最後就可以了。 我在做一個修改信息的功能時,發現上一次提交的內容在下一次打開的記錄里又顯示出來,因為有一個input框每一個記錄都是不一樣的,為了避免操作人員手工清空內容,我打打算在新記錄修改時候清空這個i ...
  • CSS3 transform變換 1、translate(x,y) 設置盒子位移2、scale(x,y) 設置盒子縮放3、rotate(deg) 設置盒子旋轉4、skew(x-angle,y-angle) 設置盒子斜切5、perspective 設置透視距離6、transform-style fla ...
  • CSS權重 CSS權重指的是樣式的優先順序,有兩條或多條樣式作用於一個元素,權重高的那條樣式對元素起作用,權重相同的,後寫的樣式會覆蓋前面寫的樣式。 權重的等級 可以把樣式的應用方式分為幾個等級,按照等級來計算權重 1、!important,加在樣式屬性值後,權重值為 100002、內聯樣式,如:st ...
  • 詳情請 咨詢 QQ 759104513 精品新增,持續中.... 192、PHP進階:面向對象及TP5框架初識-慕課網職業路徑 191、0961、手把手帶你入坑H5與小程式直播開發 190、SpringBoot2.0不容錯過的新特性 WebFlux響應式編程 189、Vue2.5開發去哪兒網App ...
  • 定位 關於定位 我們可以使用css的position屬性來設置元素的定位類型,postion的設置項如下: relative 生成相對定位元素,元素所占據的文檔流的位置不變,元素本身相對文檔流的位置進行偏移 absolute 生成絕對定位元素,元素脫離文檔流,不占據文檔流的位置,可以理解為漂浮在文檔 ...
  • css元素溢出 當子元素的尺寸超過父元素的尺寸時,需要設置父元素顯示溢出的子元素的方式,設置的方法是通過overflow屬性來設置。 overflow的設置項: 1、visible 預設值。內容不會被修剪,會呈現在元素框之外。2、hidden 內容會被修剪,並且其餘內容是不可見的,此屬性還有清除浮動 ...
  • json數據作為和後臺交互的良好交互方式,這裡介紹下前端怎麼封裝成json數據給到後臺。 示例代碼: (1)封裝成json數據 最終結果為:{"id":0,"name":"張三","job":"學生"} (2)封裝成json數組 最終結果為:[{"id":0,"name":"張三","job":"學 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...