1. 程式人生 > >Java秒殺系統優化的工程要點

Java秒殺系統優化的工程要點

這篇部落格是筆者學習慕課網若魚老師的《Java秒殺系統方案優化 高效能高併發實戰》課程的學習筆記。若魚老師授課循循善誘,講解由淺入深,歡迎大家支援。

本文記錄課程中的注意點,方便以後code review。此外,本文將注意點相關的優質講解連結在了一起,方便初學者系統學習。

> 本文並非單純介紹秒殺系統特有的技術點,不適合高手。進階學習的話,極客時間有個不錯的小專欄——如何設計一個秒殺系統,阿里高階技術專家講解秒殺系統的設計要點,那個課程挺乾貨的。

設計秒殺系統的技術要點

1. 登入的密碼傳輸:

使用者的資料庫表設計,需要增加一欄位儲存密碼的Salt值

兩次MD5操作(敏感資料一定要使用https協議傳輸

):

  • 客戶端:將明文password和客戶端硬編碼的Salt值進行拼接,然後進行MD5操作。

> 不用鹽的話,MD5字串有可能會被彩虹表或者社工庫破解

  • 服務端:將客戶端傳過來的MD5字串和資料庫使用者對應的Salt欄位進行拼接。然後進行MD5操作。

> 這次加鹽MD5,可以有效防止內部員工洩露或者資料庫被拖庫後,明文密碼洩露

2. 自定義JSR303的校驗器

可以參照javax.validation.constraints.NotNull註解,自定義自己的校驗器,將校驗程式碼與業務程式碼分離。不過由於校驗失敗會輸出BindException異常,所以最好配合全域性捕獲異常進行友好的輸出。

> 自定義校驗器很簡單,只需要定義一個註解和對應的校驗類

3. 自定義全域性異常捕獲

使用@ControllerAdvice註解,定義全域性的異常捕獲,並從異常中獲取異常資訊解析出來,傳送給前端
可以自定義一個GlobalException異常,利用全域性異常捕獲,將所有伺服器處理異常集中處理。(Service層處理異常後不設定狀態碼,而是直接拋GlobalException全域性異常)

> 不返回狀態碼的好處是Controller層不需要再繁瑣的判斷Service層的返回值,程式碼更簡潔

4. 資料庫表設計

  • 通過將訂單建立唯一索引來保證使用者只能建立一個秒殺訂單
  • 商品金額最好以分為單位,比較安全
  • 商品ID最好不要使用自增,會暴露商品總數等資訊。可以使用UUID,但範圍查詢時會有效能損耗。所以一般採用SnowFlake演算法生成ID

> 另外,自增ID的缺點也就是無法在多個表中,或者多個數據庫中保持ID主鍵唯一不重複,所以若是使用分散式資料庫以及資料合併的情況下時不能使用自增ID的。

5. 程式碼規範

  • 更新欄位越多,產生的資料庫Binlog就越多。所以只更新資料庫部分欄位的時候,最好新建一個物件,只賦值要更新的欄位,然後呼叫mybatis的@Update,這樣不做全量更新可以提高效能
  • 前端回包使用Result包裝類封裝,對報錯資訊使用CodeMsg包裝類封裝,保持程式碼風格統一
  • Service只注入跟自己同名的dao,如果需要別的dao,請注入對應的Service

> Service的api相比dao會多一些防禦程式碼(例如,直接修改了別的模組dao資料,但快取未清理),更加安全

6. 事務

秒殺有兩個事務:

  1. 減庫存->建立秒殺訂單
  2. 建立秒殺訂單
    秒殺中涉及到上述兩個事務,為了保障資料安全,可以使用宣告式事務(Spring的@Transactional)

> PROPAGATION_REQUIRED是Spring預設的傳播機制,如果外層有事務,則當前事務加入到外層事務,一塊提交,一塊回滾。本工程的場景使用預設事務傳播機制即可

有關Spring事務傳播機制可以檢視這篇部落格

7. 壓測

  • 在生產環境中,秒殺系統要獨立執行與其他業務系統,實現資源隔離,避免業務系統相互影響穩定性
  • 請求入口可以使用nginx,LVS,F5等不同的負載均衡器
  • Jmeter 隨機生成使用者資料,然後使用Jmeter模擬使用者壓測。壓測執行環境最好與被測伺服器環境隔離。

> 介面測試可以還使用Postman和ApacheBench

8. 頁面優化技術

  • 頁面/URL快取。用於資料變化不頻繁的頁面或者熱點網頁。如果資料較多需要分頁的資料,類似商品詳情資料,一般可以考慮只快取前兩頁(根據訪問量作取捨)

> 快取方法:將渲染好的html檔案存放到Redis。在訪問Url時,首先檢測Redis是否有html快取。有快取的話則直接返回快取;沒有快取的話則渲染後存入Redis,並返回給前端。頁面快取過期時間具體根據業務場景判斷。

  • 頁面區域性快取。熱點資料快取,當Ajax請求資訊更新,涉及的可能是需要儲存在資料庫的操作,例如表格資訊等時,可以採用Redis快取,方法同頁面快取一樣,定義好可以區分業務的Key即可

  • 靜態資源優化

    • JS/CSS壓縮,減少流量(可通過升級HTTP2來解決)
    • 多個JS/CSS組合,減少連線數(例如:tengine)
    • CDN就近訪問

> 如果需要採用JS/CSS壓縮或者減少連線數等方法,可以使用HTTP2來提升效能

  • 物件快取。例如使用Redis儲存Session物件。物件快取涉及到一個雙寫一致性問題,有關雙寫一致性問可以檢視這篇部落格

9. 秒殺的邏輯優化

順序:

  1. 系統初始化,把商品庫存數量載入到Redis
  2. 收到請求,Redis原子操作預減庫存,庫存不足,直接返回,否則進入3
  3. 請求入隊,立即返回前端“排隊中”
  4. 請求出隊,生成訂單,減少庫存(服務端)
  5. 客戶端輪詢,是否秒殺成功(客戶端)和4同步,得到結果重新整理結果顯示

優化:

  1. 在第二步預減庫存時,可以在記憶體里加一個map,ID為商品ID,value為是否有庫存,這樣當庫存沒有之後,直接通過記憶體中的值判斷是否還有庫存,減少對Redis的訪問。
  2. 購買請求加入訊息佇列,非同步下單(前端顯示排隊中),增強使用者體驗
  3. 前端要儘量減少重複請求

10. 安全優化

10.1 秒殺介面地址隱藏

  1. 每次點選秒殺按鈕,先從伺服器獲取動態拼接而成的秒殺地址。
  2. Redis以快取使用者ID和商品ID為Key,秒殺地址為Value快取秒殺地址
  3. 使用者請求秒殺商品的時候,要帶上秒殺地址進行校驗

10.2 數學公式驗證碼

  1. 防止惡意指令碼搶購
  2. 使請求時間分散

10.3 介面限流防刷

使用計數法,在攔截器做限制請求頻率。利用Redis快取的有效期(以使用者ID拼接Url作為key,以訪問次數為value),指定快取有效期為1秒,訪問介面每次將value+1,到達閾值跳轉全域性異常。

> 優化:使用攔截器+自定義註解,減少對業務程式碼的侵入。有關攔截器可以檢視這篇部落格 > 另外對於介面限流也可以考慮使用令牌桶,控制對mysql的訪問。

哎呀,如果我的名片丟了。微信搜尋“全菜工程師小輝”,依   
 
 </div> 
 <div class=

相關推薦

Java系統優化工程要點

這篇部落格是筆者學習慕課網若魚老師的《Java秒殺系統方案優化 高效能高併發實戰》課程的學習筆記。若魚老師授課循循善誘,講解由淺入

PK2244-Java系統方案優化 高性能高並發實戰

高並發 並發 提升自己 filter container 秒殺 containe -c 提升 PK2244-Java秒殺系統方案優化 高性能高並發實戰 新年伊始,學習要趁早,點滴記錄,學習就是進步! 隨筆背景:在很多時候,很多入門不久的朋友都會問我:我是從其他語言轉到

Java系統方案優化---高性能高並發實戰

http 大並發 並發實戰 -- share 系統 消息 java com Java秒殺系統方案優化---高性能高並發實戰網盤地址:https://pan.baidu.com/s/1htNv2zq 密碼: ssyt備用地址(騰訊微雲):https://share.weiyu

Java系統方案優化視頻教程 Java高性能高並發實戰教程

Java 第1章 課程介紹及項目框架搭建技術選型思路分析,基於Maven的Spring-Boot工程框架的搭建,集成Thymeleaf,集成Mybatis,安裝Redis,集成Redis等等。第2章 實現用戶登錄以及分布式session功能實現用戶登錄功能,實現密碼兩次MD5入庫以及分布式Session。一則

Java系統方案優化 高性能高並發實戰

www. 數據庫 存儲 redis服務器 live 框架搭建 入門 服務 dea 第1章 課程介紹(講師參與學習討論)本章將為大家介紹課程目標,課程技術棧,課程收獲,以及課程安排,讓大家更好的了解這門課程具體能幫助大家學習到哪些內容,能有哪些提高,希望本課程能很好的幫助大家

Java系統方案優化 2 --第2章 實現使用者登入以及分散式session功能

第2章 實現使用者登入以及分散式session功能 1. 明文密碼兩次md5入庫 分別使用簽名如1a2b3c4d,分別用簽名和密碼使用MD5加密兩次後(一次是最原始密碼加密,一次是加密後再使用MD5和簽名加密)才存入資料庫,每個使用者對應都有一個欄位,例如本案例中的sa

Java系統方案優化 高效能高併發實戰

第9章 Tomcat服務端優化(Tomcat/Ngnix/LVS/Keepalived) 本章將帶大家進行線上部署相關技術的學習,包括Tomcat配置優化以及使用APR聯結器提高併發效能,以及用Ngnix如何配置併發連線數、長連線、壓縮、快取、狀態監控以及請求統計,如何配置LVS四層負載均衡,最後用四

2018年最全Java系統方案優化 高效能高併發實戰教程

所謂虛擬機器,就是一臺虛擬的計算機。它是一款軟體,用來執行一系列虛擬計算機指令。虛擬機器可以分為系統虛擬機器和程式虛擬機器。Java虛擬機器專門為執行單個計算機程式而設計,在Java虛擬機器中執行的指令我們稱為Java位元組碼指令。一個Java程式(Java位元組碼的集合),通過Java虛擬機器運

系統優化思路

按鈕 clas 繼續 -i 火車票 時間 有意 用戶 頁面 一、秒殺業務為什麽這麽難做 秒殺系統,庫存只有一份,所有人會在集中的時間讀和寫這些數據。 例如: 小米手機每周二的秒殺,可能手機只有1萬部,但瞬間進入的流量可能是幾百幾千萬。 12306搶票,票是有限的,但是搶票

Java-系統的設計

Java-秒殺系統的設計 Java-秒殺系統的設計 1 緣起 2 思路 & 實現 2.1 資料庫 2.2 前端 2.2.1 前後端分離 2.2.2 儘量的快取

實戰剖析 Java 系統的實現

本場 Chat 將為您介紹如何從0到1搭建一個分散式架構的秒殺系統,如何利用 Redis 的特性發揮它在秒殺系統中的大作用,如何利用訊息佇列實現請求的非同步處理;帶您思考實現秒殺系統過程中需要注意的點,以及需要掌握的技巧。 本場 Chat 主要內容: 如何限流; 如何削峰; 如何完

Java系統(十)實現功能-商品列表頁

商品表 CREATE TABLE `goods` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '商品ID', `goods_name` varchar(16) CHARACTER SET utf8mb4 DEFA

JAVA系統(五)實現登入功能--明文密碼兩次MD5處理

1.資料庫設計2.明文密碼兩次MD5處理3.JSR303引數檢驗+全域性異常處理4.分散式Session1.新建查詢2.兩次MD5:防止資料洩露       1.使用者端:pass = MD5(明文+固

java系統實現

秒殺系統高併發優化:系統流程 秒殺未開始【詳情頁】(各種商品資訊)包含-系統時間-倒計時;進入秒殺環節【地址暴露介面】(拿到秒殺地址)-【執行秒殺操作】-【放回結果】具體優化操作:詳情頁:使用者大量重新整理,可以將detail 頁靜態化,靜態資源css,js等部署到CDN(內

java系統四,整合redis

新增jedis和fastjson依賴配置redispackage cn.tedu.miaosha.redis; public abstract class BasePrefix implements KeyPrefix { private int expireSeco

Java系統專案環境搭建一(Spring Boot)

一,新建maven  project二、導包            在pom.xml中新增,如下圖:相關程式碼請檢視https://projects.spring.io/spring-boot/官網以下是環境配置的所有程式碼package cn.tedu.miaosha.co

Java系統實戰系列~整體業務流程介紹與資料庫設計

摘要: 本篇博文是“Java秒殺系統實戰系列文章”的第三篇,本篇博文將主要介紹秒殺系統的整體業務流程,並根據相應的業務流程進行資料庫設計,最終採用Mybatis逆向工程生成相應的實體類Entity、操作Sql的介面Mapper以及寫動態Sql的配置檔案Mapper.xml。內容:

Java系統實戰系列~商品程式碼實戰

摘要: 本篇博文是“Java秒殺系統實戰系列文章”的第六篇,本篇博文我們將進入整個秒殺系統核心功能模組的程式碼開發,即“商品秒殺”功能模組的程式碼實戰。內容: “商品秒殺”功能模組是建立在“商品詳情”功能模組的

SpringBoot實現Java高併發系統之併發優化

秒殺系統架構的設計和優化分析,以我一個小菜雞,目前是說不出來的o(╥﹏╥)o。 因此呢,我這裡僅從本專案已經實現的優化來介紹一下: 本專案中做到了以下優化: 秒殺介面採用md5加密方式防刷。 訂單表使用聯合主鍵方式,限制一個使用者只能購買該商品一次。 配合Spring事務

Java開發面試:高併發系統如何設計與優化

      如今處在一個大資料時代,應屆生找工作面試高階Java開發工程師時,經常會被問一些和大資料相關的問題,比如大資料處理問題、高併發處理問題、資料優化問題等,筆者曾經遇到兩個比較經典的問題,高併發秒殺系統的設計優化問題和大資料檔案排序問題。在這裡總結了高併發秒殺系統