黃素萍,劉敏娜,朱亞兵,田知佩
(咸陽師范學院 計算機學院,陜西 咸陽 712000)
便捷的網(wǎng)絡使得互聯(lián)網(wǎng)用戶基數(shù)越來越大,并發(fā)請求量隨之增多。當大量用戶通過網(wǎng)絡同時訪問同一站點時, 就會出現(xiàn)高并發(fā)的情況,Web 系統(tǒng)性能瓶頸也會隨之出現(xiàn)。相對于用戶對服務性能提出的更高要求, 服務器對Web 訪問請求處理速度的提升卻遠遠低于應用服務的增長需求,單靠提升服務器硬件性能已不能滿足一些Web 應用系統(tǒng)[1]的需求。 目前,大型分布式系統(tǒng)采用的高并發(fā)解決方案并不適用部署在單服務器上的中小型Web 應用。通過集群等方式處理高并發(fā)流量的方案成本過高[2]。 因此,需要為部署在單服務器的Web 應用提出可用的網(wǎng)絡流量高并發(fā)優(yōu)化處理方案。
Web 應用系統(tǒng)在大量用戶進行訪問的情況下,易出現(xiàn)系統(tǒng)響應的時間過長、系統(tǒng)崩潰和癱瘓等現(xiàn)象。同時,隨著社會不斷發(fā)展,使用互聯(lián)網(wǎng)的用戶越來越多。 所以,要對Web 應用系統(tǒng)功能進行優(yōu)化,以保證Web 應用系統(tǒng)的服務質量。
解決高并發(fā)的一些常用關鍵技術包含:
(1)緩存技術。它是把數(shù)據(jù)庫的數(shù)據(jù)存入緩存,請求不經(jīng)過數(shù)據(jù)庫,直接從緩存中讀取數(shù)據(jù),能夠大大提高效率。 其中,Redis 是單線程的 NoSQL[3]技術,單線程注定了它是線程安全的。并且,它作為內存技術, 訪問和處理速度都遠大于如MySQL 等硬盤技術。
(2)消息隊列技術。RabbitMQ 是目前使用最多的消息隊列。它典型的使用場景就是在大量訪問涌入時,服務器可能無法及時處理需要進行業(yè)務削峰時發(fā)揮作用。
(3)Zookeeper 技術。Zookeeper 是一門分布式技術。 它通過序列節(jié)點機制實現(xiàn)分布式鎖,能夠解決多個線程競爭同一個共享資源時的線程安全問題。
通過研究Web 系統(tǒng),為了應對高并發(fā)問題,可將結合 Redis 緩存、RabbitMQ 消息隊列、Zookeeper的不可重入鎖等中間件技術的實現(xiàn)方案, 應用于Web 應用系統(tǒng)產(chǎn)生高并發(fā)訪問功能的模塊,以保證系統(tǒng)的快速響應,解決異步消息、流量削峰和線程安全等問題。 其中,使用Redis 對信息存取處理進行緩存。 同時, 結合RabbitMQ 消息隊列技術,把Redis 處理的大量請求,不直接請求數(shù)據(jù)庫訪問,采用異步操作方式,先進入消息隊列,然后排隊處理,將瞬間并發(fā)訪問變成一段時間正常訪問數(shù)據(jù)庫。其中,消息隊列可以解決應用耦合、異步消息、流量削峰等的問題,實現(xiàn)系統(tǒng)的高性能、高可用和可伸縮等特點。 另外,通過Zookeeper 實現(xiàn)一個分布式鎖來解決線程安全問題。
為應用以上高并發(fā)技術解決方案, 現(xiàn)設計實現(xiàn)一個商品秒殺系統(tǒng)。該系統(tǒng)的用戶分為兩類:管理員和商品秒殺用戶。系統(tǒng)的業(yè)務功能有秒殺管理、商品管理、訂單管理、客戶管理、人員管理、購物中心和個人中心等功能模塊。 系統(tǒng)功能模塊如圖1 所示。
圖1 系統(tǒng)功能模塊Figure 1 System function module
系統(tǒng)中,管理員功能模塊分為秒殺管理、訂單管理、商品管理、客戶管理和人員管理模塊。
(1)秒殺管理:分為秒殺信息的添加、修改、刪除和查詢功能。
(2)商品管理: 包括商品基本信息管理、商品類別信息管理和庫存管理。
(3)訂單管理:包括訂單的查詢、刪除、出貨功能。
(4)客戶管理:包含對客戶信息的查看、刪除功能。
(5)人員管理:包括管理員的信息查詢、添加、刪除和修改。
商品秒殺用戶功能模塊分為注冊登錄、購物中心和人個中心。
(1)注冊登錄:未注冊用戶可進行信息填寫并注冊,已經(jīng)注冊用戶可輸入賬號、密碼、驗證碼進行登錄。
(2)購物中心:包括所有商品、限時搶購、即將開始商品查看功能。
(3)個人中心:包括我的訂單、地址管理、個人信息功能。
本系統(tǒng)設計的數(shù)據(jù)庫實體主要有商品信息、庫存信息、訂單信息、秒殺活動信息等。 針對這些實體, 商品秒殺系統(tǒng)的數(shù)據(jù)庫創(chuàng)建了對應的數(shù)據(jù)表。其中,與秒殺功能有關的主要表字段設計如下:
(1)商品數(shù)據(jù)表:字段有ID、商品名、類別ID、圖片地址、是否上架、商品描述、差價、創(chuàng)建時間、更新時間、邏輯刪除。
(2)庫存數(shù)據(jù)表:字段有 ID、商品 ID、進價、成本價、售價、數(shù)量、預警量(默認10)、快遞費用、是否刪除。
(3)秒殺活動數(shù)據(jù)表:字段有ID、庫存ID、收藏人數(shù)、剩余數(shù)量、總數(shù)、銷售價格、開始時間、結束時間、創(chuàng)建時間、修改時間、是否刪除。
系統(tǒng)中包含多個模塊,每個功能模塊又包含多個子功能。本系統(tǒng)主要研究的是處理高并發(fā)功能的實現(xiàn),下面將著重闡述應用高并發(fā)技術方案的核心模塊——商品秒殺用戶購物中心模塊。購物中心模塊包括:商品瀏覽、商品查詢、限時搶購三個功能。限時搶購功能的設計中應用了高并發(fā)處理方案,其他功能不再贅述。
限時搶購是出現(xiàn)高并發(fā)的核心功能。它涉及大量用戶同時操作時的庫存安全、系統(tǒng)可用性、單用戶多次操作的冪等性、要避免用戶點擊一次產(chǎn)生多筆相同訂單和商品超賣等問題。該功能的實現(xiàn)邏輯是,當秒殺用戶參與秒殺操作提交請求時,系統(tǒng)程序首先判斷當前商品的庫存是否充足。若庫存不充足,返回商品售空提示;若庫存充足,程序申請一個基于Zookeeper 的不可重入鎖,如果申請成功進入隊列排隊等待執(zhí)行,否則返回秒殺失敗提示。 隊列中的任務會依次執(zhí)行, 執(zhí)行到的任務會先從Redis拿出進入隊列前生成的訂單ID, 進行實際的下單操作,下單成功后將保存數(shù)據(jù)庫的操作放入消息隊列,返回下單成功提示,并跳轉到支付界面。功能實現(xiàn)的流程如圖2 所示。
圖2 限時搶購功能流程圖Figure 2 The flow chart of the limited-time snap-up function
由于本系統(tǒng)是使用SpringBoot 框架來實現(xiàn)的,在此功能的實現(xiàn)中,首先在SpringBoot 框架的pom.xml 配置文件里加入依賴整合, 使用Redis 對商品庫存進行緩存,以減小查詢數(shù)據(jù)庫的壓力。 用戶每次進行商品秒殺時, 系統(tǒng)程序通過調用AddOrder-Controller 添加訂單控制類的 killGoods()方法,使用 其 中 的 語 句 redisTemplate.opsForValue ().get(RedisEnum.USER_KILL_NUM + id + goodsId)從緩存中獲取商品庫存。但這一步并不能完全解決此時的高并發(fā)問題,還需要應用RabbitMQ 消息隊列技術,通過Redis 的大量請求,不直接請求數(shù)據(jù)庫下單采用異步下單方式,調用rabbitTemplate. convertAndSend()方法先進入消息隊列,然后排隊消費,可將瞬間并發(fā)訪問變成一段時間正常訪問數(shù)據(jù)庫。 同時,通過Zookeeper 的序列節(jié)點機制來實現(xiàn)一個分布式鎖, 調用AddOrderServiceImpl 添加訂單服務類的killOrder()方法。 在該方法使用lock.acquire(60,TimeUnit.SECONDS)的結果來判斷是否獲取到鎖,解決多個線程競爭同一個共享資源時候的線程安全問題。 基于SpringBoot 框架,系統(tǒng)實現(xiàn)限時搶購功能的業(yè)務關系如圖3 所示。
圖3 限時搶購功能實現(xiàn)的業(yè)務關系Figure 3 The business relationship of the flash sale function
通過以上幾個環(huán)節(jié), 本功能將Redis、Rabbit-MQ、Zookeeper 這幾種中間件技術應用到具體實現(xiàn)中,解決了用戶在商品秒殺產(chǎn)生高并發(fā)情況下的異步消息、流量削峰和線程安全問題,實現(xiàn)了系統(tǒng)的快速響應。
在系統(tǒng)開發(fā)完成之后, 使用了開源測試工具JMeter 對系統(tǒng)實現(xiàn)高并發(fā)處理商品秒殺功能模塊中的限時搶購功能進行了性能測試。JMeter 是開源測試工具,其運行原理是通過線程組來驅動多個線程的方式運行,可以進行接口測試、性能測試、接口及性能的自動化測試。
在JMeter 中, 通過不斷增加線程數(shù)模擬多個用戶同時秒殺同一件商品。線程總共啟動時間設置為0 表示并發(fā),隨著線程數(shù)量不斷增加,吞吐量在線程數(shù)為600 時為987.8/sec。線程數(shù)為600 時的聚合報告如圖4 所示。之后,隨線程數(shù)增加,吞吐量開始逐漸降低并且平均響應時間變長,當線程數(shù)逐漸增大至650 時,吞吐量為866.4/sec。 可以看出系統(tǒng)進行商品秒殺操作能支持的最大的用戶數(shù)為600。
圖4 線程數(shù)為600 時的聚合報告Figure 4 Aggregate report with 600 threads
另外,在系統(tǒng)的限時搶購功能中,針對高并發(fā)方案對應程序進行相應的注釋和修改后,獲得了功能實現(xiàn)的常規(guī)方案程序。對不應用本文介紹的高并發(fā)案的常規(guī)方案實現(xiàn)的功能程序進行測試發(fā)現(xiàn),在多個用戶同時秒殺同一件商品時,當線程數(shù)逐漸增大至300 時,吞吐量為875.5/sec。 之后隨線程數(shù)增加吞吐量逐漸降低,同時平均響應時間變長。 限時搶購功能性能測試如表1 所示。
本系統(tǒng)測試時,秒殺系統(tǒng)運行在普通性能的筆記本電腦上,當程序按常規(guī)方案實現(xiàn)時,系統(tǒng)的高性能并發(fā)承載量最高為300 個用戶。在應用了高并發(fā)技術方案后,系統(tǒng)的高性能并發(fā)承載量最高可達600 個用戶。 這說明此方案從軟件實現(xiàn)的角度大大提升了Web 應用系統(tǒng)的并發(fā)性和吞吐量, 同時保證了系統(tǒng)的可用性。
本文研究了高并發(fā)的優(yōu)化技術,提出了基于限流、緩存、消息隊列等技術結合的方案,設計實現(xiàn)了商品秒殺系統(tǒng)。該系統(tǒng)中的限時搶購功能通過應用高并發(fā)技術方案,大大改善了系統(tǒng)在較高并發(fā)訪問時的并發(fā)性和吞吐量,即使在大量用戶進行訪問的情況下也不易出現(xiàn)系統(tǒng)響應時間過長、系統(tǒng)崩潰和癱瘓等現(xiàn)象,能夠保證用戶有較好的應用體驗。 由于本系統(tǒng)的實現(xiàn)和測試是在普通性能筆記本做為服務器的條件下完成的, 今后還可以從服務器性能、數(shù)據(jù)庫軟件性能、網(wǎng)絡操作等方面進行進一步優(yōu)化。
表1 限時搶購功能性能測試表Table 1 Time-limited snap-up function performance test table