您好,登錄后才能下訂單哦!
我們都知道,正常去實(shí)現(xiàn)一個(gè)WEB端的秒殺系統(tǒng),前端的處理和后端的處理一樣重要;前端一般會(huì)做CDN,后端一般會(huì)做分布式部署,限流,性能優(yōu)化等等一系列的操作,并完成一些網(wǎng)絡(luò)的優(yōu)化,比如IDC多線路(電信、聯(lián)通、移動(dòng))的接入,帶寬的升級(jí)等等。而由于目前系統(tǒng)前端是基于微信小程序,所以關(guān)于前端部分的優(yōu)化就盡可能都是在代碼中完成,CDN這一步就可以免了;
關(guān)于秒殺的更多思考,在原有的秒殺架構(gòu)的基礎(chǔ)上新增了新的實(shí)現(xiàn)方案
通過(guò)分布式鎖的方式控制最終庫(kù)存不超賣,并控制最終能夠進(jìn)入到下單環(huán)節(jié)的訂單,入到隊(duì)列中慢慢去消費(fèi)下單
請(qǐng)求進(jìn)來(lái)之后,通過(guò)活動(dòng)開(kāi)始判斷和重復(fù)秒殺判斷之后,即進(jìn)入到消息隊(duì)列,然后在消息的消費(fèi)端去做庫(kù)存判斷等操作,通過(guò)消息隊(duì)列達(dá)到削峰的操作
其實(shí),我覺(jué)得兩種方案都是可以的,只是具體用在什么樣的場(chǎng)景;原有方案更適合流量相對(duì)較小的平臺(tái),而且整個(gè)流程也會(huì)更加簡(jiǎn)單;而新增方案則是許多超大型平臺(tái)采用的方案,通過(guò)消息隊(duì)列達(dá)到削峰的目的;而這兩種方案都加了真實(shí)能進(jìn)入的請(qǐng)求限制,通過(guò)redis的原子自增來(lái)記錄請(qǐng)求數(shù),當(dāng)請(qǐng)求量達(dá)到庫(kù)存的n倍時(shí),后面再進(jìn)入的請(qǐng)求,則直接返回活動(dòng)太火爆的提示;
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開(kāi)發(fā)便利性巧妙地簡(jiǎn)化了分布式系統(tǒng)基礎(chǔ)設(shè)施的開(kāi)發(fā),如服務(wù)發(fā)現(xiàn)注冊(cè)、配置中心、消息總線、負(fù)載均衡、斷路器、數(shù)據(jù)監(jiān)控等,都可以用Spring Boot的開(kāi)發(fā)風(fēng)格做到一鍵啟動(dòng)和部署。Spring Cloud并沒(méi)有重復(fù)制造輪子,它只是將各家公司開(kāi)發(fā)的比較成熟、經(jīng)得起實(shí)際考驗(yàn)的服務(wù)框架組合起來(lái),通過(guò)Spring Boot風(fēng)格進(jìn)行再封裝屏蔽掉了復(fù)雜的配置和實(shí)現(xiàn)原理,最終給開(kāi)發(fā)者留出了一套簡(jiǎn)單易懂、易部署和易維護(hù)的分布式系統(tǒng)開(kāi)發(fā)工具包。
后端項(xiàng)目是基于SpringCloud+SpringBoot搭建的微服務(wù)框架架構(gòu)
前端在微信小程序商城上
服務(wù)網(wǎng)關(guān) Zuul
服務(wù)注冊(cè)發(fā)現(xiàn) Eureka+Ribbon
服務(wù)框架 Spring MVC/Boot
服務(wù)容錯(cuò) Hystrix
分布式鎖 Redis
服務(wù)調(diào)用 Feign
消息隊(duì)列 Kafka
文件服務(wù) 私有云盤
富文本組件 UEditor
定時(shí)任務(wù) xxl-job
秒殺時(shí)大量用戶會(huì)在同一時(shí)間同時(shí)進(jìn)行搶購(gòu),網(wǎng)站瞬時(shí)訪問(wèn)流量激增;
秒殺一般是訪問(wèn)請(qǐng)求量遠(yuǎn)遠(yuǎn)大于庫(kù)存數(shù)量,只有少部分用戶能夠秒殺成功;
限流:鑒于只有少部分用戶能夠秒殺成功,所以要限制大部分流量,只允許少部分流量進(jìn)入服務(wù)后端(暫未處理);
削峰:對(duì)于秒殺系統(tǒng)瞬時(shí)的大量用戶涌入,所以在搶購(gòu)開(kāi)始會(huì)有很高的瞬時(shí)峰值。實(shí)現(xiàn)削峰的常用方法有利用緩存或者消息中間件等技術(shù);
異步處理:對(duì)于高并發(fā)系統(tǒng),采用異步處理模式可以極大地提高系統(tǒng)并發(fā)量,異步處理就是削峰的一種實(shí)現(xiàn)方式;
內(nèi)存緩存:秒殺系統(tǒng)最大的瓶頸最終都可能會(huì)是數(shù)據(jù)庫(kù)的讀寫,主要體現(xiàn)在的磁盤的I/O,性能會(huì)很低,如果能把大部分的業(yè)務(wù)邏輯都搬到緩存來(lái)處理,效率會(huì)有極大的提升;
由于前端是屬于小程序端,所以不存在前端部分的訪問(wèn)壓力,所以前端的訪問(wèn)壓力就無(wú)從談起;
1、秒殺相關(guān)的活動(dòng)頁(yè)面相關(guān)的接口,所有查詢能加緩存的,全部添加redis的緩存;
2、活動(dòng)相關(guān)真實(shí)庫(kù)存、鎖定庫(kù)存、限購(gòu)、下單處理狀態(tài)等全放redis;
3、當(dāng)有請(qǐng)求進(jìn)來(lái)時(shí),首先通過(guò)redis原子自增的方式記錄當(dāng)前請(qǐng)求數(shù),當(dāng)請(qǐng)求超過(guò)一定量,比如說(shuō)庫(kù)存的10倍之后,后面進(jìn)入的請(qǐng)求則直接返回活動(dòng)太火爆的響應(yīng);而能進(jìn)入搶購(gòu)的請(qǐng)求,則首先進(jìn)入活動(dòng)ID為粒度的分布式鎖,第一步進(jìn)行用戶購(gòu)買的重復(fù)性校驗(yàn),滿足條件進(jìn)入下一步,否則返回已下單的提示;
4、第二步,判斷當(dāng)前可鎖定的庫(kù)存是否大于購(gòu)買的數(shù)量,滿足條件進(jìn)入下一步,否則返回已售罄的提示;
5、第三步,鎖定當(dāng)前請(qǐng)求的購(gòu)買庫(kù)存,從鎖定庫(kù)存中減除,并將下單的請(qǐng)求放入kafka消息隊(duì)列;
6、第四步,在redis中標(biāo)記一個(gè)polling的key(用于輪詢的請(qǐng)求接口判斷用戶是否下訂單成功),在kafka消費(fèi)端消費(fèi)完成創(chuàng)建訂單之后需要?jiǎng)h除該key,并且維護(hù)一個(gè)活動(dòng)id+用戶id的key,防止重復(fù)購(gòu)買;
7、第五步,消息隊(duì)列消費(fèi),創(chuàng)建訂單,創(chuàng)建訂單成功則扣減redis中的真實(shí)庫(kù)存,并且刪除polling的key。如果下單過(guò)程出現(xiàn)異常,則刪除限購(gòu)的key,返還鎖定庫(kù)存,提示用戶下單失敗;
8、第六步,提供一個(gè)輪詢接口,給前端在完成搶購(gòu)動(dòng)作后,檢查最終下訂單操作是否成功,主要判斷依據(jù)是redis中的polling的key的狀態(tài);
SpringCloud zuul的層面有很好的限流策略,可以防止同一用戶的惡意請(qǐng)求行為
1 zuul:
2 ratelimit:
3 key-prefix: your-prefix #對(duì)應(yīng)用來(lái)標(biāo)識(shí)請(qǐng)求的key的前綴
4 enabled: true
5 repository: REDIS #對(duì)應(yīng)存儲(chǔ)類型(用來(lái)存儲(chǔ)統(tǒng)計(jì)信息)
6 behind-proxy: true #代理之后
7 default-policy: #可選 - 針對(duì)所有的路由配置的策略,除非特別配置了policies
8 limit: 10 #可選 - 每個(gè)刷新時(shí)間窗口對(duì)應(yīng)的請(qǐng)求數(shù)量限制
9 quota: 1000 #可選- 每個(gè)刷新時(shí)間窗口對(duì)應(yīng)的請(qǐng)求時(shí)間限制(秒)
10 refresh-interval: 60 # 刷新時(shí)間窗口的時(shí)間,默認(rèn)值 (秒)
11 type: #可選 限流方式
12 - user
13 - origin
14 - url
15 policies:
16 myServiceId: #特定的路由
17 limit: 10 #可選- 每個(gè)刷新時(shí)間窗口對(duì)應(yīng)的請(qǐng)求數(shù)量限制
18 quota: 1000 #可選- 每個(gè)刷新時(shí)間窗口對(duì)應(yīng)的請(qǐng)求時(shí)間限制(秒)
19 refresh-interval: 60 # 刷新時(shí)間窗口的時(shí)間,默認(rèn)值 (秒)
20 type: #可選 限流方式
21 - user
22 - origin
23 - url
當(dāng)一個(gè)活動(dòng)的訪問(wèn)量級(jí)特別大的時(shí)候,可能從域名分發(fā)進(jìn)來(lái)的nginx就算是做了高可用,但實(shí)際上最終還是單機(jī)在線,始終敵不過(guò)超大流量的壓力時(shí),我們可以考慮域名的多IP映射。也就是說(shuō)同一個(gè)域名下面映射多個(gè)外網(wǎng)的IP,再映射到DMZ的多組高可用的nginx服務(wù)上,nginx再配置可用的應(yīng)用服務(wù)集群來(lái)減緩壓力;
這里也順帶介紹redis可以采用redis cluster的分布式實(shí)現(xiàn)方案,同時(shí)springcloud hystrix 也能有服務(wù)容錯(cuò)的效果;
而關(guān)于nginx、springboot的tomcat、zuul等一系列參數(shù)優(yōu)化操作對(duì)于性能的訪問(wèn)提升也是至關(guān)重要;
補(bǔ)充說(shuō)明一點(diǎn),即使前端是基于小程序?qū)崿F(xiàn),但是活動(dòng)相關(guān)的圖片資源都放在自己的云盤服務(wù)上,所以活動(dòng)前活動(dòng)相關(guān)的圖片資源上傳CDN也是至關(guān)重要,否則哪怕是你IDC有1G的流量帶寬,也會(huì)分分鐘被吃完;
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。