如何從零設(shè)計(jì)一款高并發(fā)架構(gòu)
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

-? ? ?前言? ? -

-? ? ?服務(wù)器架構(gòu)? ? -
服務(wù)器 均衡負(fù)載(如:nginx,阿里云SLB) 資源監(jiān)控 分布式 數(shù)據(jù)庫(kù) 主從分離,集群 DBA 表優(yōu)化,索引優(yōu)化,等 分布式 nosql 主從分離,集群 主從分離,集群 主從分離,集群 redis mongodb memcache cdn html css js image

-? ? ?并發(fā)測(cè)試? ? -
阿里云性能測(cè)試
Apache JMeter Visual Studio性能負(fù)載測(cè)試 Microsoft Web Application Stress Tool

-? ? ?實(shí)戰(zhàn)方案? ? -
通用方案
日用戶流量大,但是比較分散,偶爾會(huì)有用戶高聚的情況;

用戶簽到獲取積分 計(jì)算出用戶分布的key,redis hash中查找用戶今日簽到信息 如果查詢到簽到信息,返回簽到信息 如果沒(méi)有查詢到,DB查詢今日是否簽到過(guò),如果有簽到過(guò),就把簽到信息同步redis緩存。 如果DB中也沒(méi)有查詢到今日的簽到記錄,就進(jìn)行簽到邏輯,操作DB添加今日簽到記錄,添加簽到積分(這整個(gè)DB操作是一個(gè)事務(wù)) 緩存簽到信息到redis,返回簽到信息 注意這里會(huì)有并發(fā)情況下的邏輯問(wèn)題,如:一天簽到多次,發(fā)放多次積分給用戶。 用戶訂單 這里我們只緩存用戶第一頁(yè)的訂單信息,一頁(yè)40條數(shù)據(jù),用戶一般也只會(huì)看第一頁(yè)的訂單數(shù)據(jù) 用戶訪問(wèn)訂單列表,如果是第一頁(yè)讀緩存,如果不是讀DB 計(jì)算出用戶分布的key,redis hash中查找用戶訂單信息 如果查詢到用戶訂單信息,返回訂單信息 如果不存在就進(jìn)行DB查詢第一頁(yè)的訂單數(shù)據(jù),然后緩存redis,返回訂單信息 用戶中心 計(jì)算出用戶分布的key,redis hash中查找用戶訂單信息 如果查詢到用戶信息,返回用戶信息 如果不存在進(jìn)行用戶DB查詢,然后緩存redis,返回用戶信息 其他業(yè)務(wù) 上面例子多是針對(duì)用戶存儲(chǔ)緩存,如果是公用的緩存數(shù)據(jù)需要注意一些問(wèn)題,如下 注意公用的緩存數(shù)據(jù)需要考慮并發(fā)下的可能會(huì)導(dǎo)致大量命中DB查詢,可以使用管理后臺(tái)更新緩存,或者DB查詢的鎖住操作。 博文《大話Redis進(jìn)階》對(duì)更新緩存問(wèn)題和推薦方案的分享。

-? ? ?消息隊(duì)列? ? -
秒殺、秒搶等活動(dòng)業(yè)務(wù),用戶在瞬間涌入產(chǎn)生高并發(fā)請(qǐng)求

一般習(xí)慣使用 redis的 list 當(dāng)用戶參與活動(dòng),將用戶參與信息push到隊(duì)列中 然后寫個(gè)多線程程序去pop數(shù)據(jù),進(jìn)行發(fā)放紅包的業(yè)務(wù) 這樣可以支持高并發(fā)下的用戶可以正常的參與活動(dòng),并且避免數(shù)據(jù)庫(kù)服務(wù)器宕機(jī)的危險(xiǎn)

-? ? ?一級(jí)緩存? ? -


-? ? ?靜態(tài)化數(shù)據(jù)? ? -
其他方案
對(duì)于更新頻繁度不高的數(shù)據(jù),APP,PC瀏覽器,可以緩存數(shù)據(jù)到本地,然后每次請(qǐng)求接口的時(shí)候上傳當(dāng)前緩存數(shù)據(jù)的版本號(hào),服務(wù)端接收到版本號(hào)判斷版本號(hào)與最新數(shù)據(jù)版本號(hào)是否一致,如果不一樣就進(jìn)行最新數(shù)據(jù)的查詢并返回最新數(shù)據(jù)和最新版本號(hào),如果一樣就返回狀態(tài)碼告知數(shù)據(jù)已經(jīng)是最新。減少服務(wù)器壓力:資源、帶寬等。

-? ? ?分層、分割、分布式? ? -
分層 將系統(tǒng)在橫向維度上切分成幾個(gè)部分,每個(gè)部門負(fù)責(zé)一部分相對(duì)簡(jiǎn)單并比較單一的職責(zé),然后通過(guò)上層對(duì)下層的依賴和調(diào)度組成一個(gè)完整的系統(tǒng) 比如把電商系統(tǒng)分成:應(yīng)用層,服務(wù)層,數(shù)據(jù)層。(具體分多少個(gè)層次根據(jù)自己的業(yè)務(wù)場(chǎng)景) 應(yīng)用層:網(wǎng)站首頁(yè),用戶中心,商品中心,購(gòu)物車,紅包業(yè)務(wù),活動(dòng)中心等,負(fù)責(zé)具體業(yè)務(wù)和視圖展示 服務(wù)層:訂單服務(wù),用戶管理服務(wù),紅包服務(wù),商品服務(wù)等,為應(yīng)用層提供服務(wù)支持 數(shù)據(jù)層:關(guān)系數(shù)據(jù)庫(kù),nosql數(shù)據(jù)庫(kù) 等,提供數(shù)據(jù)存儲(chǔ)查詢服務(wù) 分層架構(gòu)是邏輯上的,在物理部署上可以部署在同一臺(tái)物理機(jī)器上,但是隨著網(wǎng)站業(yè)務(wù)的發(fā)展,必然需要對(duì)已經(jīng)分層的模塊分離部署,分別部署在不同的服務(wù)器上,使網(wǎng)站可以支撐更多用戶訪問(wèn) 分割 在縱向方面對(duì)業(yè)務(wù)進(jìn)行切分,將一塊相對(duì)復(fù)雜的業(yè)務(wù)分割成不同的模塊單元 包裝成高內(nèi)聚低耦合的模塊不僅有助于軟件的開發(fā)維護(hù),也便于不同模塊的分布式部署,提高網(wǎng)站的并發(fā)處理能力和功能擴(kuò)展 比如用戶中心可以分割成:賬戶信息模塊,訂單模塊,充值模塊,提現(xiàn)模塊,優(yōu)惠券模塊等 分布式 分布式應(yīng)用和服務(wù),將分層或者分割后的業(yè)務(wù)分布式部署,獨(dú)立的應(yīng)用服務(wù)器,數(shù)據(jù)庫(kù),緩存服務(wù)器 當(dāng)業(yè)務(wù)達(dá)到一定用戶量的時(shí)候,再進(jìn)行服務(wù)器均衡負(fù)載,數(shù)據(jù)庫(kù),緩存主從集群 分布式靜態(tài)資源,比如:靜態(tài)資源上傳cdn 分布式計(jì)算,比如:使用hadoop進(jìn)行大數(shù)據(jù)的分布式計(jì)算 分布式數(shù)據(jù)和存儲(chǔ),比如:各分布節(jié)點(diǎn)根據(jù)哈希算法或其他算法分散存儲(chǔ)數(shù)據(jù)


-? ? ?集群? ? -
應(yīng)用服務(wù)器集群 nginx 反向代理 slb … … (關(guān)系/nosql)數(shù)據(jù)庫(kù)集群 主從分離,從庫(kù)集群


-? ? ?異步? ? -
如: 自動(dòng)彈窗簽到,雙11跨0點(diǎn)的時(shí)候并發(fā)請(qǐng)求簽到接口 雙11搶紅包活動(dòng) 雙11訂單入庫(kù) 等 設(shè)計(jì)考慮: 逆向思維,壓力在數(shù)據(jù)庫(kù),那業(yè)務(wù)接口就不進(jìn)行數(shù)據(jù)庫(kù)操作不就沒(méi)壓力了 數(shù)據(jù)持久化是否允許延遲? 如何讓業(yè)務(wù)接口不直接操作DB,又可以讓數(shù)據(jù)持久化? 方案設(shè)計(jì): 像這種涉及數(shù)據(jù)庫(kù)操作的高并發(fā)的業(yè)務(wù),就要考慮使用異步了 客戶端發(fā)起接口請(qǐng)求,服務(wù)端快速響應(yīng),客戶端展示結(jié)果給用戶,數(shù)據(jù)庫(kù)操作通過(guò)異步同步 如何實(shí)現(xiàn)異步同步? 使用消息隊(duì)列,將入庫(kù)的內(nèi)容enqueue到消息隊(duì)列中,業(yè)務(wù)接口快速響應(yīng)給用戶結(jié)果(可以溫馨提示高峰期延遲到賬) 然后再寫個(gè)獨(dú)立程序從消息隊(duì)列dequeue數(shù)據(jù)出來(lái)進(jìn)行入庫(kù)操作,入庫(kù)成功后刷新用戶相關(guān)緩存,如果入庫(kù)失敗記錄日志,方便反饋查詢和重新持久化 這樣一來(lái)數(shù)據(jù)庫(kù)操作就只有一個(gè)程序(多線程)來(lái)完成,不會(huì)給數(shù)據(jù)帶來(lái)壓力 補(bǔ)充: 消息隊(duì)列除了可以用在高并發(fā)業(yè)務(wù),其他只要有相同需求的業(yè)務(wù)也是可以使用,如:短信發(fā)送中間件等 高并發(fā)下異步持久化數(shù)據(jù)可能會(huì)影響用戶的體驗(yàn),可以通過(guò)可配置的方式,或者自動(dòng)化監(jiān)控資源消耗來(lái)切換時(shí)時(shí)或者使用異步,這樣在正常流量的情況下可以使用時(shí)時(shí)操作數(shù)據(jù)庫(kù)來(lái)提高用戶體驗(yàn) 異步同時(shí)也可以指編程上的異步函數(shù),異步線程,在有的時(shí)候可以使用異步操作,把不需要等待結(jié)果的操作放到異步中,然后繼續(xù)后面的操作,節(jié)省了等待的這部分操作的時(shí)間

-? ? ?緩存? ? -
設(shè)計(jì)考慮: 還是逆向思維,壓力在數(shù)據(jù)庫(kù),那么我們就不進(jìn)行數(shù)據(jù)庫(kù)查詢 數(shù)據(jù)不經(jīng)常變化,我們?yōu)樯兑恢辈樵僁B? 數(shù)據(jù)不變化客戶端為啥要向服務(wù)器請(qǐng)求返回一樣的數(shù)據(jù)? 方案設(shè)計(jì): 數(shù)據(jù)不經(jīng)常變化,我們可以把數(shù)據(jù)進(jìn)行緩存,緩存的方式有很多種,一般的:應(yīng)用服務(wù)器直接Cache內(nèi)存,主流的:存儲(chǔ)在memcache、redis內(nèi)存數(shù)據(jù)庫(kù) Cache是直接存儲(chǔ)在應(yīng)用服務(wù)器中,讀取速度快,內(nèi)存數(shù)據(jù)庫(kù)服務(wù)器允許連接數(shù)可以支撐到很大,而且數(shù)據(jù)存儲(chǔ)在內(nèi)存,讀取速度快,再加上主從集群,可以支撐很大的并發(fā)查詢 根據(jù)業(yè)務(wù)情景,使用配合客戶端本地存,如果我們數(shù)據(jù)內(nèi)容不經(jīng)常變化,為啥要一直請(qǐng)求服務(wù)器獲取相同數(shù)據(jù),可以通過(guò)匹配數(shù)據(jù)版本號(hào),如果版本號(hào)不一樣接口重新查詢緩存返回?cái)?shù)據(jù)和版本號(hào),如果一樣則不查詢數(shù)據(jù)直接響應(yīng) 這樣不僅可以提高接口響應(yīng)速度,也可以節(jié)約服務(wù)器帶寬,雖然有些服務(wù)器帶寬是按流量計(jì)費(fèi),但是也不是絕對(duì)無(wú)限的,在高并發(fā)的時(shí)候服務(wù)器帶寬也可能導(dǎo)致請(qǐng)求響應(yīng)慢的問(wèn)題 補(bǔ)充: 緩存同時(shí)也指靜態(tài)資源客戶端緩存 cdn緩存,靜態(tài)資源通過(guò)上傳cdn,cdn節(jié)點(diǎn)緩存我們的靜態(tài)資源,減少服務(wù)器壓力


-? ? ?面向服務(wù)? ? -
SOA面向服務(wù)架構(gòu)設(shè)計(jì) 微服務(wù)更細(xì)粒度服務(wù)化,一系列的獨(dú)立的服務(wù)共同組成系統(tǒng)
服務(wù)例子: 用戶行為跟蹤記錄統(tǒng)計(jì) 說(shuō)明: 通過(guò)上報(bào)應(yīng)用模塊,操作事件,事件對(duì)象,等數(shù)據(jù),記錄用戶的操作行為 比如:記錄用戶在某個(gè)商品模塊,點(diǎn)擊了某一件商品,或者瀏覽了某一件商品 背景: 由于服務(wù)需要記錄用戶的各種操作行為,并且可以重復(fù)上報(bào),準(zhǔn)備接入服務(wù)的業(yè)務(wù)又是核心業(yè)務(wù)的用戶行為跟蹤,所以請(qǐng)求量很大,高峰期會(huì)產(chǎn)生大量并發(fā)請(qǐng)求。 架構(gòu): nodejs WEB應(yīng)用服務(wù)器均衡負(fù)載 redis主從集群 mysql主 nodejs+express+ejs+redis+mysql 服務(wù)端采用nodejs,nodejs是單進(jìn)程(PM2根據(jù)cpu核數(shù)開啟多個(gè)工作進(jìn)程),采用事件驅(qū)動(dòng)機(jī)制,適合I/O密集型業(yè)務(wù),處理高并發(fā)能力強(qiáng) 業(yè)務(wù)設(shè)計(jì): 并發(fā)量大,所以不能直接入庫(kù),采用:異步同步數(shù)據(jù),消息隊(duì)列 請(qǐng)求接口上報(bào)數(shù)據(jù),接口將上報(bào)數(shù)據(jù)push到redis的list隊(duì)列中 nodejs寫入庫(kù)腳本,循環(huán)pop redis list數(shù)據(jù),將數(shù)據(jù)存儲(chǔ)入庫(kù),并進(jìn)行相關(guān)統(tǒng)計(jì)Update,無(wú)數(shù)據(jù)時(shí)sleep幾秒 因?yàn)閿?shù)據(jù)量會(huì)比較大,上報(bào)的數(shù)據(jù)表按天命名存儲(chǔ) 接口: 上報(bào)數(shù)據(jù)接口 統(tǒng)計(jì)查詢接口 上線跟進(jìn): 服務(wù)業(yè)務(wù)基本正常 每天的上報(bào)表有上千萬(wàn)的數(shù)據(jù)

-? ? ?冗余,自動(dòng)化? ? -
冗余 數(shù)據(jù)庫(kù)備份 備用服務(wù)器 自動(dòng)化 自動(dòng)化監(jiān)控 自動(dòng)化報(bào)警 自動(dòng)化降級(jí)

-? ? ?總結(jié)? ? -
來(lái)源:網(wǎng)絡(luò)
評(píng)論
圖片
表情

