<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 4231字,需瀏覽 9分鐘

           ·

          2021-06-08 14:58

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

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

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

          接下來,我們重點來介紹這 三高


          高并發(fā)


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


          1、負載均衡

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

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

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

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

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

          2、池化技術

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

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

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


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

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

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

          3、流量漏斗

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

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

          攔截器分層:

          • 網(wǎng)關和 WAF(Web Application Firewall,Web 應用防火墻)

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

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



          高性能

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

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

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

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

          1、高性能緩存

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

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

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

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

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

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

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

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

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

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

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

          這種批量化、順序?qū)懀蟠筇嵘舜疟P的吞吐性能!


          高可用

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

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

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

          技術架構,高可用有哪些策略?

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

          1、主備切換,縮減故障時間

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

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

          主備切換大致分為三步:

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

          2、熔斷,提供過載保護

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

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

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

          3、限流,提供過載保護

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

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

          4、降級

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

          當然不同業(yè)務、不同公司處理方式也各不相同,需要結合實際場景,和業(yè)務方一塊討論,最后達成一個統(tǒng)一認可的降級方案。

          總結下來:降級是通過暫時關閉某些非核心服務或者組件從而保護核心系統(tǒng)的可用性。


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

          互聯(lián)網(wǎng)全棧架構

          瀏覽 57
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  视频一区免费 | 久久久成人影片 | 成人69视频 | 色影音先锋色资源网站 | 免费看无码一级A片放24小时 |