偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官問我:如何設計一個秒殺場景?

開發(fā) 架構
高并發(fā)指的是在同一時刻,有大量用戶的請求同時到達服務器,而服務器需要在有限的資源內處理這些請求,并盡可能快地響應用戶請求。

[[400329]]

前段時間在公眾號讀者交流群,有讀者提問到關于并發(fā)場景相關的問題:

從讀者的描述,可以看出高并發(fā)處理的經(jīng)驗,在面試中占據(jù)著舉足輕重的地位,關于高并發(fā)相關的面試題,一直都是面試熱題,因為這類面試題能夠更加直觀地體現(xiàn)候選人的技術水平與深度。如何解決高并發(fā)場景下的問題,永遠都不會過時。

在之前的工作經(jīng)歷中,我做過營銷相關項目,接觸過關于票券秒殺的高并發(fā)場景,秒殺場景也算是最熱門的高并發(fā)場景之一了。

下面我就把我對秒殺場景的一些理解簡單寫下來,僅供大家參考,歡迎留言糾錯或者補充。

核心要素

何為高并發(fā)?

高并發(fā)指的是在同一時刻,有大量用戶的請求同時到達服務器,而服務器需要在有限的資源內處理這些請求,并盡可能快地響應用戶請求。

在秒殺場景中,我們需要從在大量并發(fā)請求過程中提升服務器的處理性能,在處理過程中數(shù)據(jù)處理不能存錯,同時在整個秒殺鏈路中需要滿足高可用性,即在秒殺過程中,服務不能突然掉鏈子,需要滿足秒殺場景活動生命周期的完成。

我們可以總結出秒殺場景中有三個核心要素:

  • 高性能;
  • 一致性;
  • 高可用性。

如何提高性能?

秒殺場景核心的問題是如何解決海量請求帶來的性能問題,那么我們如何在有限的資源下,盡最大的限度去提高服務器訪問性能?按照我以往的經(jīng)驗,我大致總結有這幾點:熱點數(shù)據(jù)處理、流量削峰、資源隔離、服務器優(yōu)化。

熱點數(shù)據(jù)處理

1、什么是熱點數(shù)據(jù)?

我理解的熱點數(shù)據(jù)指的是用戶請求量非常高的那些數(shù)據(jù),在秒殺場景中,熱點數(shù)據(jù)就是那些要被秒殺的商品數(shù)據(jù)。

這些熱點請求會大量占用服務器的資源,如果不對這些數(shù)據(jù)進行處理,那么會嚴重占用資源,進而影響系統(tǒng)的性能,導致其他業(yè)務也受影響。

熱點數(shù)據(jù)又可以分為“靜態(tài)熱點數(shù)據(jù)”和“動態(tài)熱點數(shù)據(jù)”。

2、靜態(tài)熱點數(shù)據(jù)

靜態(tài)熱點數(shù)據(jù)指的是可以提前預知的熱點數(shù)據(jù),比如本文所說的秒殺場景,需要參與本次秒殺的商家提前報名,并將秒殺的商品錄入熱點分析系統(tǒng)中。業(yè)務系統(tǒng)通過這次提前錄入的熱點數(shù)據(jù),進行預加載,甚至可以將數(shù)據(jù)放入本地緩存中,這樣做的好處可以有效緩解避緩存集群的壓力,避免流量集中時壓垮緩存集群。

可能有人會問如何更新本地緩存?

我的做法是將熱點數(shù)據(jù)錄入熱點分析平臺,本地對熱點數(shù)據(jù)進行訂閱,并根據(jù)訂閱規(guī)則去更新本地緩存即可。

3、動態(tài)熱點數(shù)據(jù)

動態(tài)指的就是不能提前預知哪些數(shù)據(jù)是熱點的,需要通過數(shù)據(jù)收集與分析,或者通過大數(shù)據(jù)平臺預測。

我的做法是通過在網(wǎng)關平臺中做一個用于收集日志的異步日志收集系統(tǒng),通過采集商品請求的日志,處理后發(fā)送到熱點分析平臺,熱點分析平臺通過一些列的分析計算將這些熱點商品進行熱點數(shù)據(jù)處理,后端通過訂閱這些熱點數(shù)據(jù)就可以識別哪些商品是熱點數(shù)據(jù)了。

流量削峰

在服務器資源固定的情況下,說明處理能力是有峰值存在的,如果不對請求處理進行處理的話,很可能會在流量峰值的瞬間壓垮服務器,但流量峰值存在的時間不長,其實服務器的處理能力大部分時間都是處于閑置狀態(tài),那么我們可不可以將峰值集中的請求分散到其他時間呢?

1、消息隊列

消息隊列除了在解耦、異步場景之外,最大的作用場景是用于流量削峰,面對海量流量請求,可以將這些請求數(shù)據(jù)用異步的方式先存放在消息隊列中,而消息隊列一般都能夠存儲大量消息,消息會被消費端訂閱消費,這樣就有效地將峰值均攤到其他時間進行處理了。

如上,消息隊列就像我們平常見到的水庫一樣,當洪水來臨時,攔住并對其進行儲蓄,以減少對下游的沖擊,避免了洪水的災害。

目前有大量優(yōu)秀的開源消息隊列框架,如 RocketMQ、Kafka 等,而我之前在中通時主要負責消息平臺的建設與維護工作,中通每天面對幾千萬的訂單流量依然那么穩(wěn)固,其中消息隊列起了很大的“防洪”作用!

2、答題

除了利用消息隊列對請求進行“儲蓄”達到削峰的目的之外,還可以通過在用戶發(fā)起請求前,對用戶進行一些校驗操作,比如答題、輸入驗證碼等等,這種答題機制,除了可以防止買家在秒殺過程中使用作弊腳本之外,在秒殺場景中最主要的作還是將請求分散到各個時間點,秒殺場景一般都是集中在某個點進行,比如 0 點時刻,如果沒有答題機制,幾乎所有的流量都在 0 點時刻涌入服務器中,如果有答題機制,就能延緩用戶的請求,從而達到請求分散到各個時間點的目的。

如何保持一致性?

秒殺場景,本質上就是在海量買家同時請求購買時,能夠準確并將商品賣出去。

在秒殺的高并發(fā)讀寫請求過程中,需要保證商品不會發(fā)生“超賣”現(xiàn)象,因為秒殺的商品是數(shù)量一定的,但會有成千上萬個用戶在同一時間下單購買,在減扣庫存過程中如何保證商品數(shù)量的準確性至關重要。

減扣庫存方案分析

我在以前在做秒殺項目的時,分析過幾種減扣庫存的方式,我簡單分析下。

1、下單減扣庫存

買家只要完成下單,立即減扣商品庫存,這種方式實現(xiàn)是最簡單而且也是最精準的,通常可以在下單時利用數(shù)據(jù)庫事務能力即可保證減扣庫存的準確性,但需要考慮買家下單后不付款的情況。

2、付款減扣庫存

即買家下單后,并不立即減庫存,而是等到有用戶付款后才真正減庫存,否則庫存一直保留給其他買家。但因為付款時才減庫存,如果并發(fā)比較高,有可能出現(xiàn)買家下單后付不了款的情況,因為可能商品已經(jīng)被其他人買走了。

當只有買家下單后,并且已完成付款,才執(zhí)行庫存的減扣,這種方式好處是避免了買家不付款導致實際沒有賣出這么多商品的情況,但這種方式會造成用戶體驗不好,因為這會導致有些用戶付款時商品有可能被人買走了導致付款失敗的問題。

3、預扣庫存

這種方式結合以上兩種方式的優(yōu)點,當買家下單后,預扣庫存,只會其保留一定的時間,比如 10 分鐘,在這段時間內如果買家不付款,則將庫存自動釋放,其它買家可以繼續(xù)搶購。這種做法需要買家付款前,再做一次商品庫是否還有保留,如果沒有保留,則再次嘗試預扣,預扣失敗則不允許繼續(xù)付款;如果有保留,付款完成后執(zhí)行真正的減扣庫存動作。

但預扣庫存依然沒有徹底解決減扣庫存鏈路中存在的問題,比如有些買家可以在釋放的瞬間立馬又重新下單一次,相當于將庫存無限地保留下去,因此我們還需要將記錄用戶下單次數(shù),如果連續(xù)下單超過一定次數(shù),或者超過下單并不付款次數(shù),就攔截用戶下單請求。

總結:

一般最簡單的做法就是使用下單減庫存的方式(我之前的項目中就是用的這種),我當初的考慮是因為在秒殺場景中,商品的性價比通常很高,秒殺就是創(chuàng)造一種只有少量買家能買到的場景,一般來說買家只要“秒”到商品了,極少情況會出現(xiàn)退款的,即使發(fā)生了少量退款,造成實際賣出去的商品會比數(shù)據(jù)上少,也是可以通過候補來解決。

如何減扣庫存?

減扣庫存動作應該放在哪里執(zhí)行?

下面我具體分析一下減扣庫存的幾種實現(xiàn)方式:

  1. 如果鏈路涉及的邏輯比較簡單的,比如下單減庫存這種方式,最簡單的做法就是在下單時,利用數(shù)據(jù)庫的本地事務機制進行對庫存的減扣,比如使用 where 庫存 >0不滿足就回滾;
  2. 將庫存數(shù)量值放在緩存中,比如 Redis,并做持久化處理。

需要注意的是,如果遇到減扣庫存的邏輯很復雜,比如減扣庫存之后需要在同一個事務中做一些其他事情,那么就不能使用第二種方式了,只能使用第一種方式在數(shù)據(jù)庫層面上面操作,以保證同在一個事務中。面對這種情況,你可以將熱點數(shù)據(jù)進行數(shù)據(jù)庫隔離,把這些熱點商品單獨放在一個數(shù)據(jù)庫中。

如何實現(xiàn)高可用性?

最后,為了保證秒殺系統(tǒng)的高可用性,必須要對系統(tǒng)進行兜底處理,以便遇到極端的情況系統(tǒng)依然能夠運轉,通常的做法有服務降級、服務限流、拒絕請求等方式處理。

服務降級

當請求量達到系統(tǒng)承受的能力時,需要對系統(tǒng)的一些非核心功能進行關閉操作,盡可能將資源留給秒殺核心鏈路。

比如在秒殺系統(tǒng)中,還存在其他非核心的功能,我們可以在系統(tǒng)中設計一些動態(tài)開關,比如在網(wǎng)關層在路由開關,將這些非核心的請求直接在最外層拒掉。

還有就是對頁面展示的數(shù)據(jù)進行精簡化,用降低用戶體驗換取核心鏈路的穩(wěn)定運行。

服務限流

限流的目的是通過對并發(fā)訪問/請求進行限速或者一個時間窗口內的的請求進行限速來保護系統(tǒng),常用的有 QPS 限流,用戶請求排隊限流,需要設置過期時間,一旦超過過期時間則丟棄,這樣做是為了用戶請求可以做到快速失敗的效果,這種機制在 RocketMQ 中也有相關的應用,RocketMQ broker 會對客戶端請求進行排隊限流處理,當請求在隊列中超過了過期時間,則丟棄,客戶端快速失敗進行第二輪重試。

拒絕請求 

如果服務降級、服務限流都不能解決問題,最后的兜底,那就是直接拒絕用戶請求,比如直接給用戶返回 “服務器繁忙,請稍后再試”等提示文案。只會發(fā)生在服務器負載過載時會啟動,因此只會發(fā)生短暫不可用時刻,由于此時服務依然還在穩(wěn)定運行中,等負載下降時,可以快速恢復正常服務。

本文轉載自微信公眾號「后端進階」,可以通過以下二維碼關注。轉載本文請聯(lián)系后端進階公眾號。

 

責任編輯:武曉燕 來源: 后端進階
相關推薦

2024-12-26 10:19:16

2025-10-20 04:00:00

2021-05-20 08:54:16

Go面向對象

2025-09-19 09:57:46

2021-12-02 08:19:06

MVCC面試數(shù)據(jù)庫

2025-06-04 03:15:00

高并發(fā)短鏈系統(tǒng)

2022-03-11 21:35:57

Java程序線程

2025-09-17 10:08:43

2025-09-15 10:05:00

后端URL短鏈

2024-10-07 08:52:59

分布式系統(tǒng)分布式 IDID

2020-04-16 08:22:11

HTTPS加解密協(xié)議

2010-08-23 15:06:52

發(fā)問

2025-04-29 02:00:00

高并發(fā)系統(tǒng)場景

2022-05-24 08:03:28

InnoDBMySQL數(shù)據(jù)

2024-04-09 08:39:16

本地緩存開發(fā)線程安全

2024-08-07 08:15:47

2021-08-28 09:06:11

Dubbo架構服務

2022-04-08 08:26:03

JavaHTTP請求

2021-09-28 13:42:55

Chrome Devwebsocket網(wǎng)絡協(xié)議

2021-06-03 08:55:54

分布式事務ACID
點贊
收藏

51CTO技術棧公眾號