主頁 > 後端開發 > 高并發高可用系統以及面試分析

高并發高可用系統以及面試分析

2020-09-17 11:02:17 後端開發

1.高并發,高可用系統的一些思考

高并發依賴于場景和邏輯

不一定每個場景都會產生高并發,不要為了高并發而盲目的設計,過度設計帶來 的問題遠比意料之外的高并發要多很多,依賴于具體場景和行為進行分析,一個 購物類網站,搶購場景,會觸發很多的讀取商品詳情,計算庫存等操作,而且不 需要每個請求都到達支付頁面,也不會在網站主頁帶來很多的請求,所以需要針 對搶購場景進行優化,而不是巨大的支付流程進行優化,當然商品數量多和用戶 多的情況,才需要也優化一下支付流程,

拋開場景,不談流量的盲目高并發設計,一般是過度設計,未來維護臃腫而復 雜的代碼會懲罰你當初的過度設計,

突如其來的高并發

基本是被人刷了,或者比預估的情況要多了幾倍,才有這種情況,前者可能性很 大,最近這兩年的金融網站,區塊鏈,xx 幣網站,基本會被羊毛黨盯上,沒做 好訪問防作弊,或者被對手 ddos 攻擊,都會造成高并發中網站癱瘓,清洗流 量一般就可以的,不要讓辣雞流量貫穿整個業務,高并發會帶來網站請求慢,但 網站請求慢不一定是高并發了,對癥下藥,

如果是網紅帶貨什么的,給網站帶來高并發了,這種情況下可以在提前流量上做 些手腳,例如:1. 用訊息佇列排隊流量,例如猴王網站的搶購 2. 采用一些高 端點的驗證碼,讓一些秒殺搶購的機器號被過濾出去,盡量不影響真實用戶的 搶購結果 3. 分層過濾,例如靜態資源放在 CDN 上,NGINX 層面使用自身的 快取,根據路由快取基礎資料,其他動態資料再讀寫資料庫,而不是每個請求 都經過整體的業務,這樣帶來的壓力太大了,而且也不值得,

 

并發中的整體專案穩定性

可以將高并發的業務部分分離到單獨的服務器,這種情況下能夠避免這部分業務 帶來機器性能的消耗,從而影響整個專案的穩定性,這樣的結果不太好的,也可 以預先將熱資料放到快取中,提高讀寫效率,也能讓 MySQL 比較穩定,一般 情況下能有高并發的網站,資料量也不少,舉例某個電商網站,可能有 100w 商 品資料,但大家搶購的是今天熱推的 10 個商品,將這十個資料提取放到快取 中,而不是每次去資料庫中查詢,當然 MySQL 設定合理的話,自身的 buffer pool 也能搞定這些熱資料快取,這樣相當于將這 10 條資料隔離出來,而不是影響到整體資料,關于熱點資料的發現,還有一些高端的是從 NGINX 訪問日 志層面實時分析,據說淘寶這種是這樣的,實時發現訪問很多的路由,分析路由 獲取到對應的商品資料,放到快取中,減輕服務器壓力,

穩定性不光存在于業務機器層面,也可能是網路寬帶不夠,或者程式在磁盤寫日 志的時候遇到瓶頸,或者記憶體不夠,導致可用快取空間很小,這些在測驗和計算 層面需要注意的問題,也會影響整體穩定性和性能的,應該提前解決,例如秒殺 系統需要關注 CPU,并發讀需要關注快取,靜態資源多的也需要考慮寬帶,

預先測驗

簡單可以是壓測關鍵業務部分,簡單的查詢一般不會帶來問題,這個頁面的靜態 資源太多,同時都在統一個域名下的話,相當于在現有并發的數量上加了更多, 這非常不利,對于瀏覽器的加載也是不利的,簡單業務也會體驗很差,壓力測驗 應當遵循慢慢提升流量的方式,并發量和回應時間并不是等比例上漲的,慢慢 提升并發量的測驗,會展示代碼的瓶頸部分在哪,然后在去解決和提升,測驗也 可以

在基礎的并發測驗之外,還有在正是服務器上的全鏈路壓力測驗,為了防止和真 實資料沖突,可以將請求中加上額外的標記,或者針對特定的用戶帳號測驗,在 資料中體現這部分額外標記,測驗完畢之后將資料洗掉,

同時,不要高并發的主要業務一直占用機器的 100% 的運算能力,這樣整體邏 輯和請求支持已經到了極限,基本再高一點就會造成問題,應該盡量讓業務只占 用機器 60-70% 的運算能力,留出一部分的余地,防止意外,

安全及備用方案

1. 從 NGINX 層面限制單個 IP 單位時間內請求頻率和次數,屏蔽掉機器刷 的可能性,從而不影響正常訪問, 2. 切記高并發 + 高可用不可以用單 點系統,例如不能因為熱資料少而就用一臺 Redis 服務器,或者更狠的 直接本機快取,一旦系統崩潰,相當于觸發連鎖反應,連保存現場和恢復 都很難, 3. 提前設計兜底方案 ① 降級,例如商品詳情頁面不展示推薦 商品,或者減少推薦商品展示數量等, ② 限流,不讓更多流量涌入,能 減少很多壓力 ③ 過載臨界點拒絕服務,這個是最壞的情況,直接阻斷壓 垮系統的最后一個流量,

2.面試官為什么會問你,如何設計一個高并發系統?

面試官心理分析

說實話,如果面試官問你這個題目,那么你必須要使出全身吃奶勁了,為啥?因 為你沒看到現在很多公司招聘的 JD 里都是說啥,有高并發就經驗者優先,

如果你確實有真才實學,在互聯網公司里干過高并發系統,那你確實拿 offer 基 本如探囊取物,沒啥問題,面試官也絕對不會這樣來問你,否則他就是蠢,

假設你在某知名電商公司干過高并發系統,用戶上億,一天流量幾十億,高峰期 并發量上萬,甚至是十萬,那么人家一定會仔細盤問你的系統架構,你們系統啥 架構?怎么部署的?部署了多少臺機器?快取咋用的?MQ 咋用的?資料庫咋 用的?就是深挖你到底是如何扛住高并發的,

因為真正干過高并發的人一定知道,脫離了業務的系統架構都是在紙上談兵,真 正在復雜業務場景而且還高并發的時候,那系統架構一定不是那么簡單的,用個 redis,用 mq 就能搞定?當然不是,真實的系統架構搭配上業務之后,會比這 種簡單的所謂“高并發架構”要復雜很多倍,

如果有面試官問你個問題說,如何設計一個高并發系統?那么不好意思,一定是 因為你實際上沒干過高并發系統,面試官看你簡歷就沒啥出彩的,感覺就不咋地, 所以就會問問你,如何設計一個高并發系統?其實說白了本質就是看看你有沒有 自己研究過,有沒有一定的知識積累,

最好的當然是招聘個真正干過高并發的哥兒們咯,但是這種哥兒們人數稀缺,不 好招,所以可能次一點的就是招一個自己研究過的哥兒們,總比招一個啥也不會 的哥兒們好吧!

所以這個時候你必須得做一把個人秀了,秀出你所有關于高并發的知識!

 

面試題剖析

其實所謂的高并發,如果你要理解這個問題呢,其實就得從高并發的根源出發, 為啥會有高并發?為啥高并發就很牛逼?

我說的淺顯一點,很簡單,就是因為剛開始系統都是連接資料庫的,但是要知道 資料庫支撐到每秒并發兩三千的時候,基本就快完了,所以才有說,很多公司, 剛開始干的時候,技術比較 low,結果業務發展太快,有的時候系統扛不住壓力 就掛了,

當然會掛了,憑什么不掛?你資料庫如果瞬間承載每秒 5000/8000,甚至上萬 的并發,一定會宕機,因為比如 mysql 就壓根兒扛不住這么高的并發量,

所以為啥高并發牛逼?就是因為現在用互聯網的人越來越多,很多 app、網站、 系統承載的都是高并發請求,可能高峰期每秒并發量幾千,很正常的,如果是什 么雙十一之類的,每秒并發幾萬幾十萬都有可能,

那么如此之高的并發量,加上原本就如此之復雜的業務,咋玩兒?真正厲害的, 一定是在復雜業務系統里玩兒過高并發架構的人,但是你沒有,那么我給你說一 下你該怎么回答這個問題:

可以分為以下 6 點:

系統拆分 快取
MQ
分庫分表
讀寫分離
ElasticSearch

 

系統拆分

將一個系統拆分為多個子系統,用 dubbo 來搞,然后每個系統連一個資料庫, 這樣本來就一個庫,現在多個資料庫,不也可以扛高并發么,

快取

快取,必須得用快取,大部分的高并發場景,都是讀多寫少,那你完全可以在數 據庫和快取里都寫一份,然后讀的時候大量走快取不就得了,畢竟人家 redis 輕 輕松松單機幾萬的并發,所以你可以考慮考慮你的專案里,那些承載主要請求的 讀場景,怎么用快取來抗高并發,

MQ

MQ,必須得用 MQ,可能你還是會出現高并發寫的場景,比如說一個業務操作 里要頻繁搞資料庫幾十次,增刪改增刪改,瘋了,那高并發絕對搞掛你的系統, 你要是用 redis 來承載寫那肯定不行,人家是快取,資料隨時就被 LRU 了,數 據格式還無比簡單,沒有事務支持,所以該用 mysql 還得用 mysql 啊,那你 咋辦?用 MQ 吧,大量的寫請求灌入 MQ 里,排隊慢慢玩兒,后邊系統消費 后慢慢寫,控制在 mysql 承載范圍之內,所以你得考慮考慮你的專案里,那些 承載復雜寫業務邏輯的場景里,如何用 MQ 來異步寫,提升并發性,MQ 單機 抗幾萬并發也是 ok 的,這個之前還特意說過,

 

 

分庫分表

分庫分表,可能到了最后資料庫層面還是免不了抗高并發的要求,好吧,那么就 將一個資料庫拆分為多個庫,多個庫來扛更高的并發;然后將一個表拆分為多個 表,每個表的資料量保持少一點,提高 sql 跑的性能,

讀寫分離

讀寫分離,這個就是說大部分時候資料庫可能也是讀多寫少,沒必要所有請求都 集中在一個庫上吧,可以搞個主從架構,主庫寫入,從庫讀取,搞一個讀寫分離, 讀流量太多的時候,還可以加更多的從庫,

ElasticSearch

Elasticsearch,簡稱 es,es 是分布式的,可以隨便擴容,分布式天然就可以支 撐高并發,因為動不動就可以擴容加機器來扛更高的并發,那么一些比較簡單的 查詢、統計類的操作,可以考慮用 es 來承載,還有一些全文搜索類的操作,也 可以考慮用 es 來承載,


上面的 幾點點,基本就是高并發系統肯定要干的一些事兒,大家可以仔細結合之 前講過的知識考慮一下,到時候你可以系統的把這塊闡述一下,然后每個部分要 注意哪些問題,之前都講過了,你都可以闡述闡述,表明你對這塊是有點積累的,

 

說句實話,畢竟你真正厲害的一點,不是在于弄明白一些技術,或者大概知道一 個高并發系統應該長什么樣?其實實際上在真正的復雜的業務系統里,做高并發 要遠遠比上面提到的點要復雜幾十倍到上百倍,你需要考慮:哪些需要分庫分表, 哪些不需要分庫分表,單庫單表跟分庫分表如何 join,哪些資料要放到快取里 去,放哪些資料才可以扛住高并發的請求,你需要完成對一個復雜業務系統的分 析之后,然后逐步逐步的加入高并發的系統架構的改造,這個程序是無比復雜的, 一旦做過一次,并且做好了,你在這個市場上就會非常的吃香,

其實大部分公司,真正看重的,不是說你掌握高并發相關的一些基本的架構知識, 架構中的一些技術,RocketMQ、Kafka、Redis、Elasticsearch,高并發這一塊, 你了解了,也只能是次一等的人才,對一個有幾十萬行代碼的復雜的分布式系統, 一步一步架構、設計以及實踐過高并發架構的人,這個經驗是難能可貴的,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/65117.html

標籤:PHP

上一篇:php異步多執行緒swoole用法實體

下一篇:[PHP] PHP 7.4.4錯誤修復版本的更改日志

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more