成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這一次,徹底弄懂“秒殺系統”

原創
開發 前端
說到“秒殺”,恐怕大多數人想到的就是“雙 11”,“促銷”,“買買買”等火爆的場面吧。

【51CTO.com原創稿件】說到“秒殺”,恐怕大多數人想到的就是“雙 11”,“促銷”,“買買買”等火爆的場面吧。

[[276668]]
圖片來自 Pexels 

大家為了打折商品蜂擁而至,造成電商網站一片繁華的景象。但作為程序員的我們,看到的卻是背后的高并發和可靠性。無論你處在軟件開發的哪個階段,都希望能夠設計一套屬于自己的秒殺系統。

今天我們一起來看看,一套秒殺系統在架構設計上需要有哪些考量:

  • 秒殺場景的特點
  • 系統隔離的設計思路
  • 客戶端設計
  • 代理層設計
  • 應用層設計
  • 數據庫設計
  • 壓力測試
  • 總結

秒殺場景的特點

秒殺場景是電商網站定期舉辦的活動,這個活動有明確的開始和結束時間,而且參與互動的商品是事先定義好了,參與秒殺商品的個數也是有限制的。同時會提供一個秒殺的入口,讓用戶通過這個入口進行搶購。

總結一下秒殺場景的特點:

  • 定時開始,秒殺時大量用戶會在同一時間,搶購同一商品,網站瞬時流量激增。
  • 庫存有限,秒殺下單數量遠遠大于庫存數量,只有少部分用戶能夠秒殺成功。
  • 操作可靠,秒殺業務流程比較簡單,一般就是下訂單減庫存。庫存就是用戶爭奪的“資源”,實際被消費的“資源”不能超過計劃要售出的“資源”,也就是不能被“超賣”。

系統隔離的設計思路

在分析秒殺的特點后,我們發現秒殺活動是有計劃的,并且在短時間內會爆發大量的請求。為了不影響現有的業務系統的正常運行,我們需要把它和現有的系統做隔離。

即使秒殺活動出現問題也不會影響現有的系統。隔離的設計思路可以從三個維度來思考。

  • 業務隔離
  • 技術隔離
  • 數據庫隔離

業務隔離

既然秒殺是一場活動,那它一定和常規的業務不同,我們可以把它當成一個單獨的項目來看。在活動開始之前,最好設計一個“熱場”。

“熱場”的形式多種多樣,例如:分享活動領優惠券,領秒殺名額等等。“熱場”的形式不重要,重要的是通過它獲取一些準備信息。

例如:有可能參與的用戶數,他們的地域分布,他們感興趣的商品。為后面的技術架構提供數據支持。

技術隔離

 

技術隔離架構圖

前面有了準備工作,那么從技術上需要有以下幾個方面的考慮:

  • 客戶端,前端秒殺頁面使用專門的頁面,這些頁面包括靜態的 HTML 和動態的 JS,他們都需要在 CDN 上緩存。
  • 接入層,加入過濾器專門處理秒殺請求,即使我們擴展再多的應用,使用再多的應用服務器,部署再多的負載均衡器,都會遇到支撐不住海量請求的時候。

所以,在這一層我們要考慮的是如何做好限流,當超過系統承受范圍的時候,需要果斷阻止請求的涌入。

  • 應用層,瞬時的海量請求好比請求的“高峰”,我們架構系統的目的就是“削峰”。

需要使用服務集群和水平擴展,讓“高峰”請求分流到不同的服務器進行處理。同時,還會利用緩存和隊列技術減輕應用處理的壓力,通過異步請求的方式做到最終一致性。

由于是多線程操作,而且商品的額度有限,為了解決超賣的問題,需要考慮進程鎖的問題。

數據庫隔離

秒殺活動持續時間短,瞬時數據量大。為了不影響現有數據庫的正常業務,可以建立新的庫或者表來處理。

在秒殺結束以后,需要把這部分數據同步到主業務系統中,或者查詢表中。如果數據量特別巨大,到千萬級別甚至上億,建議使用分表或者分庫。

客戶端設計

上面提到的三個隔離維度中,我們對技術維度是最為關心的。如果說瀏覽器/客戶端是用戶接觸“秒殺系統”的入口,那么在這一層提供緩存數據就是非常必要的。

在設計之初,我們會為秒殺的商品生成專門的商品頁面和訂單頁面。這些頁面以靜態的 HTML 為主,包括的動態信息盡量少。

從業務的角度來說,這些商品的信息早就被用戶熟識了,在秒殺的時候,他們關心的是如何快速下單。

既然商品的詳情頁面和訂單頁面都是靜態生成的,那么就需要定義一個 URL,當要開始秒殺之前,開放這個 URL 給用戶訪問。

為了防止“程序員或者內部人員”作弊,這里的地址可以通過時間戳和 Hash 算法來生成,也就是說這個地址只有系統知道,到了快秒殺之前才由系統發放出去。

有人說瀏覽器/客戶端如果存放的都是靜態頁面,那么“控制開始下單”的按鈕,以及發送“下單請求”的按鈕,也是靜態的嗎?

答案是否定的,其實靜態頁面是方便客戶端好緩存,下單的動作以及下單時間的控制還是在服務器端。

只不過是通過 JS 文件的方式發送給客戶端,在快要秒殺之前,會把這部分 JS 下載到客戶端。

因為,其業務邏輯很少,基本只包括時間,用戶信息,商品信息等等。所以,其對網絡的要求不高。

同時,在網絡設計上,我們也會將 JS 和 HTML 同時緩存在 CDN 上面,讓用戶從離自己最近的 CDN 服務器上獲取這些信息。

為了避免秒殺程序參與秒殺,在客戶端也會設計一些問答或者滑塊的功能,減少此類機器人對服務器的壓力。

 

秒殺系統前端設計簡圖

代理層設計

說完了秒殺系統的前端設計,請求自然地來到了代理層。由于用戶的請求量大,我們需要用負載均衡加上服務器集群,來面對如此空前的壓力。

 

代理層三大功能簡圖

在這一層是可以做緩存,過濾和限流的:

  • 緩存,以 Nginx 為例,它可以緩存用戶的信息。假設用戶信息的修改沒有那么頻繁,即使有類似的修改也可以通過更新服務來刷新。總比從服務器上獲取效率要高得多。
  • 過濾,既然緩存了用戶信息,這里就可以過濾掉一些不滿足條件的用戶。注意,這里的用戶信息的過濾和緩存只是一個例子。

主要想表達的意思是,可以將一些變化不頻繁的數據,提到代理層來緩存,提高響應的效率。

同時,還可以根據風控系統返回的信息,過濾一些疑似機器人或者惡意請求。例如:從固定 IP 過來的,頻率過高的請求。最重要的就是在這一層,可以識別來自秒殺系統的請求。

如果是帶有秒殺系統的參數,就要把請求路由到秒殺系統的服務器集群。這樣才能和正常的業務系統分割開來。

  • 限流,每個服務器集群能夠承受的壓力都是有限的。代理層可以根據服務器集群能夠承受的最大壓力,設置流量的閥值。

閥值的設置可以是動態調整的。例如:集群服務器中有 10 個服務器,其中一臺由于壓力過大掛掉了。

此時就需要調整代理層的流量閥值,將能夠處理的請求流量減少,保護后端的應用服務器。

當服務器恢復以后,又可以將閥值調回原位。可以通過 Nginx+Lua 合作完成,Lua 從服務注冊中心讀取服務健康狀態,動態調整流量。

應用層設計

“秒殺系統”秒殺的是什么?無非是商品。對于系統來說就是商品的庫存,購買的商品一旦超過了庫存就不能再賣了。

防止超賣

超過了庫存還可以賣給用戶,這就是“超賣”,也是系統設計需要避免的。為了承受大流量的訪問,我們用了水平擴展的服務,但是對于他們消費的資源“庫存”來說,卻只有一個。

為了提高效率,會將這個庫存信息放到緩存中。以流行的 Redis 為例,用它存放庫存信息,由多個線程來訪問就會出現資源爭奪的情況。也就是分布式程序爭奪唯一資源,為了解決這個問題我們需要實現分布式鎖。

假設這里有多個應用響應用戶的訂單請求,他們同時會去訪問 Redis 中存放的庫存信息,每接受用戶一次請求,都會從 Redis 的庫存中減去 1 個商品庫存量。

當任何一個進程訪問 Redis 中的庫存資源時,其他進程是不能訪問的,所以這里需要考慮鎖的情況(樂觀,悲觀)。

Redis 緩存承載庫存變量 

如果鎖長期沒有釋放,需要考慮鎖的過期時間,需要設置兩個超時時間:

  • 資源本身的超時時間,一旦資源被使用一段時間還沒有被釋放,Redis 會自動釋放掉該資源給其他服務使用。
  • 服務獲取資源的超時時間,一旦一個服務獲取資源一段時間后,不管該服務是否處理完這個資源,都需要釋放該資源給其他服務使用。

訂單處理流程

這里的“扣減服務”完成了最簡單的扣減庫存工作,并沒有和其他項目服務打交道,更沒有訪問數據庫。

 

訂單流程示意圖

后面的流程相對比較復雜,我們先看圖,根據圖示來講解:

  • 首先,扣減服務作為下單流程的入口,會先對商品的庫存做扣減。同樣它會檢查商品是否還有庫存?
  • 由于訂單對應的操作步驟比較多,為了讓流量變得平滑,這里使用隊列存放每個訂單請求,等待訂單處理服務完成具體業務。
  • 訂單處理服務實現多線程,或者水平擴展的服務陣列,它們不斷監聽隊列中的消息。一旦發現有新訂單請求,就取出訂單進行后續處理。

注意,這里可以加入類似 ZooKeeper 這樣的服務調度來幫助,協調服務調度和任務分配。

  • 訂單處理服務,處理完訂單以后會把結果寫到數據庫。寫數據庫是 IO 操作,耗時長。
  • 所以,在寫數據庫的同時,會把結果先寫入緩存中,這樣用戶是可以第一時間查詢自己是否下單成功了。
  • 結果寫入數據庫,這個操作有可能成功也有可能失敗。
  • 為了保證數據的最終一致性,我們用訂單結果同步的服務不斷的對比,緩存和數據庫中的訂單結果信息。

一旦發現不一致,會去做重試操作。如果重試依舊不成功,會重寫信息到緩存,讓用戶知道失敗原因。

  • 用戶下單以后,焦慮地刷新頁面查看下單的結果,實際上是讀到的緩存上的下單結果信息。

雖然,這個信息和最終結果有偏差,但是在秒殺的場景,要求高性能是前提,結果的一致性,可以后期補償。

數據庫設計

講完了秒殺的處理流程,來談談數據庫設計要注意的點。

數據估算

前面說了秒殺場景需要注意隔離,這里的隔離包括“業務隔離”。就是說我們在秒殺之前,需要通過業務的手段,例如:熱場活動,問卷調查,歷史數據分析。通過他們去估算這次秒殺可能需要存儲的數據量。

這里有兩部分的數據需要考慮:

  • 業務數據
  • 日志數據

前者不言而喻是給業務系統用的。后者,是用來分析和后續處理問題訂單用的,秒殺完畢以后還可以用來復盤。

分表分庫

對于這些數據的存放,需要分情況討論,例如,MySQL 單表推薦的存儲量是 500W 條記錄(經驗數字)。

如果估算的時候超過了這個數據,建議做分表。如果服務的連接數較多,建議進行分庫的操作。

數據隔離

由于大量的數據操作是插入,有少部分的修改操作。如果使用關系型數據來存儲,建議用專門的表來存放,不建議使用業務系統正在使用的表。

這個開頭提到了,數據隔離是必須的,一旦秒殺系統掛了,不會影響到正常業務系統,這個風險意識要有。表的設計除了 ID 以外,最好不要設置其他主鍵,保證能夠快速地插入。

數據合并

由于是用的專用表存儲,在秒殺活動完畢以后,需要將其和現有的數據做合并。其實,交易已經完成,合并的目的也就是查詢。

這個合并需要根據具體情況來分析,如果對于那些“只讀”的數據,對于做了讀寫分離的公司,可以導入到專門負責讀的數據庫或者 NoSQL 數據庫中。

壓力測試

構建了秒殺系統,一定會面臨上線,那么在上線之前壓力測試是必不可少的。

我們做壓力測試的目的是檢驗系統崩潰的邊緣在哪里?系統的極限在哪里?

這樣才能合理地設置流量的上限,為了保證系統的穩定性,多余的流量需要被拋棄。

壓力測試的方法

合理的測試方法可以幫助我們對系統有深入的了解,這里介紹兩種壓力測試的方法:

  • 正壓力測試
  • 負壓力測試

正壓力測試。每次秒殺活動都會計劃,使用多少服務器資源,承受多少的請求量。

可以在這個請求量上面不斷加壓,直到系統接近崩潰或者真正崩潰。簡單的說就是做加法。

 

正壓力測試示意圖

負壓力測試。在系統正常運行的情況下,逐步減少支撐系統的資源(服務器),看什么時候系統無法支撐正常的業務請求。

例如:在系統正常運行的情況下,逐步減少服務器或者微服務的數量,觀察業務請求的情況。說白了就是做減法。

 

負壓力測試示意圖

壓力測試的步驟

 

測試步驟

有了測試方法的加持,我們來看看需要遵循哪些測試步驟。下面的操作偏套路化,大家在其他系統的壓力測試也可以這么做,給大家做個參考。

第一,確定測試目標。與性能測試不同的是,壓力測試的目標是,什么時候系統會接近崩潰。比如:需要支撐 500W 訪問量。

第二,確定關鍵功能。壓力測試其實是有重點的,根據 2/8 原則,系統中 20% 的功能被使用的是最多的,我們可以針對這些核心功能進行壓力測試。例如:下單,庫存扣減。

 

關注核心服務

第三,確定負載。這個和關鍵服務的思路一致,不是每個服務都有高負載的,我們的測試其實是要關注那些負載量大的服務,或者是一段時間內系統中某些服務的負載有波動。這些都是測試目標。

第四,選擇環境,建議搭建和生產環境一模一樣的環境進行測試。

第五,確定監視點,實際上就是對關注的參數進行監視,例如 CPU 負載,內存使用率,系統吞吐量等等。

第六,產生負載,這里需要從生產環境去獲取一些真實的數據作為負載數據源,這部分數據源根據目標系統的承受要求由腳本驅動,對系統進行沖擊。

建議使用往期秒殺系統的數據,或者實際生產系統的數據進行測試。

第七,執行測試,這里主要是根據目標系統,關鍵組件,用負載進行測試,返回監視點的數據。

建議團隊可以對測試定一個計劃,模擬不同的網絡環境,硬件條件進行有規律的測試。

第八,分析數據,針對測試的目的,對關鍵服務的壓力測試數據進行分析得知該服務的承受上限在哪里。

對一段時間內有負載波動或者大負載的服務進行數據分析,得出服務改造的方向。

總結

秒殺系統的特點,并發量大,資源有限,操作相對簡單,訪問的都是熱點數據。因此,我們需要把它從業務,技術,數據上做隔離,保證不影響到現有的系統。

因此,架構設計需要分幾層來考慮,從客戶請求到數據庫存儲,到最后上線前的壓力測試。

 

簡易的思維導圖送給大家

思考順序如下,客戶端→代理層→應用層→數據庫→壓力測試:

客戶端 90% 靜態 HTML+10% 動態 JS;配合 CDN 做好緩存工作。

接入層專注于過濾和限流。

應用層利用緩存+隊列+分布式處理好訂單。

做好數據的預估,隔離,合并。

上線之前記得進行壓力測試。

作者:崔皓

簡介:十六年開發和架構經驗,曾擔任過惠普武漢交付中心技術專家,需求分析師,項目經理,后在創業公司擔任技術/產品經理。善于學習,樂于分享。目前專注于技術架構與研發管理。

【51CTO原創稿件,合作站點轉載請注明原文作者和出處為51CTO.com】

 

責任編輯:武曉燕 來源: 51CTO技術棧
相關推薦

2019-11-08 16:05:54

Promise前端鏈式調用

2018-08-07 14:45:52

編程語言JavaScripthtml

2024-05-15 10:14:00

CRDT數據類型協同編輯

2024-03-11 08:47:30

CRDT數據類型協同編輯

2021-07-03 08:59:49

動態代理JDK

2021-08-29 08:14:30

GPU CSS gpu

2019-06-05 13:00:00

2016-03-31 17:01:26

桂林甲天下

2018-07-23 16:13:27

Google歐盟Android

2024-05-20 00:00:00

代碼主線程

2019-11-05 11:17:11

Java虛擬機技術Java 堆

2025-04-09 10:36:32

2024-10-09 12:05:27

2014-07-18 17:14:16

小米蘋果雷軍

2016-01-06 11:15:03

VR

2019-04-12 11:25:24

華為

2016-11-08 07:58:02

樂視難關科技新聞早報

2021-03-11 12:15:37

Kubernetes云原生容器

2021-04-28 09:55:52

JavaLock接口并發編程

2020-08-13 07:04:45

跨域CORS瀏覽器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久久一区二区三区 | wwww.8888久久爱站网 | 嫩草网| 欧美高清一区 | 中文字幕乱码一区二区三区 | 欧美成人精品二区三区99精品 | 日韩在线视频观看 | 日韩亚洲一区二区 | 日韩伦理一区二区 | 91精品国产日韩91久久久久久 | 天天草视频| 亚洲欧美在线视频 | 亚洲精品一区国产精品 | 91精品国产91久久综合桃花 | 中文字幕精品一区 | 国产精品亚洲视频 | 日本久久一区二区三区 | 亚洲欧美久久 | 欧美4p| 九九热在线免费视频 | 国产成人高清视频 | 中国一级特黄真人毛片 | 97人人干| 久草精品在线 | 久久亚洲一区二区 | 伊人网综合 | 91免费版在线观看 | 婷婷99| 久久久久久久国产 | 综合色站导航 | 日韩成人免费视频 | 亚洲精品一区在线 | 免费成人高清在线视频 | 国产成人在线视频免费观看 | 国产精品欧美一区二区三区不卡 | ww 255hh 在线观看| 北条麻妃国产九九九精品小说 | 成人免费毛片在线观看 | 日本在线网址 | 国产在线a视频 | 99久久婷婷 |