日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

什么是“秒杀”?为什么传统项目中也有“秒杀”的概念?一起来分析一下.

發(fā)布時(shí)間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 什么是“秒杀”?为什么传统项目中也有“秒杀”的概念?一起来分析一下. 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是“秒殺”?為什么傳統(tǒng)項(xiàng)目中也有“秒殺”的概念?一起來分析一下.

?

如題所述,到底什么是“秒殺”,為什么我不是做電商的,還和秒殺扯上關(guān)系了?

或者說“秒殺”一定是電商項(xiàng)目的一個(gè)關(guān)鍵字嗎?

?

當(dāng)然,筆者這樣反問了,那么當(dāng)然,秒殺就不是特定電商項(xiàng)目的事情了。可以將其理解為這一類的業(yè)務(wù)的一個(gè)代稱。

哪一類業(yè)務(wù)呢?高并發(fā)項(xiàng)目。

?

?

舉個(gè)行業(yè)的例子來說;(這里還是以電商項(xiàng)目為例,因?yàn)殡娚添?xiàng)目的并發(fā)場景比較便于理解)

雙十一,是每個(gè)人都熱血沸騰的時(shí)刻,為什么這里說是時(shí)刻呢?因?yàn)閺奈覀兗夹g(shù)人眼中,雙十一不是一天的概念,而是那么一瞬間的概念,通常來說,我們比較關(guān)心雙十一 0點(diǎn)的時(shí)候的一個(gè)流量情況,而不是關(guān)心一天的流量情況(當(dāng)然,一天也得關(guān)心,此處相對(duì)而論);

從產(chǎn)品角度、用戶角度而言,雙十一是一個(gè)活動(dòng),一個(gè)通過各種紅包、優(yōu)惠價(jià)等方式形成的一種促銷活動(dòng),這種活動(dòng),將會(huì)吸引用戶大量購物,產(chǎn)生大量交易訂單,從而帶動(dòng)經(jīng)濟(jì)流動(dòng),產(chǎn)生各種經(jīng)濟(jì)利益。

從技術(shù)角度而言,雙十一產(chǎn)生的數(shù)據(jù)量也是龐大的,此處通過去年雙十一一個(gè)圖片表達(dá)。

這是歷年的雙十一當(dāng)天的訂單數(shù)量產(chǎn)生量,以2019年為例,一天的時(shí)間產(chǎn)生了2684億元的成交量

,這當(dāng)天的并發(fā)量是怎么評(píng)估的。

?

再看另一張圖,這里統(tǒng)計(jì)的是突破1000億耗時(shí),用了64分鐘成交金額1000億,這并發(fā)量又是多少?

.

2秒不到產(chǎn)生了100億的交易額

?

這種數(shù)據(jù)量的產(chǎn)生的流量高峰是什么樣的高度,相信這都是行業(yè)能標(biāo)桿的表現(xiàn)。

這里的并發(fā)量是真的不敢想象,我們簡單的計(jì)算一下,1.36秒,產(chǎn)生了100億的交易額。

假設(shè)1個(gè)訂單平均是100塊錢,那么1.36秒就是產(chǎn)生了 1億的訂單數(shù)

假設(shè)1個(gè)訂單平均是1000塊錢,那么1.36秒就是產(chǎn)生了 10000000的訂單數(shù)

那么就可以認(rèn)為 并發(fā)為 7,352,941/s

一秒 700多萬的并發(fā),試問這什么數(shù)據(jù)庫,什么服務(wù)能承受得了?

?

此處再強(qiáng)調(diào),700多萬的并發(fā)量是站在有效訂單生成的基礎(chǔ)上計(jì)算而來,并且是估算1000元一個(gè)訂單的平均成交額。

要知道,我們平時(shí)的搶購經(jīng)驗(yàn)來說,基本上是一件商品,上千上萬的用戶在搶購,這個(gè) 700多萬 應(yīng)當(dāng) * 1000 都不為過。

?

那么給各位先分析了一個(gè)數(shù)據(jù)上的概念,我們對(duì)后面的分析可能會(huì)更加理解一些。

那么在這種情況,上萬人搶購一件商品的庫存,對(duì)于系統(tǒng)而言,如何承擔(dān)這樣大的壓力,并且有多少這種搶購存在,對(duì)系統(tǒng)的負(fù)載又是一大考驗(yàn)。

從數(shù)據(jù)庫層面,我們需要生成訂單,減庫存,這么大的并發(fā)請求,我們?nèi)绾文鼙WC一件商品,最終成交只會(huì)有一個(gè)訂單,其他請求都搶購失敗。我們?nèi)绾伪WC我們能夠保證系統(tǒng)能夠正常處理這么大的并發(fā)搶購量,而不是導(dǎo)致此次搶購活動(dòng)癱瘓,導(dǎo)致就連一個(gè)訂單都沒有生成?這些都是我們此次需要思考的問題。

對(duì)于數(shù)據(jù)而言,我們需要將庫存 -1,然后生成一個(gè)訂單數(shù);這樣才是正確的流程,并且?guī)齑嬷荒苁?gt;=0,切不能成為負(fù)數(shù)。我們系統(tǒng)如何控制此種規(guī)則嚴(yán)格執(zhí)行?在很多場景,很多顧客在搶購成功后,生成訂單了,然后不想要了,就會(huì)取消訂單,這個(gè)時(shí)候,我們需要將庫存+1,吧這個(gè)名額給其他顧客繼續(xù)搶購,那么這如何實(shí)現(xiàn)?是直接將庫存加回去嗎?

站在數(shù)據(jù)庫層面,我們對(duì)于一件商品的庫存數(shù)據(jù),如果多個(gè)個(gè)顧客同時(shí)請求下單,這個(gè)時(shí)候,我們怎么處理這種多線程環(huán)境下,保證不會(huì)超出庫存量?

每個(gè)用戶都會(huì)去不停的刷新商品,不停地關(guān)注商品的庫存量,想看看現(xiàn)在庫存是否有,我是否能下單?這種高請求量的讀請求和其他用戶的高請求量的下單操作并發(fā)出現(xiàn),我們?nèi)绾慰刂埔粭l數(shù)據(jù)讀寫操作并發(fā)環(huán)境下正常?那這種情況下,我們既要保證有序進(jìn)行,又要保證系統(tǒng)的高吞吐性能?

?

上面拋出來了一些問題,我們接下來都會(huì)一一分析,一一思考解決方案;

?

對(duì)于上述問題,我們需要考慮整體的架構(gòu)設(shè)計(jì),因?yàn)閷?duì)于一個(gè)系統(tǒng)的健壯性,不能單單考慮一個(gè)點(diǎn),依賴于某個(gè)技術(shù)棧就能解決問題;

對(duì)于系統(tǒng)的健壯性,高可用,業(yè)務(wù)應(yīng)用集群部署是少不了的,通常來說,一般的互聯(lián)網(wǎng)項(xiàng)目,我們都是線上部署多個(gè)應(yīng)用集群,通過負(fù)載均衡規(guī)則,將流量均攤給各個(gè)服務(wù)。保證整體業(yè)務(wù)的高可用。這是一種思路,但是我們今天從另外一個(gè)角度來分析一下系統(tǒng)優(yōu)化。

很多后端程序員都會(huì)片面思考服務(wù)端如何優(yōu)化,怎么保證系統(tǒng)的健壯,但是我認(rèn)為這是不好的思維方式(雖然筆者側(cè)重后端開發(fā));作為一個(gè)優(yōu)秀的程序員,應(yīng)當(dāng)有全局設(shè)計(jì)的思考能力。

通常來說,我們一個(gè)B/S應(yīng)用結(jié)構(gòu),是由用戶電腦的瀏覽器發(fā)起請求,然后由統(tǒng)一網(wǎng)關(guān)接收,然后將其路由至對(duì)應(yīng)的服務(wù)應(yīng)用上處理,然后服務(wù)應(yīng)用訪問數(shù)據(jù)庫的數(shù)據(jù)。一個(gè)由上至下的層次訪問方式。(應(yīng)該不會(huì)有人問直接瀏覽器訪問數(shù)據(jù)庫吧?)畫個(gè)圖

?

很簡單的一個(gè)架構(gòu)方式,我們就需要對(duì)這圖上的各個(gè)節(jié)點(diǎn)進(jìn)行系統(tǒng)優(yōu)化思考

?

用戶的瀏覽器

對(duì)于頂層,直接和用戶打交道的,通常交互應(yīng)用是通過應(yīng)用客戶端,和瀏覽器網(wǎng)頁等形式,在這層上,我們通常都會(huì)有一定的處理邏輯。H5上會(huì)有js腳本,控制整個(gè)網(wǎng)頁的規(guī)則運(yùn)行,APP上通常有類似java等語言處理邏輯。我們都是通過這些邏輯再與服務(wù)器進(jìn)行交互請求,回調(diào)的。那么在此處,我們就需要限制用戶的無意或者惡意操作了。例如,用戶狂刷新商品,看看商品的最新庫存(本質(zhì)來說,這是很常見的用戶操作行為,但是在筆者看來,這無意義人工壓測了)。那么這種操作,我們就需要控制真正請求到后端的請求量了。如果客戶端是一個(gè)吃瓜群眾,用戶操作多少下,就請求多少下,那么這個(gè)客戶端開發(fā)就會(huì)被服務(wù)端打死。

我們會(huì)看到很多類似的場景,例如,一個(gè)下單按鈕,我們會(huì)在正常發(fā)起了一個(gè)下單請求后,當(dāng)服務(wù)端還未返回結(jié)果前,這個(gè)按鈕就是置灰的,不允許點(diǎn)擊的。這也是降頻操作。

但是對(duì)于一些操作場景,讀的場景,我們不可能說,用戶去刷新商品的庫存,一秒鐘只能刷新一次(至少不能讓用戶這樣感知),這個(gè)時(shí)候,我們就需要做一些特殊處理了。例如,采用客戶端本地緩存,舉例說明,對(duì)于某個(gè)商品的庫存數(shù)據(jù),客戶端采用緩存,緩存的過期時(shí)間為2s,當(dāng)緩存過期后,才再次真實(shí)的向服務(wù)端發(fā)起請求,那么原本用戶在10s中共刷新了200下商品緩存,那么這個(gè)時(shí)候,其實(shí)只會(huì)發(fā)起5個(gè)請求到服務(wù)端,原本需要200個(gè)請求,攔截了大量的惡意用戶操作請求。并且我們并不限制用戶的操作,提高的用戶的體驗(yàn)感。

平時(shí)我們也會(huì)看到很多搶購活動(dòng)中,明明有庫存啊,就是下單的時(shí)候,就告訴我,沒貨了。這其實(shí)就是緩存一致性問題導(dǎo)致的。這種問題都是我們故意制造出來的,因?yàn)樵谶@種業(yè)務(wù)場景下,我們是不太特別嚴(yán)格要求數(shù)據(jù)的一致性的。

?

網(wǎng)關(guān)

上面關(guān)于普通的用戶操作,我們是可以處理大部分的用戶的惡意操作的。但是在一個(gè)合格的程序員面前,我們所考慮的用戶并不都是那種"良好"操作習(xí)慣的用戶。對(duì)于系統(tǒng)安全來說,我們還需要考慮“同行”的行為。

我們的12306搶票軟件,都知道,我們很多人大多時(shí)候并不會(huì)真的在這個(gè)軟件平臺(tái)上進(jìn)行購票操作,因?yàn)楹芏鄷r(shí)候我們在上面看,基本上都是沒票。

那么這個(gè)時(shí)候就衍生出來了很多“同行”的產(chǎn)品,例如“智行12306”、“美團(tuán)搶票”等等,那么對(duì)于這種第三方平臺(tái)所制作出來的應(yīng)用,目的是什么?是為了保護(hù)"官方12306購票系統(tǒng)"嗎?當(dāng)然不是,他們的目的就是保證他們的付費(fèi)用戶能夠高效的購買的心意的票。那么這個(gè)時(shí)候,就是不是用戶與服務(wù)之間的較量了。這就是服務(wù)與服務(wù)之間的較量了。并且這種第三方應(yīng)用很多,這個(gè)時(shí)候又變成“多個(gè)打一個(gè)”了。你覺得"官方12306購票系統(tǒng)"難不難?這也是為什么早期"官方12306購票系統(tǒng)"上線的時(shí)候,直接崩了的原因了。

那么"官方12306購票系統(tǒng)"怎么處理呢?不管你還是“智行12306”、“美團(tuán)搶票”,你都需要登錄吧?不登錄,你還想搶票?當(dāng)游客嗎?那么這個(gè)時(shí)候,我們就可以有效的過濾一批請求了。我們的 12306賬戶都是實(shí)名制的,一個(gè)真實(shí)的合法公民只能有一個(gè)賬號(hào),綁定了我們的身份證,那么這個(gè)時(shí)候,我們就能確定一個(gè)用戶發(fā)起的所有請求是否只是一個(gè)用戶發(fā)起的,我們就可以針對(duì)這個(gè)用戶進(jìn)行精準(zhǔn)限流了,在用戶發(fā)起下單請求的時(shí)候,都需要攜帶用戶ID,那么這個(gè)時(shí)候,我們在站點(diǎn)層面就可以控制一個(gè)用戶ID只路由一個(gè)請求到后端中,其他請求,站點(diǎn)都可以拋棄,直接返回false了。這樣,同一個(gè)用戶不管1秒發(fā)起的10000個(gè)下單請求還是10個(gè)下單請求,只會(huì)有一個(gè)請求被放行。這樣即使有些用戶使用了第三方搶票軟件,我們也可以控制每個(gè)用戶之間的請求是公平的。

甚至我們還可以做一些惡意攻擊的處理方案,例如當(dāng)1s發(fā)起了1000個(gè)請求,將其用戶ID放入小黑屋待一段時(shí)間(布隆過濾器),或者將這個(gè)主機(jī)ip加進(jìn)去,這樣的話,就又控制了一批非人為操作發(fā)起的請求。

上面說的是寫請求,那么獲取請求呢?返回false?那這個(gè)時(shí)候也是不合理的,我們這個(gè)時(shí)候還是需要考慮緩存,站點(diǎn)層面的數(shù)據(jù)緩存,例如,用戶獲取當(dāng)前商品的庫存,這個(gè)時(shí)候,我們不以用戶ID作為緩存鍵,而是以用戶請求的商品的ID為緩存鍵,這樣,即使兩個(gè)不同的用戶發(fā)起的請求,我們也可以實(shí)現(xiàn)緩存共用了。當(dāng)用戶1查詢火車A的票余量的時(shí)候,生成的緩存,用戶2也去查詢火車B的票余量的時(shí)候,當(dāng)超出限額流量的時(shí)候,也返回這個(gè)緩存數(shù)據(jù),那么真實(shí)的請求就不會(huì)直接路由到業(yè)務(wù)服務(wù)上去。這也是一種保障用戶友好體驗(yàn)的行為了。如果我們直接拋“請求過快,請稍后再重試”,你煩嗎?我挺煩的。

對(duì)于此處,我們可以考慮“七層負(fù)載均衡”,通過nginx實(shí)現(xiàn)。如果想提高系統(tǒng)的吞吐率,我們可以使用增加節(jié)點(diǎn)方式,增加系統(tǒng)的吞吐率性能。

?

業(yè)務(wù)應(yīng)用

存在一種這樣的情況,服務(wù)已用戶的賬戶進(jìn)行限流,那么這個(gè)時(shí)候,如果我用1000個(gè)賬戶去搶票呢?其他用戶只能用自己的1個(gè)賬戶去搶票,那么我的搶票的成功的概率是不是相對(duì)高一些呢?那這個(gè)時(shí)候,系統(tǒng)的并發(fā)也會(huì)有1000,再結(jié)合真實(shí)的人為產(chǎn)生的并發(fā),也是有很高的并發(fā)量,那這個(gè)時(shí)候?qū)τ谙到y(tǒng)而言,怎么控制順序讀寫?

mysql官方宣稱寫操作,單機(jī)并發(fā)2000寫操作極限。再多就爆了。

那么redis官方宣稱單機(jī)并發(fā)80000寫操作,那這就可以解決很多流量問題了。

然后我們需要真實(shí)的控制可控的請求到數(shù)據(jù)庫層面,那么如何控制呢?也就是緩存限流。

票的余量有1000張,10000個(gè)請求如果全部請求到數(shù)據(jù)庫中?后面的9000個(gè)請求都直接返回票已賣光,這樣不就可以嗎?可以通過緩存記錄票余量,直接在緩存中操作數(shù)量的讀寫操作,對(duì)于緩存的數(shù)據(jù)我們采用異步入庫操作。定時(shí)將票的余量同步至數(shù)據(jù)庫中。這樣也保證了數(shù)據(jù)的持久性。 那么怎么控制買票的有序執(zhí)行呢?隊(duì)列,我們可以通過有序隊(duì)列,消費(fèi)下單請求,這樣也保護(hù)了數(shù)據(jù)庫的安全性。不使用隊(duì)列,直接通過一個(gè)狀態(tài)進(jìn)行記錄當(dāng)前售票的情況,當(dāng)我們記錄到第1100個(gè)請求后,就直接將“票是否售完”狀態(tài)變?yōu)閠rue,那么這個(gè)時(shí)候,后面的請求都直接返回“票已售光”,那么就降低了系統(tǒng)邏輯的處理負(fù)載。

當(dāng)然,對(duì)于業(yè)務(wù)應(yīng)用,我們可以通過產(chǎn)品規(guī)則去解決,通過一些案例去解決。

例如:分時(shí)段操作,將用戶從產(chǎn)品設(shè)計(jì)上進(jìn)行拆分,這也是一種分散流量的操作。

對(duì)于"用戶取消訂單"的這種操作,我們可以將緩存中的票的余量進(jìn)行重建,將票的余量+1,然后再將“票是否售完”狀態(tài)變?yōu)閒alse,這個(gè)時(shí)候我們會(huì)驚奇的發(fā)現(xiàn),過了1個(gè)小時(shí)了,突然發(fā)現(xiàn)又有票了,奇怪哈!

在雙十一的時(shí)候,淘寶也做了一個(gè)操作,就是“雙十一當(dāng)天禁止取消訂單”操作,只能通過攔截方式。這是屬于產(chǎn)品設(shè)計(jì)上進(jìn)行系統(tǒng)保護(hù)。

?

數(shù)據(jù)庫

從數(shù)據(jù)庫層面而言,我們只需要考慮幾點(diǎn):保證數(shù)據(jù)庫的可用性、保證數(shù)據(jù)的持久性、保證業(yè)務(wù)數(shù)據(jù)的正確性(不能賣票賣到還剩-10張吧?)

對(duì)于數(shù)據(jù)庫的特性而言,存在行鎖,多條請求,我們在多個(gè)請求的時(shí)候,當(dāng)一個(gè)請求在修改數(shù)據(jù)庫的數(shù)據(jù)的時(shí)候,就會(huì)出現(xiàn)排他鎖,其他操作都是阻塞的,那么我們?nèi)绻鉀Q呢?排他鎖,能夠保證業(yè)務(wù)的正常,事務(wù)的隔離性,數(shù)據(jù)的臟讀、幻讀、重復(fù)讀等異常情況,顯然,我們不能直接不用innodb,對(duì)于互聯(lián)網(wǎng)項(xiàng)目而言,讀多寫少,我們還是需要考慮事務(wù)問題,那么這個(gè)時(shí)候,我們就可以對(duì)數(shù)據(jù)進(jìn)行拆分了。當(dāng)票的余量的表的數(shù)據(jù)過大,我們可以考慮水平分表,分庫,通過地域進(jìn)行拆分。用售票規(guī)則而定,假如一張“杭州東” ~ “南昌西”的車次的票,我們可以將其放在“浙江庫的杭州表”中,那么杭州始發(fā)地的票的余額,我們都可以知道去哪里查詢,那么對(duì)于這趟車次的用戶假設(shè)也很多呢?我們怎么解決一條數(shù)據(jù)的并發(fā)寫操作呢?這里我們可以考慮將始發(fā)地進(jìn)行拆分。都知道,我們12306放票規(guī)則是根據(jù)始發(fā)地分配的。

“杭州東” ~ “南昌西”

會(huì)途徑 “金華”/"上饒" ,那么這個(gè)時(shí)候,我們假設(shè)這趟車一共有1000張票,那么“杭州東” 可以賣500張,“金華”可以賣 300張 “上饒”可以賣200張(當(dāng)然,賣火車票不是這么簡單的,我們需要考慮出發(fā)地,目的地,才能知道區(qū)間的票的購買余量,并且還需要控制始發(fā)地的放票量,才能給中間的站點(diǎn)買票數(shù)量)。那么這樣我們就可以將一個(gè)車次的票拆分為3條數(shù)據(jù),這樣,3條數(shù)據(jù)就便于我們寫操作了。

對(duì)于上述的業(yè)務(wù)而言,存在不嚴(yán)謹(jǐn)?shù)臄?shù)據(jù)假設(shè),此處也只是為了舉例思考。歡迎各位舉例批評(píng)。

?

?

總結(jié):

以上為個(gè)人通過個(gè)人學(xué)習(xí),網(wǎng)絡(luò)大佬的分享,總結(jié)的一些思考,希望各位bu she li jiao (沒打出來這個(gè)成語,尷尬了)

總結(jié)

以上是生活随笔為你收集整理的什么是“秒杀”?为什么传统项目中也有“秒杀”的概念?一起来分析一下.的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。