SSM整合開發(四)—高併發優化思路
首先感謝慕課網的老師,講的真的很棒,學習很多書本上學不到的實用知識。
學習課程的地址: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上有這一段的源碼。
系統的部署架構
爲日後學習做鋪墊吧,對集羣化部署有一個感性的認識。
課程總結
數據庫設計和實現,能夠手動編寫建庫建表的SQL語句。
MyBatis理解和使用技巧,編寫dao接口,供service層調用。
MyBatis整合Spring,如何配置嵌入Spring容器。
業務層的接口設計和封裝、SpringIOC配置、Spring聲明式事務使用和理解、SpringMVC的使用。
Restful接口運用和URL的設計規範,通過URL可以知道請求的行爲等。
前端Bootstrap框架進行前端模板編寫比較方便。
這節課主要講解了關於高併發下秒殺的簡單案例(當然現實比這個複雜的多),個人把之前學習的SSM框架進行整合鞏固了一遍。
最後感嘆一句,老師真是太牛了,全棧大神!