1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【高并發(fā)、高性能、高可用】系統(tǒng)設(shè)計(jì)經(jīng)驗(yàn)

        共 4231字,需瀏覽 9分鐘

         ·

        2021-06-08 14:58

        知識(shí)分享,以技會(huì)友。大家好,我是Tom哥。閱讀本文大約需要 15 分鐘。

        軟件開發(fā)通常會(huì)提到一個(gè)名詞 “三高”,即高并發(fā)、高性能、高可用。

        具體的指標(biāo)定義,如:高并發(fā)方面要求QPS 大于 10萬;高性能方面要求請(qǐng)求延遲小于 100 ms;高可用方面要高于 99.99%。

        接下來,我們重點(diǎn)來介紹這 三高


        高并發(fā)


        我們使用 QPS(Queries Per Second,每秒查詢率)來衡量系統(tǒng)承載能力。架構(gòu)策略有哪些?


        1、負(fù)載均衡

        正所謂雙拳難敵四手,高并發(fā)撐場面的首選方案就是集群化部署,一臺(tái)服務(wù)器承載的QPS有限,多臺(tái)服務(wù)器疊加效果就不一樣了。

        如何將流量轉(zhuǎn)發(fā)到服務(wù)器集群,這里面就要用到負(fù)載均衡,比如:LVS 和 Nginx。

        常用的負(fù)載算法有輪詢法、隨機(jī)法、源地址哈希法、加權(quán)輪詢法、加權(quán)隨機(jī)法、最小連接數(shù)法等

        業(yè)務(wù)實(shí)戰(zhàn):對(duì)于千萬級(jí)流量的秒殺業(yè)務(wù),一臺(tái)LVS扛不住流量洪峰,通常需要 10 臺(tái)左右,其上面用DDNS(Dynamic DNS)做域名解析負(fù)載均衡。搭配高性能網(wǎng)卡,單臺(tái)LVS能夠提供百萬以上并發(fā)能力。

        注意, LVS 負(fù)責(zé)網(wǎng)絡(luò)四層協(xié)議轉(zhuǎn)發(fā),無法按 HTTP 協(xié)議中的請(qǐng)求路徑做負(fù)載均衡,所以還需要 Nginx

        2、池化技術(shù)

        復(fù)用單個(gè)連接無法承載高并發(fā),如果每次請(qǐng)求都新建連接、關(guān)閉連接,考慮到TCP的三次握手、四次揮手,有時(shí)間開銷浪費(fèi)。池化技術(shù)的核心是資源的“預(yù)分配”和“循環(huán)使用”,常用的池化技術(shù)有線程池、進(jìn)程池、對(duì)象池、內(nèi)存池、連接池、協(xié)程池。

        連接池的幾個(gè)重要參數(shù):最小連接數(shù)、空閑連接數(shù)、最大連接數(shù)

        Linux 內(nèi)核中是以進(jìn)程為單元來調(diào)度資源的,線程也是輕量級(jí)進(jìn)程。所以說,進(jìn)程、線程都是由內(nèi)核來創(chuàng)建并調(diào)度。協(xié)程是由應(yīng)用程序創(chuàng)建出來的任務(wù)執(zhí)行單元,比如 Go 語言中的協(xié)程“goroutine”。協(xié)程本身是運(yùn)行在線程上,由應(yīng)用程序自己調(diào)度,它是比線程更輕量的執(zhí)行單元。


        在 Go 語言中,一個(gè)協(xié)程初始內(nèi)存空間是 2KB(Linux 下線程棧大小默認(rèn)是 8MB),相比線程和進(jìn)程來說要小很多。協(xié)程的創(chuàng)建和銷毀完全是在用戶態(tài)執(zhí)行的,不涉及用戶態(tài)和內(nèi)核態(tài)的切換。另外,協(xié)程完全由應(yīng)用程序在用戶態(tài)下調(diào)用,不涉及內(nèi)核態(tài)的上下文切換。協(xié)程切換時(shí)由于不需要處理線程狀態(tài),需要保存的上下文也很少,速度很快。

        Go語言中協(xié)程池的實(shí)現(xiàn)方法有兩種:搶占式和調(diào)度式。

        • 搶占式協(xié)程池,所有任務(wù)存放到一個(gè)共享的 channel 中,多個(gè)協(xié)程同時(shí)去消費(fèi) channel 中的任務(wù),存在鎖競爭。
        • 調(diào)度式協(xié)程池,每個(gè)協(xié)程都有自己的 channel,每個(gè)協(xié)程只消費(fèi)自己的 channel。下發(fā)任務(wù)的時(shí)候,采用負(fù)載均衡算法選擇合適的協(xié)程來執(zhí)行任務(wù)。比如選擇排隊(duì)中任務(wù)最少的協(xié)程,或者簡單輪詢。

        3、流量漏斗

        上面講的是正向方式提升系統(tǒng)QPS,我們也可以逆向思維,做減法,攔截非法請(qǐng)求,將核心能力留給正常業(yè)務(wù)!

        互聯(lián)網(wǎng)高并發(fā)流量并不都是純凈的,也有很多惡意流量(比如黑客攻擊、惡意爬蟲、黃牛、秒殺器等),我們需要設(shè)計(jì)流量攔截器,將那些非法的、無資格的、優(yōu)先級(jí)低的流量過濾掉,減輕系統(tǒng)的并發(fā)壓力。

        攔截器分層:

        • 網(wǎng)關(guān)和 WAF(Web Application Firewall,Web 應(yīng)用防火墻)

        采用封禁攻擊者來源 IP、拒絕帶有非法參數(shù)的請(qǐng)求、按來源 IP 限流、按用戶 ID 限流等方法

        • 風(fēng)控分析。借助大數(shù)據(jù)能力分析訂單等歷史業(yè)務(wù)數(shù)據(jù),對(duì)同ip多個(gè)賬號(hào)下單、或者下單后支付時(shí)間過快等行為有效識(shí)別,并給賬號(hào)打標(biāo)記,提供給業(yè)務(wù)團(tuán)隊(duì)使用。
        • 下游的每個(gè)tomcat實(shí)例應(yīng)用本地內(nèi)存緩存化,將一些庫存存儲(chǔ)在本地一份,做前置校驗(yàn)。當(dāng)然,為了盡量保持?jǐn)?shù)據(jù)的一致性,有定時(shí)任務(wù),從 Redis 中定時(shí)拉取最新的庫存數(shù)據(jù),并更新到本地內(nèi)存緩存中。



        高性能

        性能直接影響用戶的感官體驗(yàn),訪問一個(gè)系統(tǒng),如果超過5秒沒有響應(yīng),絕大數(shù)用戶會(huì)選擇離開。

        那么有哪些因素會(huì)影響系統(tǒng)的性能呢?

        • 用戶網(wǎng)絡(luò)環(huán)境
        • 請(qǐng)求/響應(yīng)的數(shù)據(jù)包大小
        • 業(yè)務(wù)系統(tǒng) CPU、內(nèi)存、磁盤等性能
        • 業(yè)務(wù)鏈路的長度
        • 下游系統(tǒng)的性能
        • 算法實(shí)現(xiàn)是否高效

        當(dāng)然,隨著并發(fā)數(shù)的提升,系統(tǒng)壓力增大,平均請(qǐng)求延遲也會(huì)增大。

        1、高性能緩存

        對(duì)一些熱點(diǎn)數(shù)據(jù)每次都從 DB 中讀取,會(huì)給 DB 帶來較大的壓力,導(dǎo)致性能大幅下降。所以,我們需要用緩存來提升熱點(diǎn)數(shù)據(jù)的訪問性能,比如將活動(dòng)信息數(shù)據(jù)在瀏覽器的緩存中保存一段時(shí)間。

        緩存根據(jù)性能由高到低分為:寄存器、L1緩存、L2緩存、L3緩存、本地內(nèi)存、分布式緩存

        上層的寄存器、L1 緩存、L2 緩存是位于 CPU 核內(nèi)的高速緩存,訪問延遲通常在 10 納秒以下。L3 緩存是位于 CPU 核外部但在芯片內(nèi)部的共享高速緩存,訪問延遲通常在十納秒左右。高速緩存具有成本高、容量小的特點(diǎn),容量最大的 L3 緩存通常也只有幾十MB。

        本地內(nèi)存是計(jì)算機(jī)內(nèi)的主存儲(chǔ)器,相比 CPU 芯片內(nèi)部的高速緩存,內(nèi)存的成本要低很多,容量通常是 GB 級(jí)別,訪問延遲通常在幾十到幾百納秒。

        內(nèi)存和高速緩存都屬于掉電易失的存儲(chǔ)器,如果機(jī)器斷電了,這類存儲(chǔ)器中的數(shù)據(jù)就丟失了。

        特別說明:在使用緩存時(shí),要注意緩存穿透、緩存雪崩、緩存熱點(diǎn)問題、緩存數(shù)據(jù)一致性問題。當(dāng)然為了提升整體性能通常會(huì)采用多級(jí)緩存組合方案(瀏覽器緩存+服務(wù)端本地內(nèi)存緩存+服務(wù)端網(wǎng)絡(luò)內(nèi)存緩存)

        2、日志優(yōu)化,避免IO瓶頸

        當(dāng)系統(tǒng)處理大量磁盤 IO 操作的時(shí)候,由于 CPU 和內(nèi)存的速度遠(yuǎn)高于磁盤,可能導(dǎo)致 CPU 耗費(fèi)太多時(shí)間等待磁盤返回處理的結(jié)果。對(duì)于這部分 CPU 在 IO 上的開銷,我們稱為 “iowait”。

        在IO中斷過程中,如果此時(shí)有其他任務(wù)線程可調(diào)度,系統(tǒng)會(huì)直接調(diào)度其他線程,這樣 CPU 就相應(yīng)顯示為 Usr 或 Sys;但是如果此時(shí)系統(tǒng)較空閑,無其他任務(wù)可以調(diào)度,CPU 就會(huì)顯示為 iowait(實(shí)際上與 idle 無本質(zhì)區(qū)別)。

        磁盤有個(gè)性能指標(biāo):IOPS,即每秒讀寫次數(shù),性能較好的固態(tài)硬盤,IOPS 大概在 3 萬左右。對(duì)于秒殺系統(tǒng),如果單節(jié)點(diǎn)QPS在10萬,每次請(qǐng)求產(chǎn)生3條日志,那么日志的寫入QPS在 30W/s,磁盤根本扛不住。

        Linux 有一種特殊的文件系統(tǒng):tmpfs(臨時(shí)文件系統(tǒng)),它是一種基于內(nèi)存的文件系統(tǒng),由操作系統(tǒng)管理。當(dāng)我們寫磁盤的時(shí)候?qū)嶋H是寫到內(nèi)存中,當(dāng)日志文件達(dá)到我們的設(shè)置閾值,操作系統(tǒng)會(huì)將日志寫到磁盤中,并將tmpfs中的日志文件刪除。

        這種批量化、順序?qū)?,大大提升了磁盤的吞吐性能!


        高可用

        高可用指標(biāo)是指用來衡量一個(gè)系統(tǒng)可用性有多高。

        • MTBF(Mean Time Between Failure),系統(tǒng)可用時(shí)長
        • MTTR(Mean Time To Repair),系統(tǒng)從故障后到恢復(fù)正常所耗費(fèi)的時(shí)間
        • SLA(Service-Level Agreement),服務(wù)等級(jí)協(xié)議,用于評(píng)估服務(wù)可用性等級(jí)。計(jì)算公式是 MTBF/(MTBF+MTTR)

        一般我們所說的可用性高于 99.99%,是指 SLA 高于 99.99%。

        技術(shù)架構(gòu),高可用有哪些策略?

        • 多云架構(gòu)、異地多活、異地備份
        • 主備切換,如redis緩存、mysql數(shù)據(jù)庫,主備節(jié)點(diǎn)會(huì)實(shí)時(shí)數(shù)據(jù)同步、備份。如果主節(jié)點(diǎn)不可用,自動(dòng)切換到備用節(jié)點(diǎn)
        • 微服務(wù),無狀態(tài)化架構(gòu),業(yè)務(wù)集群化部署,有心跳檢測(cè),能最短時(shí)間檢測(cè)到不可用的服務(wù)。
        • 通過熔斷、限流,解決流量過載問題,提供過載保護(hù)
        • 重視web安全,解決攻擊和XSS問題

        1、主備切換,縮減故障時(shí)間

        當(dāng)系統(tǒng)出現(xiàn)故障時(shí),首要任務(wù)不是立馬查找原因,考慮到故障的復(fù)雜樣,定位排查要花些時(shí)間,等問題修復(fù)好,SLA也降了好幾個(gè)檔。有沒有更快的方式解決這個(gè)問題?那就是故障轉(zhuǎn)移。

        當(dāng)發(fā)現(xiàn)故障節(jié)點(diǎn)的時(shí)候,不是嘗試修復(fù)它,而是立即把它隔離,同時(shí)將流量轉(zhuǎn)移到正常節(jié)點(diǎn)上。這樣通過故障轉(zhuǎn)移,不僅減少了 MTTR 提升了 SLA,還為修復(fù)故障節(jié)點(diǎn)贏得了足夠的時(shí)間。

        主備切換大致分為三步:

        • 第一步故障自動(dòng)偵測(cè)(Auto-detect),采用健康檢查、心跳等技術(shù)手段自動(dòng)偵測(cè)故障節(jié)點(diǎn);
        • 第二步自動(dòng)轉(zhuǎn)移(FailOver),當(dāng)偵測(cè)到故障節(jié)點(diǎn)后,采用摘除流量、脫離集群等方式隔離故障節(jié)點(diǎn),將流量轉(zhuǎn)移到正常節(jié)點(diǎn);
        • 第三步自動(dòng)恢復(fù)(FailBack),當(dāng)故障節(jié)點(diǎn)恢復(fù)正常后,自動(dòng)將其加入集群中,確保集群資源與故障前一致。

        2、熔斷,提供過載保護(hù)

        所謂過載保護(hù),是指負(fù)載超過系統(tǒng)的承載能力時(shí),系統(tǒng)會(huì)自動(dòng)采取保護(hù)措施,確保自身不被壓垮。

        熔斷就是在系統(tǒng)瀕臨崩潰的時(shí)候,立即中斷服務(wù),從而保障系統(tǒng)穩(wěn)定避免崩潰。它類似于電器中的“保險(xiǎn)絲”,當(dāng)電流過大的時(shí)候,“保險(xiǎn)絲”會(huì)先被燒掉,斷開電流,以免電路過熱燒毀電器引起火災(zāi)。

        例子:熔斷觸發(fā)條件往往跟系統(tǒng)節(jié)點(diǎn)的承載能力和服務(wù)質(zhì)量有關(guān),比如 CPU 的使用率超過 90%,請(qǐng)求錯(cuò)誤率超過 5%,請(qǐng)求延遲超過 500ms, 它們中的任意一個(gè)滿足條件就會(huì)出現(xiàn)熔斷。

        3、限流,提供過載保護(hù)

        限流的原理跟熔斷有點(diǎn)類似,都是通過判斷某個(gè)條件來確定是否執(zhí)行某個(gè)策略。但是又有所區(qū)別,熔斷觸發(fā)過載保護(hù),該節(jié)點(diǎn)會(huì)暫停服務(wù),直到恢復(fù)。限流,則是只處理自己能力范圍之內(nèi)的請(qǐng)求,超量的請(qǐng)求會(huì)被限流。

        限流算法主要有:計(jì)數(shù)器限流、滑動(dòng)窗口限流、令牌桶限流、漏桶限流。網(wǎng)上的資料很多,這里就不多贅述。

        4、降級(jí)

        比如電商大促,業(yè)務(wù)在峰值時(shí)刻,系統(tǒng)抵擋不住全部的流量時(shí),系統(tǒng)的負(fù)載、CPU 的使用率都超過了預(yù)警水位,可以對(duì)一些非核心的功能進(jìn)行降級(jí),降低系統(tǒng)壓力,比如把商品評(píng)價(jià)、成交記錄等功能臨時(shí)關(guān)掉。棄車保帥,保證 創(chuàng)建訂單、支付 等核心功能的正常使用

        當(dāng)然不同業(yè)務(wù)、不同公司處理方式也各不相同,需要結(jié)合實(shí)際場景,和業(yè)務(wù)方一塊討論,最后達(dá)成一個(gè)統(tǒng)一認(rèn)可的降級(jí)方案。

        總結(jié)下來:降級(jí)是通過暫時(shí)關(guān)閉某些非核心服務(wù)或者組件從而保護(hù)核心系統(tǒng)的可用性。


        推薦閱讀:
        億級(jí)系統(tǒng)的Redis緩存如何設(shè)計(jì)
        學(xué)會(huì)這10個(gè)設(shè)計(jì)原則,離架構(gòu)師又進(jìn)一步
        知乎高贊:為什么Kafka需要Leader而Redis不需要
        由淺入深逐步講解Java并發(fā)的半壁江山AQS
        再有人問你MySQL索引原理,就把這篇文章甩給他!

        關(guān)號(hào)互聯(lián)網(wǎng)全棧架構(gòu),價(jià)。

        瀏覽 57
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            星空传媒操逼 | caobiwangzhi | 国产三级片在线视频 | www欧美| 欧美三级午夜理伦三级老人 | 人人妻人人躁人人DVD | 久久少妇免费视频 | xxxx农村野外hd | 给大家科普一下八重神子大战史莱姆 | 干逼视频免费 |