国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

超詳細(xì)的秒殺架構(gòu)設(shè)計,運(yùn)維,了解一下

新聞 架構(gòu)
我們?nèi)绾卧O(shè)計一個秒殺系統(tǒng)呢?對于秒殺系統(tǒng)應(yīng)該考慮哪些問題?如何設(shè)計出健壯的秒殺系統(tǒng)?本文我們就來探討一下這個問題。

 [[431486]]

秒殺系統(tǒng)相信很多人見過,比如京東或者淘寶的秒殺,小米手機(jī)的秒殺,那么秒殺系統(tǒng)的后臺是如何實(shí)現(xiàn)的呢?我們?nèi)绾卧O(shè)計一個秒殺系統(tǒng)呢?對于秒殺系統(tǒng)應(yīng)該考慮哪些問題?如何設(shè)計出健壯的秒殺系統(tǒng)?本文我們就來探討一下這個問題。

秒殺應(yīng)該考慮哪些問題

超賣問題

分析秒殺的業(yè)務(wù)場景,最重要的有一點(diǎn)就是超賣問題,假如備貨只有100個,但是最終超賣了200,一般來講秒殺系統(tǒng)的價格都比較低,如果超賣將嚴(yán)重影響公司的財產(chǎn)利益,因此首當(dāng)其沖的就是解決商品的超賣問題。

高并發(fā)

秒殺具有時間短、并發(fā)量大的特點(diǎn),秒殺持續(xù)時間只有幾分鐘,而一般公司都為了制造轟動效應(yīng),會以極低的價格來吸引用戶,因此參與搶購的用戶會非常的多。短時間內(nèi)會有大量請求涌進(jìn)來,后端如何防止并發(fā)過高造成緩存擊穿或者失效,擊垮數(shù)據(jù)庫都是需要考慮的問題。

接口防刷

現(xiàn)在的秒殺大多都會出來針對秒殺對應(yīng)的軟件,這類軟件會模擬不斷向后臺服務(wù)器發(fā)起請求,一秒幾百次都是很常見的,如何防止這類軟件的重復(fù)無效請求,防止不斷發(fā)起的請求也是需要我們針對性考慮的。

秒殺 URL

對于普通用戶來講,看到的只是一個比較簡單的秒殺頁面,在未達(dá)到規(guī)定時間,秒殺按鈕是灰色的,一旦到達(dá)規(guī)定時間,灰色按鈕變成可點(diǎn)擊狀態(tài)。這部分是針對小白用戶的,如果是稍微有點(diǎn)電腦功底的用戶,會通過F12看瀏覽器的network看到秒殺的url,通過特定軟件去請求也可以實(shí)現(xiàn)秒殺。或者提前知道秒殺url的人,一請求就直接實(shí)現(xiàn)秒殺了。這個問題我們需要考慮解決。

數(shù)據(jù)庫設(shè)計

秒殺有把我們服務(wù)器擊垮的風(fēng)險,如果讓它與我們的其他業(yè)務(wù)使用在同一個數(shù)據(jù)庫中,耦合在一起,就很有可能牽連和影響其他的業(yè)務(wù)。如何防止這類問題發(fā)生,就算秒殺發(fā)生了宕機(jī)、服務(wù)器卡死問題,也應(yīng)該讓他盡量不影響線上正常進(jìn)行的業(yè)務(wù)。

大量請求問題

按照「高并發(fā)」的考慮,就算使用緩存還是不足以應(yīng)對短時間的高并發(fā)的流量的沖擊。如何承載這樣巨大的訪問量,同時提供穩(wěn)定低時延的服務(wù)保證,是需要面對的一大挑戰(zhàn)。我們來算一筆賬,假如使用的是 Redis 緩存,單臺 Redis 服務(wù)器可承受的 QPS 大概是 4W 左右,如果一個秒殺吸引的用戶量足夠多的話,單 QPS 可能達(dá)到幾十萬,單體 Redis 還是不足以支撐如此巨大的請求量。緩存會被擊穿,直接滲透到 DB,從而擊垮MySQL,后臺會將會大量報錯。

秒殺系統(tǒng)的設(shè)計和技術(shù)方案

秒殺系統(tǒng)數(shù)據(jù)庫設(shè)計

針對「數(shù)據(jù)庫設(shè)計」提出的秒殺數(shù)據(jù)庫的問題,因此應(yīng)該單獨(dú)設(shè)計一個秒殺數(shù)據(jù)庫,防止因?yàn)槊霘⒒顒拥母卟l(fā)訪問拖垮整個網(wǎng)站。這里只需要兩張表,一張是秒殺訂單表,一張是秒殺貨品表。

其實(shí)應(yīng)該還有幾張表,商品表:可以關(guān)聯(lián)goods_id查到具體的商品信息,商品圖像、名稱、平時價格、秒殺價格等,還有用戶表:根據(jù)用戶user_id可以查詢到用戶昵稱、用戶手機(jī)號,收貨地址等其他額外信息,這個具體就不給出實(shí)例了。

秒殺 URL 的設(shè)計

為了避免有程序訪問經(jīng)驗(yàn)的人通過下單頁面url直接訪問后臺接口來秒殺貨品,我們需要將秒殺的 URL 實(shí)現(xiàn)動態(tài)化,即使是開發(fā)整個系統(tǒng)的人都無法在秒殺開始前知道秒殺的URL 。具體的做法就是通過 md5 加密一串隨機(jī)字符作為秒殺的 URL,然后前端訪問后臺獲取具體的 URL,后臺校驗(yàn)通過之后才可以繼續(xù)秒殺。

秒殺頁面靜態(tài)化

將商品的描述、參數(shù)、成交記錄、圖像、評價等全部寫入到一個靜態(tài)頁面,用戶請求不需要通過訪問后端服務(wù)器,不需要經(jīng)過數(shù)據(jù)庫,直接在前臺客戶端生成,這樣可以最大可能的減少服務(wù)器的壓力。具體的方法可以使用freemarker模板技術(shù),建立網(wǎng)頁模板,填充數(shù)據(jù),然后渲染網(wǎng)頁。

單體 Redis 升級為集群 Redis

秒殺是一個讀多寫少的場景,使用 Redis 做緩存再合適不過。不過考慮到緩存擊穿問題,我們應(yīng)該構(gòu)建 Redis 集群,采用哨兵模式,可以提升Redis的性能和可用性。

使用 Nginx

Nginx 是一個高性能 Web 服務(wù)器,它的并發(fā)能力可以達(dá)到幾萬,而 Tomcat 只有幾百。通過 Nginx 映射客戶端請求,再分發(fā)到后臺 Tomcat 服務(wù)器集群中可以大大提升并發(fā)能力。

精簡 SQL

典型的一個場景是在進(jìn)行扣減庫存的時候,傳統(tǒng)的做法是先查詢庫存,再去update。這樣的話需要兩個SQL,而實(shí)際上一個SQL我們就可以完成的。可以用這樣的做法:update miaosha_goods set stock =stock-1 where goos_id ={#goods_id} and version = #{version} and sock>0;這樣的話,就可以保證庫存不會超賣并且一次更新庫存,還有注意一點(diǎn)這里使用了版本號的樂觀鎖,相比較悲觀鎖,它的性能較好。

Redis 預(yù)減庫存

很多請求進(jìn)來,都需要后臺查詢庫存,這是一個頻繁讀的場景。可以使用Redis來預(yù)減庫存,在秒殺開始前可以在 Redis 設(shè)值,比如 redis.set(goodsId,100),這里預(yù)放的庫存為100可以設(shè)值為常量,每次下單成功之后,Integer stock = (Integer)redis.get(goosId); 然后判斷 sock 的值,如果小于常量值就減去1;不過注意當(dāng)取消的時候,需要增加庫存,增加庫存的時候也得注意不能大于之間設(shè)定的總庫存數(shù)(查詢庫存和扣減庫存需要原子操作,此時可以借助 lua 腳本)下次下單再獲取庫存的時候,直接從Redis里面查就可以了。

接口限流

秒殺最終的本質(zhì)是數(shù)據(jù)庫的更新,但是有很多大量無效的請求,我們最終要做的就是如何把這些無效的請求過濾掉,防止?jié)B透到數(shù)據(jù)庫。限流的話,需要入手的方面很多:

前端限流

首先第一步就是通過前端限流,用戶在秒殺按鈕點(diǎn)擊以后發(fā)起請求,那么在接下來的5秒是無法點(diǎn)擊(通過設(shè)置按鈕為disable)。這一小舉措開發(fā)起來成本很小,但是很有效。

同一個用戶xx秒內(nèi)重復(fù)請求直接拒絕

具體多少秒需要根據(jù)實(shí)際業(yè)務(wù)和秒殺的人數(shù)而定,一般限定為10秒。具體的做法就是通過Redis的鍵過期策略,首先對每個請求都從 String value = redis.get(userId);如果獲取到這個 value 為空或者為 null,表示它是有效的請求,然后放行這個請求。如果不為空表示它是重復(fù)性請求,直接丟掉這個請求。如果有效,采用redis.setexpire(userId,value,10).value 可以是任意值,一般放業(yè)務(wù)屬性比較好,這個是設(shè)置以 userId 為 key,10秒的過期時間(10秒后,key對應(yīng)的值自動為null)。

令牌桶算法限流

接口限流的策略有很多,我們這里采用令牌桶算法。令牌桶算法的基本思路是每個請求嘗試獲取一個令牌,后端只處理持有令牌的請求,生產(chǎn)令牌的速度和效率我們都可以自己限定,Guava 提供了 RateLimter 的 API 供我們使用。以下做一個簡單的例子,注意需要引入Guava:

  1. public class TestRateLimiter { 
  2.  
  3.     public static void main(String[] args) { 
  4.         //1秒產(chǎn)生1個令牌 
  5.         final RateLimiter rateLimiter = RateLimiter.create(1); 
  6.         for (int i = 0; i < 10; i++) { 
  7.             //該方法會阻塞線程,直到令牌桶中能取到令牌為止才繼續(xù)向下執(zhí)行。 
  8.             double waitTime= rateLimiter.acquire(); 
  9.             System.out.println("任務(wù)執(zhí)行" + i + "等待時間" + waitTime); 
  10.         } 
  11.         System.out.println("執(zhí)行結(jié)束"); 
  12.     } 

上面代碼的思路就是通過RateLimiter來限定我們的令牌桶每秒產(chǎn)生1個令牌(生產(chǎn)的效率比較低),循環(huán)10次去執(zhí)行任務(wù)。acquire會阻塞當(dāng)前線程直到獲取到令牌,也就是如果任務(wù)沒有獲取到令牌,會一直等待。那么請求就會卡在我們限定的時間內(nèi)才可以繼續(xù)往下走,這個方法返回的是線程具體等待的時間。執(zhí)行如下:

可以看到任務(wù)執(zhí)行的過程中,第1個是無需等待的,因?yàn)橐呀?jīng)在開始的第1秒生產(chǎn)出了令牌。接下來的任務(wù)請求就必須等到令牌桶產(chǎn)生了令牌才可以繼續(xù)往下執(zhí)行。如果沒有獲取到就會阻塞(有一個停頓的過程)。不過這個方式不太好,因?yàn)橛脩羧绻诳蛻舳苏埱螅绻^多的話,直接后臺在生產(chǎn)token就會卡頓(用戶體驗(yàn)較差),它是不會拋棄任務(wù)的,我們需要一個更優(yōu)秀的策略:如果超過某個時間沒有獲取到,直接拒絕該任務(wù)。接下來再來個案例:

  1. public class TestRateLimiter2 { 
  2.  
  3.     public static void main(String[] args) { 
  4.         final RateLimiter rateLimiter = RateLimiter.create(1); 
  5.  
  6.         for (int i = 0; i < 10; i++) { 
  7.             long timeOut = (long0.5
  8.             boolean isValid = rateLimiter.tryAcquire(timeOut, TimeUnit.SECONDS); 
  9.             System.out.println("任務(wù)" + i + "執(zhí)行是否有效:" + isValid); 
  10.             if (!isValid) { 
  11.                 continue
  12.             } 
  13.             System.out.println("任務(wù)" + i + "在執(zhí)行"); 
  14.         } 
  15.         System.out.println("結(jié)束"); 
  16.     } 

其中用到了tryAcquire方法,這個方法的主要作用是設(shè)定一個超時的時間,如果在指定的時間內(nèi)預(yù)估(注意是預(yù)估并不會真實(shí)的等待),如果能拿到令牌就返回true,如果拿不到就返回false。然后我們讓無效的直接跳過,這里設(shè)定每秒生產(chǎn)1個令牌,讓每個任務(wù)嘗試在0.5秒獲取令牌,如果獲取不到,就直接跳過這個任務(wù)(放在秒殺環(huán)境里就是直接拋棄這個請求)。程序?qū)嶋H運(yùn)行如下:

只有第1個獲取到了令牌,順利執(zhí)行了,下面的基本都直接拋棄了,因?yàn)?.5秒內(nèi),令牌桶(1秒1個)來不及生產(chǎn)就肯定獲取不到返回false了。

這個限流策略的效率有多高呢?假如我們的并發(fā)請求是400萬瞬間的請求,將令牌產(chǎn)生的效率設(shè)為每秒20個,每次嘗試獲取令牌的時間是0.05秒,那么最終測試下來的結(jié)果是,每次只會放行4個左右的請求,大量的請求會被拒絕,這就是令牌桶算法的優(yōu)秀之處。

異步下單

為了提升下單的效率,并且防止下單服務(wù)的失敗。需要將下單這一操作進(jìn)行異步處理。最常采用的辦法是使用隊(duì)列,隊(duì)列最顯著的三個優(yōu)點(diǎn):異步、削峰、解耦。這里可以采用 RabbitMQ,在后臺經(jīng)過了限流、庫存校驗(yàn)之后,流入到這一步驟的就是有效請求。然后發(fā)送到隊(duì)列里,隊(duì)列接受消息,異步下單。下完單,入庫沒有問題可以用短信通知用戶秒殺成功。假如失敗的話,可以采用補(bǔ)償機(jī)制,重試。

服務(wù)降級

假如在秒殺過程中出現(xiàn)了某個服務(wù)器宕機(jī),或者服務(wù)不可用,應(yīng)該做好后備工作。之前的博客里有介紹通過Hystrix進(jìn)行服務(wù)熔斷和降級,可以開發(fā)一個備用服務(wù),假如服務(wù)器真的宕機(jī)了,直接給用戶一個友好的提示返回,而不是直接卡死,服務(wù)器錯誤等生硬的反饋。

總結(jié) 

 

 

秒殺流程圖:

 

 

 

這就是我設(shè)計出來的秒殺流程圖,當(dāng)然不同的秒殺體量針對的技術(shù)選型都不一樣,這個流程可以支撐起幾十萬的流量,如果是成千萬破億那就得重新設(shè)計了。比如數(shù)據(jù)庫的分庫分表、隊(duì)列改成用Kafka、Redis增加集群數(shù)量等手段。通過本次設(shè)計主要是要表明的是我們?nèi)绾螒?yīng)對高并發(fā)的處理,并開始嘗試解決它,在工作中多思考、多動手能提升我們的能力水平,加油!如果本篇博客有任何錯誤,請麻煩指出來,不勝感激。

【編輯推薦】

【責(zé)任編輯:張燕妮 TEL:(010)68476606】

 

 

責(zé)任編輯:張燕妮 來源: 高效運(yùn)維
相關(guān)推薦

2021-03-26 09:49:11

運(yùn)維架構(gòu)技術(shù)

2021-07-27 11:31:29

運(yùn)維架構(gòu)技術(shù)

2018-03-21 09:08:06

超融合架構(gòu)本質(zhì)

2022-03-11 21:35:57

Java程序線程

2016-06-14 10:03:45

運(yùn)維 架構(gòu)

2021-11-19 10:25:23

MySQL數(shù)據(jù)庫架構(gòu)

2021-08-12 10:05:06

MySQL數(shù)據(jù)庫MySQL

2018-11-13 12:13:56

運(yùn)維災(zāi)備硬盤

2018-03-18 08:28:04

數(shù)據(jù)中心運(yùn)維組織架構(gòu)數(shù)據(jù)中心

2021-01-21 10:23:43

數(shù)據(jù)庫架構(gòu)技術(shù)

2018-10-24 05:14:11

2020-02-10 14:26:10

GitHub代碼倉庫

2023-10-23 10:20:25

2018-10-15 05:42:52

超參數(shù)搜索深度學(xué)習(xí)數(shù)據(jù)科學(xué)

2020-12-10 08:44:35

WebSocket輪詢Comet

2022-03-24 13:36:18

Java悲觀鎖樂觀鎖

2015-07-13 10:06:11

超融合基礎(chǔ)架構(gòu)運(yùn)維數(shù)據(jù)中心

2022-05-17 07:51:21

架構(gòu)設(shè)計運(yùn)維業(yè)務(wù)系統(tǒng)

2022-12-25 18:58:53

架構(gòu)RabbitMQ

2020-04-21 13:50:48

Wi-Fi 6無線華為
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

午夜精品一区在线观看| 韩国在线视频一区| 国产成人一级电影| 91精品久久久久久久久久久久久 | 538在线观看| 国产精品最新| 日韩在线观看免费全| 成人av激情人伦小说| 国产成人综合久久| 黑人一区二区三区四区五区| 欧美日韩精品久久久免费观看| 久久精品国产77777蜜臀| 全黄性性激高免费视频| 亚洲第一av色| 欧美伦理91| 国产激情视频一区| 韩国av一区二区三区| 黄色污网站在线免费观看| 亚洲国产古装精品网站| 先锋影音国产精品| 日韩精品一区二区三区| 欧美大片第1页| 亚洲综合欧美| 欧美日本网站| 亚洲精品中文在线| 在线播放三级网站| 国产一区成人| 18禁免费无码无遮挡不卡网站| 国产精品国产精品| 久久激情婷婷| 黑人粗进入欧美aaaaa| 欧美日韩一区二区三区视频| 91精品尤物| 日本丰满大乳奶| 日本韩国欧美在线| 奇米狠狠一区二区三区| 欧美 国产 综合| 精品国产一区二区三区免费| 国产精品v亚洲精品v日韩精品| 国产精品美女无圣光视频| 欧洲杯什么时候开赛| 久久久99精品视频| 欧洲grand老妇人| 日韩在线免费高清视频| 国产主播福利在线| 亚洲女子a中天字幕| 亚洲一卡二卡三卡四卡无卡网站在线看| 久久影院一区二区三区| 精品国产电影一区二区| 成年人免费在线视频| 一区视频在线播放| 日韩一区二区三区不卡视频| 日韩高清中文字幕一区| 91精品黄色| 欧美在线网站| 91国内精品久久| 不卡av播放| 欧美日韩国产第一页| 国产精品日本一区二区不卡视频| 亚洲黄色有码视频| 日本aa在线| 亚洲成人1234| 美女搞黄视频在线观看| 久久精品91久久久久久再现| 婷婷综合六月| 亚洲片在线观看| 超碰aⅴ人人做人人爽欧美| 日韩中文字幕久久| 精品亚洲成人| av资源站久久亚洲| 欧美wwwwww| 国产成人在线一区二区| 免费视频亚洲| 国产v亚洲v天堂无码| 国产精品资源在线观看| 国产真人无码作爱视频免费| 亚洲国产精品t66y| 三级做a全过程在线观看| 精品国产乱码久久久久久蜜臀| 春暖花开亚洲一区二区三区| 日韩最新中文字幕电影免费看| 欧美成人毛片| 久久久久久久久电影| 国产乱码精品一区二区亚洲| 亚洲成人一区二区三区| 亚洲国产精品99久久久久久久久| 黄网在线观看| 亚洲缚视频在线观看| 国产欧美自拍一区| 婷婷免费在线视频| 色综合久久久久综合体| 国产一级成人av| 成人羞羞国产免费网站| 在线视频精品一| 久国产精品韩国三级视频| 大地资源网3页在线观看| 国产在线一区二| 欧美亚洲国产一区在线观看网站 | 红桃一区二区三区| 日韩一区二区精品| 午夜在线播放视频欧美| 18视频在线观看| 在线精品日韩| 中文字幕日韩在线观看| 丰满放荡岳乱妇91ww| 亚洲国产天堂| 最近中文字幕一区二区| 蜜臀久久99精品久久久无需会员| 久久久久一区二区三区四区| 中文无码日韩欧| 日韩欧美亚洲一区| 91久久精品一区二区别| 在线不卡免费av| 久久99国产精品成人| 三级成人在线| 能在线观看的av网站| 国产福利精品在线| 欧美亚洲免费在线一区| 日韩成人一区二区| 91九色综合| www.4438全国最大| 91久久精品一区二区别| 日韩视频在线你懂得| 国产成人精品综合在线观看 | 人妻有码中文字幕| 97超碰色婷婷| 在线一区二区三区| 美女任你摸久久 | www久久日com| 四虎精品欧美一区二区免费| 美女视频久久黄| 亚洲综合视频在线观看| 黄色成人av网站| 欧美xoxoxo| baoyu777.永久免费视频| 国产嫩草一区二区三区在线观看| 亚洲国产高潮在线观看| 久久久不卡影院| 亚洲免费二区| 精精国产xxxx视频在线播放| 欧美 日韩 国产 激情| 91亚洲精品在线| 亚洲精品v欧美精品v日韩精品| 久久久亚洲高清| 欧美日韩亚洲一区| 日韩精品影院| 在线久久视频| 国产精品12p| 国产不卡一区二区在线播放| 欧美一级片免费看| 国产精品久久久久7777按摩| 国产精品久久777777毛茸茸 | 亚洲女人小视频在线观看| 亚洲欧美日韩国产| 日韩精品中文字幕吗一区二区| 中文字幕一二三区在线观看| 日韩在线电影一区| 欧美亚洲另类在线| 日韩视频国产视频| 国产精品第五页| 日本va欧美va欧美va精品| 成人免费直播在线| 污影院在线观看| 国产91久久久久蜜臀青青天草二| 中文字幕一区二区三区精彩视频| 国产精品极品美女粉嫩高清在线| 日韩国产精品一区| 欧美性jizz18性欧美| 99久久精品久久久久久清纯| 欧美午夜影院| 欧美三级午夜理伦三级在线观看| free性欧美| 国产在线观看免费| 色综合小说天天综合网| 大桥未久一区二区| 不卡视频一区| 欧美重口另类videos人妖| 亚洲欧美日韩区| 日本韩国精品在线| 亚洲国产高清不卡| 国产一区二区免费看| 亚洲精品社区| 精品国产精品久久一区免费式 | 国产清纯在线一区二区www| 精品久久视频| 久久久久久久久久久99999| 欧美精品123区| 懂色av一区二区三区四区五区| 黄网址在线观看| 亚洲三级色网| 国产丝袜一区二区三区| 日韩久久精品一区二区三区| 91www在线| 久久免费视频一区| 国产精品成人久久久久| 无遮挡动作视频在线观看免费入口| 欧美日韩国产高清| 亚洲国产另类 国产精品国产免费| 无码 制服 丝袜 国产 另类| 欧美亚洲韩国|