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. 事務
秒殺有兩個事務:
- 減庫存->建立秒殺訂單
- 建立秒殺訂單
秒殺中涉及到上述兩個事務,為了保障資料安全,可以使用宣告式事務(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. 秒殺的邏輯優化
順序:
- 系統初始化,把商品庫存數量載入到Redis
- 收到請求,Redis原子操作預減庫存,庫存不足,直接返回,否則進入3
- 請求入隊,立即返回前端“排隊中”
- 請求出隊,生成訂單,減少庫存(服務端)
- 客戶端輪詢,是否秒殺成功(客戶端)和4同步,得到結果重新整理結果顯示
優化:
- 在第二步預減庫存時,可以在記憶體里加一個map,ID為商品ID,value為是否有庫存,這樣當庫存沒有之後,直接通過記憶體中的值判斷是否還有庫存,減少對Redis的訪問。
- 購買請求加入訊息佇列,非同步下單(前端顯示排隊中),增強使用者體驗
- 前端要儘量減少重複請求
10. 安全優化
10.1 秒殺介面地址隱藏
- 每次點選秒殺按鈕,先從伺服器獲取動態拼接而成的秒殺地址。
- Redis以快取使用者ID和商品ID為Key,秒殺地址為Value快取秒殺地址
- 使用者請求秒殺商品的時候,要帶上秒殺地址進行校驗
10.2 數學公式驗證碼
- 防止惡意指令碼搶購
- 使請求時間分散
10.3 介面限流防刷
使用計數法,在攔截器做限制請求頻率。利用Redis快取的有效期(以使用者ID拼接Url作為key,以訪問次數為value),指定快取有效期為1秒,訪問介面每次將value+1,到達閾值跳轉全域性異常。
> 優化:使用攔截器+自定義註解,減少對業務程式碼的侵入。有關攔截器可以檢視這篇部落格 > 另外對於介面限流也可以考慮使用令牌桶,控制對mysql的訪問。
相關推薦
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開發工程師時,經常會被問一些和大資料相關的問題,比如大資料處理問題、高併發處理問題、資料優化問題等,筆者曾經遇到兩個比較經典的問題,高併發秒殺系統的設計優化問題和大資料檔案排序問題。在這裡總結了高併發秒殺系統