之前看了《大型網(wǎng)站技術(shù)架構(gòu)·核心原理與案例分析》一書(shū)匆浙,其中介紹了一些關(guān)于網(wǎng)購(gòu)秒殺系統(tǒng)架構(gòu)設(shè)計(jì)相關(guān)的知識(shí),碰巧在imooc上也看到了有關(guān)的課程嫁盲。在參考了各方資料之后,個(gè)人感覺(jué)對(duì)如何設(shè)計(jì)一個(gè)秒殺系統(tǒng)有了基本的了解艺玲,于是打算自己也試著實(shí)現(xiàn)一個(gè)簡(jiǎn)單的秒殺系統(tǒng)。本文的秒殺系統(tǒng)雖然是基于Spring MVC+Spring+Mybatis框架實(shí)現(xiàn)鞠抑,但是其中的架構(gòu)思想以及處理問(wèn)題的方法是語(yǔ)言無(wú)關(guān)的饭聚。所以使用其他編程語(yǔ)言做開(kāi)發(fā)的同學(xué)也可以看一看。
本文主要是對(duì)秒殺系統(tǒng)架構(gòu)設(shè)計(jì)搁拙、系統(tǒng)功能等進(jìn)行介紹秒梳,另外提一下編碼過(guò)程中遇到的一些坑,具體的編碼不過(guò)多贅述感混,代碼中都寫(xiě)了詳細(xì)的注釋端幼。建議直接把項(xiàng)目down下來(lái)自己邊運(yùn)行邊探究礼烈。
項(xiàng)目github地址:https://github.com/eakonzhao/Spike-system ( 喜歡的話記得給個(gè)star哦 o(▽)o )
怎么把項(xiàng)目運(yùn)行起來(lái)弧满?
- git clone https://github.com/eakonzhao/Spike-system
- 打開(kāi) IDEA --> File --> New --> Open
- 打開(kāi)pom.xml,然后讓Maven將所需依賴都加載進(jìn)來(lái)
- 將jdbc.properties中的數(shù)據(jù)庫(kù)url此熬、用戶名和密碼改成你自己的
- 運(yùn)行Tomcat
- 在瀏覽器輸入http://localhost:8080/seckill/list
秒殺系統(tǒng)架構(gòu)設(shè)計(jì)
一庭呜、秒殺活動(dòng)技術(shù)挑戰(zhàn)
- 對(duì)現(xiàn)有業(yè)務(wù)造成沖擊:
秒殺活動(dòng)一般是網(wǎng)站營(yíng)銷的附加活動(dòng)。秒殺活動(dòng)的特點(diǎn)是持續(xù)時(shí)間短犀忱、瞬時(shí)訪問(wèn)量大的特點(diǎn)募谎,因此在秒殺活動(dòng)進(jìn)行期間肯定要占用大量的網(wǎng)絡(luò)帶寬以及服務(wù)器資源等,如果和網(wǎng)站日常的應(yīng)用部署在一起必然會(huì)對(duì)現(xiàn)有業(yè)務(wù)造成沖擊阴汇,甚至可能會(huì)導(dǎo)致宕機(jī)時(shí)間的發(fā)生数冬。在實(shí)際生產(chǎn)中,我們有兩種選擇:一個(gè)是進(jìn)行適當(dāng)?shù)胤?wù)降級(jí)搀庶,在秒殺活動(dòng)進(jìn)行的過(guò)程中關(guān)閉一些相對(duì)來(lái)說(shuō)沒(méi)有那么重要的服務(wù)拐纱。例如淘寶最初在應(yīng)對(duì)雙11的時(shí)候,就會(huì)把確認(rèn)收貨以及商品評(píng)價(jià)等功能關(guān)閉哥倔,以爭(zhēng)取給予秒殺活動(dòng)盡可能多的可用資源秸架;另一個(gè)選擇是秒殺系統(tǒng)和現(xiàn)有業(yè)務(wù)系統(tǒng)分開(kāi)部署,其實(shí)也就是業(yè)務(wù)分割部署的思想咆蒿。
- 高并發(fā)下的應(yīng)用东抹、數(shù)據(jù)庫(kù)負(fù)載
用戶在秒殺開(kāi)始前通過(guò)不斷刷新瀏覽器頁(yè)面以保證不會(huì)錯(cuò)過(guò)秒殺,這些請(qǐng)求如果按照一般的網(wǎng)站應(yīng)用架構(gòu)沃测,訪問(wèn)服務(wù)器缭黔、連接數(shù)據(jù)庫(kù)、會(huì)對(duì)應(yīng)用服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器造成極大的負(fù)載壓力蒂破。
- 突然增加的網(wǎng)絡(luò)及服務(wù)器帶寬
秒殺活動(dòng)時(shí)所需的帶寬會(huì)超過(guò)網(wǎng)站平時(shí)使用的帶寬
- 用戶未到秒殺時(shí)間直接下單
秒殺的流程應(yīng)該是到了秒殺時(shí)間才能開(kāi)始對(duì)商品下單購(gòu)買馏谨,在此時(shí)間點(diǎn)之前,只能瀏覽商品信息而不能下單寞蚌。而下單頁(yè)面也是可以通過(guò)一個(gè)普通的URL獲取田巴,如果得到這個(gè)URL钠糊,那么不用等到秒殺開(kāi)始就可以進(jìn)行下單了。
二壹哺、秒殺系統(tǒng)的應(yīng)對(duì)策略
秒殺系統(tǒng)獨(dú)立部署
-
秒殺商品頁(yè)面靜態(tài)化
重新設(shè)計(jì)秒殺商品頁(yè)面抄伍,不使用網(wǎng)站原來(lái)的商品詳情頁(yè)面,頁(yè)面內(nèi)容靜態(tài)化:將商品描述管宵、商品參數(shù)截珍、成交記錄和用戶評(píng)價(jià)全部寫(xiě)入一個(gè)靜態(tài)頁(yè)面,用戶請(qǐng)求不需要經(jīng)過(guò)應(yīng)用服務(wù)器的業(yè)務(wù)邏輯處理箩朴,也不需要訪問(wèn)數(shù)據(jù)庫(kù)岗喉。所以秒殺商品服務(wù)不需要部署動(dòng)態(tài)的Web服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器。
租借秒殺網(wǎng)絡(luò)帶寬
-
動(dòng)態(tài)生成隨即下單頁(yè)面URL
為了避免用戶直接訪問(wèn)下單頁(yè)面URL炸庞,需要將該URL動(dòng)態(tài)化钱床,即使秒殺系統(tǒng)的開(kāi)發(fā)者也無(wú)法在秒殺開(kāi)始之前訪問(wèn)下單頁(yè)面的URL。解決辦法是在下單頁(yè)面URL加入由服務(wù)器生成的隨機(jī)數(shù)作為參數(shù)埠居,在秒殺開(kāi)始的時(shí)候得到查牌。
三、需求分析與系統(tǒng)架構(gòu)
下面是秒殺系統(tǒng)的一個(gè)基本流程圖:
但是在本系統(tǒng)中滥壕,并沒(méi)有實(shí)現(xiàn)得那么完善纸颜,而是針對(duì)一部分方面進(jìn)行了實(shí)踐:
前端主要流程圖
后端簡(jiǎn)化流程圖(因?yàn)檫€會(huì)涉及到訪問(wèn)Redis緩存等操作)
在這里特別把其中的事務(wù)拿出來(lái)說(shuō)一下。我們的事務(wù)由兩個(gè)操作組成绎橘,分別是操作兩張表胁孙,一個(gè)操作是更新某張表的數(shù)據(jù),另一個(gè)操作是往某張表里面插入數(shù)據(jù)称鳞。其實(shí)這里有一個(gè)優(yōu)化的點(diǎn)涮较,就是在業(yè)務(wù)代碼中將插入操作放在更新操作之前。假如插入失敗就直接回滾胡岔。但是如果把更新操作(即扣庫(kù)存)放在前面法希,在并發(fā)的環(huán)境下可能會(huì)涉及高頻率的行級(jí)鎖競(jìng)爭(zhēng)問(wèn)題,導(dǎo)致系統(tǒng)性能急劇下降靶瘸。(由數(shù)據(jù)庫(kù)的三級(jí)封鎖協(xié)議可知這樣確實(shí)起到了一定的優(yōu)化作用)
系統(tǒng)功能介紹
由于上面已經(jīng)給出了系統(tǒng)的詳細(xì)流程圖苫亦,所以在這里就只展示幾張系統(tǒng)的截圖
實(shí)現(xiàn)
項(xiàng)目總體描述
本項(xiàng)目是基于
項(xiàng)目中應(yīng)用到的技術(shù)與工具
- IDEA
- MySQL
- Spring MVC
- Spring
- Mybatis
- Redis(用戶緩存部分商品信息)
- Maven
- protostuff(用于序列化對(duì)象屋剑,性能會(huì)比jdk自帶的序列化好)
........
其實(shí)還用到了一些技術(shù),這里就不一一給出了诗眨。由于本項(xiàng)目采用Maven進(jìn)行管理唉匾,所以在pom.xml文件里面都給出了所需的依賴。
項(xiàng)目骨架展示
遇到的一些坑
-
Spring MVC配置出錯(cuò)
- Spring MVC參數(shù)綁定錯(cuò)誤
調(diào)試的時(shí)候打開(kāi)瀏覽器控制臺(tái)看到報(bào)了個(gè)400錯(cuò)誤巍膘,后來(lái)檢查之后發(fā)現(xiàn)原來(lái)是Spring MVC的參數(shù)綁定出錯(cuò)了厂财,使用@pathVariable的時(shí)候要注意
-
logback和slf4j整合出錯(cuò)導(dǎo)致無(wú)法正常打印日志信息
在查看了官方手冊(cè)之后發(fā)現(xiàn)原來(lái)logback和slf4j在整合的過(guò)程中應(yīng)該注意版本的問(wèn)題