購物網站和秒殺系統實現技術


我們需要兩個模塊,一個后台Admin模塊,一個前台Home模塊,利用ThinkPhp框架,自動生成MVC框架如圖6-2所示。

 

任何一個表單的操作,都需要前端驗證和后台驗證,前端驗證是為了用戶體驗,使用javascript,后台驗證是為了數據的完整性,使用php,最好的方法,是結合二者,就是ajax了。圖片上傳的部分,使用tp自帶的上傳類。

6.3 秒殺系統

秒殺系統其實是針對庫存做的系統。用戶成功秒殺商品,對於我們系統的操作就是減庫存和記錄用戶的購買明細。用戶的購買明細包括記錄誰購買成功、購買成功的時間和付款信息。而對於減庫存操作,需要考慮到以下兩個問題:

(1)若是用戶成功秒殺商品,我們記錄了其購買明細,卻沒有減庫存。會導致商品的超賣。

(2)減了庫存卻沒有記錄用戶的購買明細,導致商品的少賣。

對於上述兩個問題,可以通過MySQL內置的事務機制進行處理,它可以准確的幫我們完成減庫存和記錄用戶購買明細的過程。

對於秒殺系統,我們只是實現秒殺的一些功能:

(1)秒殺接口的暴露。

(2)執行秒殺的操作。

(3)相關查詢,比如說列表查詢,詳情頁查詢。

秒殺系統包括包括三個模塊的設計,DAO層、Service層和Web層的設計,另外考慮到系統高並發的問題,從而設計了系統高並發的處理。在系統設計之前,為了更好地理解系統的開發過程,對相關技術進行描述。

6.3.2 相關軟件包安裝

用Maven創建我們的項目seckill,然后使用IDEA打開該項目。在 main包下進行我們項目的代碼編寫及相關配置文件,test包下進行我們項目的測試。

秒殺系統的servlet版本為3.1,相關的第三發jar包通過pom文件添加,

6.3.2 DAO層

首先需要創建秒殺庫存表和秒殺成功明細表,如下所示:

基於MyBatis來實現我們設計的Dao層接口。首先需要配置我們的MyBatis,在resources包下創建MyBatis全局配置文件mybatis-config.xml文件。

配置文件創建好后我們需要關注的是Dao接口該如何實現,mybatis為我們提供了mapper動態代理開發的方式為我們自動實現Dao的接口。在mapper包下創建對應Dao接口的xml映射文件,里面用於編寫我們操作數據庫的sql語句,SeckillDao.xml和SuccessKilledDao.xml。

MyBatis和Spring的整合,整合目標:

(1)更少的編碼:只寫接口,不寫實現類。

(2)更少的配置:別名、配置掃描映射xml文件、dao實現。

(3)足夠的靈活性:自由定制SQL語句、自由傳結果集自動賦值。

在spring包下創建一個spring-dao.xml,用於配置dao層對象的配置文件,在resources包下創建jdbc.properties.xml,用於配置數據庫的連接信息,配置如下。

6.3.3 Service層

在Dao層我們只完成了針對表的相關操作,包括寫了接口方法和映射文件中的sql語句,並沒有編寫邏輯的代碼,例如對多個Dao層方法的拼接,當我們用戶成功秒殺商品時我們需要進行商品的減庫存操作(調用SeckillDao接口)和增加用戶明細(調用SuccessKilledDao接口),這些邏輯我們都需要在Service層完成。Dao層只進行數據的訪問操作,接下來我們便進行Service層代碼的編寫。秒殺Service接口設計如下:

(1)創建service包用於存放我們的Service接口和其實現類。

(2)創建exception包用於存放service層出現的異常,例如重復秒殺商品異常、秒殺已關閉等異常。

(3)創建dto包作為傳輸層, 用於完成web和service層的數據傳遞。

(4)創建entity包用於業務數據的封裝。

在dto包中創建Exposer.java,用於封裝秒殺的地址信息。SeckillExecution.java,用於判斷秒殺是否成功,成功就返回秒殺成功的所有信息(包括秒殺的商品id、秒殺成功狀態、成功信息、用戶明細),失敗就拋出一個我們允許的異常(重復秒殺異常、秒殺結束異常)。

然后需要在exception包下創建我們在秒殺業務過程中允許的異常,RepeatKillException.java用於處理重復的秒殺異常;SeckillCloseException.java用於處理秒殺關閉異常;SeckillException.java用於處理秒殺相關業務的異常。

在實現類SeckillServiceImpl.java中,我們用枚舉的方式將異常函數中返回的常量進行封裝,在enums包下創建一個枚舉類型SeckillStatEnum.java,用於返回state和stateInfo這兩個參數的相關數據。

使用Spring托管Service依賴配置:

在spring包下創建一個spring-service.xml文件,然后采用注解的方式將Service的實現類加入到Spring IOC容器中,然后在Service實現類的方法中,在需要進行事務聲明的方法上加上事務的注解,配置如下。

6.3.4 Web層

秒殺系統Web層主要涉及前端交互設計、Restful:url滿足Restful設計規范、Spring MVC、bootstrap+jquery這四個方面的開發。秒殺系統的前端交互流程設計如下圖6-3所示。

 

 

圖6-3 前端交互流程

整合配置Spring MVC框架:

在web.xml中進行我們前端控制器DispatcherServlet的配置,配置springMVC需要加載的配置文件spring-dao.xml,spring-service.xml和spring-web.xml,詳細配置如下。

完成Spring MVC的相關配置后,接下來就要基於Restful接口實現項目中的Controller開發。Controller中的每一個方法都對應我們系統中的一個資源URL,其設計應該遵循Restful接口的設計風格。在web包下創建一個SeckillController.java,內容如表6-11所示。

json數據的一個Vo類,即SeckillResult.java,在dto包中創建它,內容如下。

6.3.5 高並發的優化

秒殺系統面臨着如下問題:

(1)無法使用cdn緩存,因為系統邏輯不可能放在cdn中。

(2)后端緩存困難:庫存問題,因為運用到了mysql事務操作(設置聯合主鍵)。

(3)一行數據競爭:熱點商品,因為多個用戶同時對數據庫某條數據進行操作。

秒殺系統的優化方案:

(1)前端控制:暴露接口,按鈕防重復提交。

(2)動靜態數據分離:cdn緩存,后端Redis緩存。

(3)事務競爭優化:減少事務鎖時間,把客戶端邏輯放在mysql服務端,避免網絡延遲和GC的影響。 GC(Garbage Collection)垃圾回收機制

使用Redis優化地址暴露接口,在dao包下新建一個cache包,然后創建一個RedisDao.java函數,在spring-dao.xml中配置redisdao構造器。

針對網絡延遲和GC導致的並發問題,使用存儲過程,將整個事務放在mysql端完成,秒殺存儲過程實現如下。

最后,在ServiceService.java中建立存儲執行秒殺操作的函數,在SeckillDao.java實現該接口,在SeckillDao.xml中使用mybatis調用存儲過程,在服務端的SeckillServiceImpl.java完成配置即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM