秒殺系統架構圖該怎麼畫?手把手教你!

淚目,不堪回首!

博主畢業4年了,最近秋招開始了,每次回想起本身的秋招,都感受到當時本身特別的惋惜(菜是原罪),本身當時簡歷上面的項目,只有一個 農資電商平臺,當時的秒殺系統尚未那麼普及(簡歷人均秒殺系統)。css

第一次微衆面試

當年本身的八股文背的其實還能夠,可是本身的項目就只是一個單機系統,分佈式微服務? 什麼玩意?,還記得當時微衆面試,是二面,在一個酒店房間,面試官笑嘻嘻的看着我,說讓我先畫一下我項目裏面的農資電商平臺, 我腦子嗡嗡叫,啥? 咋畫, 就一個安卓系統,一個前端頁面,和一個後臺系統html

大概長這樣子前端

image.png

我擦,這也太簡單了吧, 我是否是該畫複雜一點? 或者說,我這個能叫架構嗎?就這樣,猶豫之間,毛線都沒有畫出來... 我記得當時好像畫了個這樣子的玩意。。 毫無心外的,嗝屁了~mysql

這玩意有點四不像,不說了,丟臉~
複製代碼

image.png

第二次微衆面試

第二次微衆面試,畢業有快一年了,抱着試一下的心態,找了個師姐內推, 那時候我在幹啥呢,在搞爬蟲。公司離微衆比較近,就在金蝶那邊,下班了溜過去,跟面試官吧啦了一會八股文,好傢伙,沒一會就掏出了一張紙:git

來畫一下大家如今這個爬蟲系統的架構圖!github

當時系統的部署架構長這樣吧, 比上面的看起來還簡單一點。web

image.png

可是,我就是畫不出手啊!!! 內心想着太簡單了啊!! 這玩意能叫架構嗎?面試

攤牌了, 我不會畫!

如今想起來,真的太憋屈了,年輕啊! 那若是如今來回頭看的話,能怎麼畫呢?redis

單體系統的部署架構圖sql

image.png

爬蟲系統的分層架構圖

image.png

爬蟲系統的業務架構

image.png

架構圖

從上面的各個方向描述架構來看,其實即便是單體系統 也可以畫出不通常的架構圖!(爲啥當時我就不會呢!)

最近在看架構相關的內容(華仔的課),在4+1 視圖裏面,從多方面描述了咱們的系統,能夠參考下面的描述,

image.png

你的秒殺系統,架構是怎麼樣的?

單體系統

無論大家簡歷吹的多牛逼,我猜大家的服務,大部分都是長這個樣子的,猜對的話點個關注, 只有瀏覽器是分佈式的。

image.png

那我該如何去描述個人單體系統呢?

架構設計的三大原則:

  • 簡單原則
  • 合適原則
  • 演進原則

每一條原則都符合咱們大學作的秒殺系統啊!!

簡單原則: 一個系統就能夠知足咱們秒殺服務的全部動做,沒有太多的中間件依賴

合適原則:在咱們的實踐項目中,單體系統是最適合不過的了。(主要是沒錢啊!拆分服務,引入中間件,部署集羣,都得錢啊!)

演進原則:這個比較好理解,沒有什麼系統架構是一出生就定下來的,是隨着時間,業務需求,不斷演變出來的。

總結:

咱們架構的優點: 成本低系統複雜度低維護成本低快速定位問題

劣勢: 穩定性差併發量低擴展性弱

在梳理架構時,每一個方案都有他的優點和缺點,因此須要瞭解你目前方案的優缺點。才能更好的向面試官展現你的系統!

服務拆分

好傢伙,參加了個科創比賽,資金到位了,能買更多機器了,那不得將服務優化一下,拆分個微服務系統出來!

image.png

在這個服務拆分的架構中,咱們作了哪些動做?

  • 靜態資源隔離(CDN加速
  • 代理服務器(Nginx
  • 服務拆分,應用獨立部署
  • 服務rpc通訊 (rpc框架 & 註冊中心

一、先後端分離

在單體系統中,咱們的靜態資源(Html,JS,CSS 和 IMG)可能都是經過咱們服務端進行返回,存在的問題是:

  • 前端代碼維護成本比較高(全棧開發成本也高)
  • 前端代碼發佈,須要整個系統進行發佈
  • 服務器帶寬請求資源佔用等

那麼經過先後端分離所帶來的好處就很明顯了:

  • 代碼獨立維護(低耦合),發佈成本低(高效率)
  • 先後端經過接口交互動態數據
  • CDN資源訪問加速,減小後端服務壓力(高性能

二、反向代理

反向代理的做用比較明顯, 因爲咱們服務拆分紅多個,那麼咱們和前端進行交互時,須要提供一個通用的入口。而這個入口,就是咱們的反向代理服務器(Nginx)。 例如: 服務域名:https://www.jiuling.com ,根據restful規範,咱們能夠經過 https://www.jiuling.com/user/1.0/login 將請求轉發到 用戶服務的登陸接口中。

3.進程間通訊

隨着服務的拆分,在部分功能的實現上,就會涉及到服務間相互調用的狀況,例如:

image.png

在常見的實現方案上,咱們會採用 註冊中心RPC框架,來實現這一能力。而咱們比較經常使用的實現方案就是 zookeeper & dubbo

image.png

爲何要使用 RPC 框架?

當咱們提到使用 RPC框架 的時候,是否有去思考過,爲何要使用 RPC框架? 每一個服務提供 RESTful 接口,不是也可以完成服務間通訊嗎?

這裏就須要進行對比 RPCRESTful 的區別了:

  • 數據報文小&傳輸效率快RPC簡化了傳輸協議中一些必要的頭部信息,從而加快了傳輸效率。
  • 開發成本低:例如 Dubbo框架,封裝好了服務間調用的邏輯(如:反射建連超時控制等),只須要開發相應的接口數據模型便可。
  • 服務治理: 在分佈式場景下,咱們的服務提供者不止一臺,那麼就涉及到 服務健康負載均衡服務流控等狀況須要處理,而這部分能力在rpc & 註冊中心 的架構下,都已經知足了。

說完優勢後,再來分析一下,RPC的缺點:

  • 耦合性強: 相較於 RESTful而言,RPC 框架在跨語言的場景下實現比較困難。而且版本依賴比較強。服務脫離了當前內網環境後,沒法正常提供服務,遷移成本高。
  • 內網調用RPC更適合內網傳輸,在公網環境下,顯得沒那麼安全。

分佈式微服務

在上一個版本的服務拆分中, 咱們根據不一樣的業務邊界功能職責,劃分出了多個子系統,而針對不一樣的系統,他所承受的負載壓力是不同的,例如: 訂單服務的每一個請求處理耗時較長(其餘服務壓力不大),爲了挺升咱們的下單量,咱們能夠只擴容訂單服務便可,這就是咱們在服務拆分所帶來的收益,性能使用率提高!

image.png

從上面的圖咱們能夠看到,有些服務出現了不一樣的重影,每個方塊,能夠理解爲一臺機器,在這個架構中, 爲了保證咱們的下單成功率,以及下單量,咱們主要將服務器集中在了訂單服務

除此以前,再來看看咱們的中間件集羣部署:

  • mysql 主從架構: 讀寫分離,減輕主庫壓力,確保數據能正常寫入,保障訂單數據落庫.
  • zookeeper 主從架構: 保障註冊中心可用,避免致使全鏈路雪崩。
  • redis 哨兵集羣: 避免redis宕機致使大流量直接打到數據庫中。

小結

到這裏爲止,通常咱們本身開發的系統,也就基本完成了整個秒殺系統的演進了。可能大夥一直有個疑問,爲何少了咱們最熟悉的MQ呢?

在整個調用鏈路中,我都是以同步調用的方式去講述這一個秒殺系統的架構,由於這個已經知足咱們當前的流量訴求了,在架構設計的原則裏面,提到的,合適原則,和演進原則。在當前知足流量需求的狀況下,咱們須要先思考引入消息中間件,帶來的問題是什麼? 解決的問題又是什麼? 在權衡利弊後,纔是咱們決策是否要使用這個方案的時候。

高性能

在上述架構演進的過程當中,咱們經過服務拆分垂直擴容分佈式部署等方式,提高了咱們架構的性能穩定性,對於咱們自研階段的架構演進已是足夠知足咱們的流量訴求了,但若是咱們想繼續優化咱們的系統,提高服務性能,能夠從如下幾個方面進行優化:

  • 資源預熱
  • 緩存預熱
  • 異步調用

一、資源預熱

在上面的服務拆分階段, 咱們就提到了資源動靜分離, 這裏的靜態資源包括:html,js,css,img 等。咱們活動階段,能夠經過後臺管理系統,將商品服務中的活動的靜態資源預熱到CDN,加速資源的訪問。

資源預熱: 經過預先將資源加載到CDN
回源: CDN找不到資源後,會觸發源站(商品服務)調用,進行查詢對應資源,若是源站存在該資源,則會返回到CDN中進行緩存。
OSS: 實際存儲靜態資源的服務(可參考阿里雲OSS)
複製代碼

image.png

上面有反覆提到,引入一個技術的時候,須要同時考慮它所帶來的利和弊,那麼 CDN的風險是什麼呢?

  • 成本 : 比較直接,就是得多花錢!
  • 帶寬 : 在大流量的訪問下, CDN 是否能支撐那麼多的帶寬,每一個服務器能支撐的流量是有限的,須要考慮CDN是否能支撐業務的訪問量。
  • CDN命中率: 在CDN命中率低的狀況下,好比活動圖片,每個小時都會發生改變,那麼每次圖片的替換,都會觸發回源操做,這時候的資源訪問效率反而有所降低。

二、緩存預熱

與上面的靜態資源加速相對比,動態數據則須要經過緩存進行性能上的優化,老生常談,爲何redis 那麼快?

  • 單線程(redis的性能瓶頸並不在這,因此這個不算優點)
  • 多路I/O複用模型
  • 數據結構簡單
  • 基於內存操做

image.png

引入 redis 帶來的風險主要有:

  • reids 宕機: 單機部署的狀況下,會致使大量的服務調用超時,最終引發服務雪崩。可經過Sentinel集羣優化。
  • 緩存擊穿:大流量下,緩存MISS緩存過時等狀況,會致使請求穿透到數據庫,若是數據庫扛不住壓力,會形成服務雪崩。能夠經過 布隆過濾器進行優化。
  • 數據一致性緩存數據與DB 的數據一致性問題,須要經過更新策略進行保障。

三、異步調用

經過異步的方式,將減庫存成功的用戶,經過消息的方式,發送給訂單服務,進行後續的下單操做。能夠在短期內,將全部的商品銷售出去。總體的流程以下圖所示:

MQ異步調用爲何能過提高咱們服務的吞吐量呢?

主要緣由在於,經過異步調用的方式,咱們將消息投遞過去了,就完成了這一次的請求處理,那麼性能的瓶頸,由訂單服務,轉移到了秒殺服務這裏。經過減小調用依賴,從而提高了總體服務的吞吐量。

image.png

MQ 帶來的常見問題:

  • 數據一致性
  • 重複消費:因爲生產者重複投遞消息,或者消費緩慢致使重複推送消息。須要經過加鎖,消費冪等來保證消費正常。
  • 消息堆積: 生產能力遠大於消費能力狀況下,會致使消息堆積。
  • MQ可用性:MQ宕機的狀況下,須要支持同步調用切換。

這裏不作詳細介紹,後面會專門寫一篇MQ相關的文章

高可用

能看到這裏真不容易,感謝你們的支持。關於可用性這裏,以前有寫過一篇 # 《高可用實戰》-B站蹦了,關我A站什麼事? 感興趣能夠看一下。

高可用主要能夠從:

同城雙活

部署在同一個城市不一樣區的機房,用專用網絡鏈接。兩個機房距離通常就是幾十公里,網絡傳輸速度幾乎和同一個機房相同,下降了系統複雜度、成本

image.png

這個模式沒法解決極端的災難狀況,例如某個城市的地震、水災,此方式是用來解決一些常規故障的,例如機房的火災、停電、空調故障

異地多活

在上述模式中,沒辦法解決城市級別的服務容災,好比水災地震等情。而經過異地多活的部署方案,則能夠解決這種問題。

可是每一個方案都是存在利和弊的,那麼異地多活的弊端主要體如今網絡傳輸數據一致性的問題上!

跨城異地主要問題就是網絡傳輸延遲,例如北京到廣州,正常狀況下的RTT(Round-Trip Time 往返時延)是50毫秒,
當遇到網絡波動等狀況,會升到500毫秒甚至1秒,並且會有丟包問題。

物理距離必然致使數據不一致,這就得從「數據」特性來解決,
若是是強一致性要求的數據(如存款餘額),就沒法作異地多活。
複製代碼

點關注,不迷路

圖片地址:draw.io原圖

好了各位,以上就是這篇文章的所有內容了,我後面會每週都更新幾篇高質量的大廠面試和經常使用技術棧相關的文章。感謝大夥能看到這裏,若是這個文章寫得還不錯, 求三連!!! 感謝各位的支持和承認,咱們下篇文章見!

我是 九靈 ,有須要交流的童鞋能夠關注公衆號:Java 補習課,掌握第一手資料! 若是本篇博客有任何錯誤,請批評指教,不勝感激 !

相關文章
相關標籤/搜索