一、秒殺場景的特點
秒殺的商品具有**低、庫存有限、定時開始的特點,因此秒殺場景最大的特點就是高併發。數以千萬的使用者的流量集中在某個時間點上(即秒殺開始時),給後端伺服器造成很大壓力,如果不能進行有效削峰、限流,所有請求一次性打到某一台伺服器或資料庫上,必然造成服務的不可用,給使用者造成不良體驗。
二、整體架構設計
在整體架構上,使用者的請求首先通過乙個閘道器進行負載均衡,根據負載均衡演算法的不同,應用不同的策略將請求**給對應的應用伺服器,伺服器對使用者的請求進行限流,拒絕大部分的請求。根據redis中快取的商品資訊,判斷當前秒殺是否已結束,如果秒殺結束,拒接請求並設定記憶體標記,後續的請求直接拒絕,無需再查詢redis快取;如果秒殺未結束,將請求入隊mq,進行非同步處理,進一步削峰。
多個消費者從mq中取訊息,進行處理,即檢查對應商品的庫存情況,減庫存並生成訂單,要注意這裡需要原子操作的控制,也有多種解決方案,在後面會詳細討論。對秒殺成功的訂單,設定有效期,使用者在有效期內成功付款,則生成支付訂單,持久化到mysql,否則會隨著redis快取中key的過期而失效。
三、秒殺系統常見的問題
秒殺系統由於高併發的特點,會帶來一系列問題,這些問題不僅是秒殺系**有,任何高併發系統都需要考慮這些問題的解決方案。
mysql由於資料都存放在磁碟中,併發量十分有限,並且為了保證業務邏輯的正確性,每個請求都需要對商品資料進行一次加鎖和解鎖操作(行鎖的效率低),更加降低了效率,造成不好的使用者體驗。更糟的情況是mysql在高併發環境下,還可能會崩潰,造成服務不可用。
超賣問題**於核減庫存的操作其實不具備原子性,它分為了三步:查詢庫存->檢查庫存不為0->扣減庫存。那麼設想乙個場景:當服務查詢庫存為1,但還未扣減庫存時,另乙個服務查詢庫存也為1,兩個服務都會進行扣減庫存、生成訂單的操作,造成了超賣。
少賣問題**於已經成功扣減庫存,但生成秒殺訂單因為各種原因失敗了,導致庫存被扣減卻沒有訂單生成的情況。該問題出現的根本原因是扣減庫存和生成訂單兩步操作沒***原子性。
某些不法使用者可能通過自動化指令碼模擬http請求的方式反覆刷秒殺介面,既對系統造成了更大的流量壓力也產生了造成了不公平。
四、優化方案
通過隨機演算法、雜湊演算法或根據當前負載情況動態地攔截請求,快速失敗,只將少部分的請求放入mq等待消費者消費。
通過驗證碼機制能夠很好限制使用者的請求速度,同時也能防止作弊。驗證碼的選擇上可以選擇、算式、滑塊等,為了防止驗證碼識別工具,盡可能選擇較複雜的驗證碼。
每次使用者請求後在快取中進行計數,並設定相應有效期,當使用者請求達到閾值直接拒絕請求,實現限制單使用者每秒請求次數的功能,防止單一使用者的高頻訪問給系統造成更大壓力,這個策略根據業務需求的不同可對賬號的限制、ip的限制或賬號和ip共同限制。
通過頁面靜態化、頁面快取的方式降低響應的時間。
頁面靜態化是進行頁面快取的第一步,將乙個動態頁面分離成靜態的頁面模板和動態的資料部分,將靜態的部分拆分出來進行快取,動態的部分根據伺服器的業務處理返回json資料再進行渲染。比如在秒殺頁面,頁面的模板框架是靜態資源,可以進行快取,而商品名稱、庫存數量、**、秒殺剩餘時間、驗證碼等資訊根據請求的響應結果進行動態渲染。
靜態頁面抽離出來之後就要進行快取,快取可以放在使用者瀏覽器、服務端或cdn,放在瀏覽器上的快取具有不可控性,如果使用者不進行及時重新整理,很可能看到錯誤的不一致資訊,對於秒殺系統而言,資訊的實時性非常重要,這點看來放在瀏覽器上的快取並不合適。另外服務端主要進行業務邏輯的計算和載入,不擅長處理大量連線,如果進行頁面的快取和載入會帶來效能的降低。因此頁面快取常放在cdn上。
cdn的節點一般選擇訪問量集中的地區附近且要保證節點與主站之間的網路通訊,即考慮快取的命中率和及時失效的問題,這點對於高併發、資訊變化快的秒殺系統而言及其重要。
大量的請求並不直接到達應用伺服器,而是先進入mq佇列,多個消費者根據處理能力從mq中拿到請求訊息並進行業務處理,類似於著名的「漏桶演算法」。mq還可以通過設定最大佇列的長度或訊息的有效期ttl來進行限流,通過設定訊息超時快速失敗,防止大量的訊息堆積給使用者帶來不好的體驗。
高併發秒殺專案 05
頁面快取 改造goodscontroller中的方法,加入thymeleafviewresolver註解 手動渲染 springwebcontext ctx newspringwebcontext request,response,request.getservletcontext request....
秒殺業務場景如何削峰
流量削峰這個概念主要來自於網際網路的業務場景。例如春節火車票搶購,大量的使用者需要同一時間去搶購 又例如阿里的雙十一秒殺,短時間內上億的使用者湧入,瞬間流量巨大 高併發 具體就是,300萬人在凌晨0點搶購一件數量只有500件的商品,最後能購買到的只有300萬人中的這500人。從業務上來說,這種秒殺活...
高併發秒殺系統方案(簡介)
memcatch相比redis而言,無法做持久化。jsr303 服務端的驗證框架。首先我們可以將靜態頁面快取在使用者的瀏覽器端或者是手機端,然後使用者的請求會到達cdn 的快取和映象 進一步到達閘道器 我們這裡是nginx,在nginx上繼續做快取 再到我們的應用伺服器 同樣可以做快取 redis快...