程序员过关斩将--搞定秒杀,只需要这几步!!
靈魂拷問
秒殺這種大并發的寫場景,直接分庫分表開干?
應對秒殺活動的流量高峰很難嗎?
不要拿淘寶級別的秒殺忽悠我
秒殺活動特點
我敢說凡是做過電商的同學,都會遇到運營展開的秒殺,限時購等“高并發”的活動。市面上也有不少針對秒殺的解決方案,什么分庫分表,緩存,消息隊列呀,但凡能想到的技術“靚點”都基本會寫上一段。我覺得應對秒殺這樣的帶有流量峰值的業務,還是要仔細分析業務的特性,以及根據自己系統的業務量來確定需要采用哪些技術“靚點”,假如:一個日活10萬的系統,采用了分庫分表,緩存,消息隊列,限流,降級等等技術手段,雖然功能上達到了預期,但是其實資源上可能會有些浪費,技術上也許只需要一個限流手段就足夠了。說這些不是想表達什么,我只是想說,那些上來就分庫分表等“大手筆”的“優化”手段一定要根據實際業務去考察是否需要實施。
言歸正傳,秒殺這種業務場景其實特點很明顯:
帶有短期流量峰值特性,即:短時間內會有大量的請求涌入
請求的數據帶有熱點性,即:大量的請求同一數據
請求的成功有效率低,即:大量的請求中可能只有少量請求會成功處理業務
請求的流量峰值發生在下單之前,即:付款階段很少存在流量峰值
靜態資源
靜態資源是指商品的圖片,視頻,音頻,html頁面等幾乎不會變化的資源,這些資源的處理方式和緩存類似,盡量放在離用戶最近的地方,比如:瀏覽器的本地緩存,當緩存過期的時候,優先推薦從CDN中獲取,CDN是應對靜態資源訪問高峰的最簡單粗暴,也是最有效的解決方案,如果沒有CDN怎么辦?那最少要把請求這些靜態資源的服務器和后臺業務服務器物理上分離,避免因為靜態資源而影響正常的業務。比如:很早之前,我就喜歡每個項目單獨一個存放圖片,css,js的網站,這個網站的優勢是無狀態,可以做到傻瓜式橫向擴展。
至于靜態資源的緩存更新,我想你可以百度一下會有很多答案。
業務讓步
如果負責秒殺活動的產品經理是一個優秀的產品經理的話,就不會設計出:用戶點擊秒殺馬上給予是否下單成功,這樣的系統。熟悉分布式的同學肯定會想到,想保證這樣的數據一致性,在可用性上必然會有所犧牲。尤其是秒殺這樣的業務,我覺得可用性要比一致性優先級要高,所以幾乎所有的秒殺系統都會采用BASE理論來設計系統,一致性上采用最終一致性。在用戶看來,點擊秒殺按鈕之后會彈出一個等待的提示,在技術上我們稱之為:異步處理。異步處理對于用戶最明顯的感知就是不會馬上得到結果,而是要等待一段時間。其實這樣的設計也是在技術和業務之間的一個權衡,算是業務作出的讓步。
至于秒殺之前需要輸入驗證碼或者某些題的答案等手段,其實也可以算是業務上作出的一些讓步。為什么說是讓步呢?對于用戶來說,最理想的秒殺場景是:一點秒殺按鈕,馬上給予結果,但是技術上難度太大了,所以嘛,互相讓一步,大家都好過,對不對?
技術第一招:限流
對于秒殺出現的流量峰值,限流是最直接的削峰手段,被限制的請求可以直接返回,客戶端提示請求中提示。可想而知,當10000/S的請求量被削成100/S的量,估計系統稍微優化一下就能抗住,至于限流的策略根據業務會有很多不同的方式,比如:
針對同一個用戶的請求次數限流,例如:每個用戶每10秒只允許請求一次
針對同一個IP的請求次數限流,例如:每個IP每10秒只允許請求一次
至于限流的算法,之前寫過一篇文章來介紹,而且性能還不錯哦
高并發優雅的做限流
第二招:消息隊列
說到消息隊列,每個程序員都不陌生,它相當于一個快速的數據容器,可以作為一個緩沖層來應對流量高峰。如果從它的使用場景上來看,它可以算是低速設備和高速設備之間的平衡者,使用消息隊列來進行削峰是一個很明顯的異步流程。
應用到秒殺的場景下,大量的請求會先進入消息隊列,它不僅削平了流量的峰值,而且把秒殺下單的這個流程異步化,只要把請求都暫存入隊列,消費端慢慢消費即可,但是這里要注意,如果消費的速度遠遠慢于消息的投遞速度,可能會影響整個系統性能。
除了削峰之外,我始終認為消息隊列的最大作用是系統解耦,它把下單和支付解耦,下單和支付業務可以隨著自身系統的承載量來單獨擴容。
第三招:緩存
為什么要加入緩存這個選項呢?別忘了,除了大量的用戶下單這個寫操作之外,還有更大量的用戶請求下單結果這個讀操作。當用戶點擊秒殺按鈕之后,系統會彈出等待的提示框,很多系統是不停的去輪訓用戶的下單結果,我之前也寫過緩存的文章,曾經提到過緩存最大的作用是提供讀操作的快速響應。整個秒殺系統可以這樣做:
用戶點擊下單按鈕,請求經過限流組件,如果成功,則進入下單環節(這里可以進入消息隊列,異步下單)
服務端無論是采用redis緩存,還是其他緩存組件,存放著下單成功的用戶信息(也可以包括訂單信息)
客戶端采用輪訓的方式去查詢緩存,如果查詢到信息說明下單成功,進入支付環節,未查詢到則說明下單還未成功
服務端下單成功,往緩存中寫入數據,當用戶下次再次查詢的時候會提示下單成功。
雖然過程很簡單,但是其實整個過程中有很多細節需要注意,比如:緩存的過期時間怎么設置?能否引入下單中的狀態?怎么保證緩存數據和數據庫數據的一致性?
談了千百遍的緩存數據的一致性問題
除了以上的信息數據緩存,商品的信息數據也可以放在緩存中,由于讀的請求量比較大,可以考慮采用緩存副本的方式來提高整體的吞吐量。
寫在最后
其實很多系統應用上消息隊列+限流之后,針對秒殺業務已經足夠了,其余的分庫分表等方案可以根據自己的業務量來確定。每個系統在滿足功能性的需求下,也在滿足非功能性需求的前提下越簡單越好,不是每個系統都需要淘寶的架構。
END
更多精彩文章
????分布式大并發系列
????架構設計系列
????趣學算法和數據結構系列
????設計模式系列
總結
以上是生活随笔為你收集整理的程序员过关斩将--搞定秒杀,只需要这几步!!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打爆你的 CPU
- 下一篇: 那些鼓吹国内首个.NET 5框架的,该醒