SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis兩個開源框架整合而成(SpringMVC是Spring中的部分內容)。常作為數據源較簡單的web項目的框架。
學習課程的地址:https://www.imooc.com/learn/632
老師的GitHub地址:https://github.com/geekyijun/seckill
高並發發生在哪里?
分析整個系統流程,用戶進行秒殺時最感興趣的進入詳情頁進行秒殺。圖中紅色表示可能會出現高並發的點,綠色表示不會出現高並發。
為什么要單獨獲取系統時間?
用戶進行大量刷新時,詳情頁會部署到CDN節點上,進行靜態化處理同時包括靜態資源(css/js等)。這樣就難以獲得系統的統一秒殺時間。
CDN(內容分發網絡)加速用戶獲取數據的系統,部署在離用戶最近的網絡節點上,命中CDN不需要訪問后端服務器,互聯網公司一般自己搭建或租用CDN服務器。涉及到CDN知識,進公司后涉及到自然就會了。。。
獲取系統時間不用進行優化,因為訪問內存的速度相當快。
秒殺地址接口分析
無法使用CDN,使用CDN一般是不便的資源,而這里返回秒殺地址是變化的。適合使用服務端緩存如redis等。
流程則是先訪問redis,如果redis中沒有再去數據庫中尋找,即redis是數據庫的一個映射(后面得學下redis。。。),這里涉及到一致性問題,使用超時穿透/主動更新的方法。
秒殺操作的優化分析
無法使用CDN,庫存量緩存困難,一行數據競爭(熱點商品)。
為什么說MySQL低效?測試里MySQL的一條update一秒鍾可以進行4W多次,不算低。主要是因為行級鎖,每個用戶都進行update,進行事務操作,等待鎖的過程變成了串行化的操作。行級鎖是在commit之后釋放,優化的方向則是如何減少行級鎖的持有時間。
延遲的分析:物理上的距離、JVM的GC問題。將客戶端運行在MySQL端。方案一:定制SQL方案,需要修改MySQL源碼。方案二:使用存儲過程,整個事務在MySQL端完成。(這一段需要查更多資料)。
總結
前端控制:暴露接口、按鈕防重復
動靜態數據分離:CDN緩存、后端緩存
事務競爭優化:減少事務鎖時間
redis后端緩存優化
redis目前官網不支持Windows,不過微軟做了一個win64的版本。
具體編碼這里不貼出了(見GitHub:https://github.com/geekyijun/seckill),理解原理就好。需要用到高並發時候可以詳細學習一下。大致的思路就是訪問redis緩存有沒有數據,有就直接讀,沒有再讀數據庫並更新redis緩存。一致性通過設置一段時間后redis失效(超時穿透)和更新數據庫時同時更新redis緩存(主動更新)。
秒殺操作—並發優化
將update減庫存和insert購買明細進行順序調整,將減少行級鎖的時間,不必擔心insert的問題,因為減庫存成功后才commit否則rollback。但是這么做減少一半的網絡延時和GC時間。關注點在哪些事務的操作中對數據庫的行級鎖有競爭關系,將行級鎖的更新壓縮到最小。
深度優化:將邏輯判斷直接以函數的形式寫入MySQL。
-- 存儲過程
-- 1:存儲過程優化:事務行級鎖持有的時間
-- 2:不要過度依賴存儲過程(一般存在於銀行,互聯網公司很少使用,秒殺單有用的地方)
-- 3:簡單的邏輯可以應用存儲過程
-- 4:QPS:一個秒殺單6000/qps
GitHub上有這一段的源碼。
系統的部署架構
講解了關於高並發下秒殺的簡單案例(當然現實比這個復雜的多),感謝大牛。