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ā)的性能優(yōu)化思考

        共 5347字,需瀏覽 11分鐘

         ·

        2020-10-11 21:34


        在假期某個夜黑風(fēng)高的晚上,商家正在直播間如火如荼的做著直播,突然間屏幕卡頓,隨后屏幕上出現(xiàn)大大的“404”,緊接著大量的客訴、告警撲面而來。好在有贊教育的技術(shù)團(tuán)隊響應(yīng)及時,再經(jīng)過很短時間的問題分析后,迅速的恢復(fù)了系統(tǒng),保障了商家直播順利進(jìn)行。這故障到底是怎么產(chǎn)生的呢?經(jīng)排查是因為在流量高峰時,系統(tǒng)在性能、可用性方面存在不足導(dǎo)致的。那當(dāng)時你們是怎么處理的呢?接下來,我會重點(diǎn)從性能優(yōu)化這塊出發(fā),先普及下性能優(yōu)化的基本概念,然后再簡述下常用的性能優(yōu)化手段,最后給出這個故障我們當(dāng)時的應(yīng)對之道。

        一、什么是性能優(yōu)化

        正如熵增定律描述的那樣,在一個孤立的系統(tǒng)里,如果沒有外力做工,其總混亂度(即熵)會不斷增大,直至系統(tǒng)徹底變得無序。在軟件服務(wù)領(lǐng)域亦是如此:從應(yīng)用系統(tǒng)上線那一刻開始,隨著用戶量的增加、業(yè)務(wù)功能的持續(xù)迭代,系統(tǒng)會面臨各種不同程度的挑戰(zhàn),如果不及時采取優(yōu)化措施,我們會發(fā)現(xiàn)諸多問題,比如:系統(tǒng)怎么越來越慢了,流量一高系統(tǒng)就卡頓、甚至宕機(jī)等等??梢哉f,性能優(yōu)化是貫穿在整個軟件生命周期之中的。

        1.1 性能衡量指標(biāo)

        在衡量系統(tǒng)性能基線時,一般會從接口“響應(yīng)時間”和“并發(fā)能力”兩個維度考慮。
        (1)響應(yīng)時間(RT)
        所謂響應(yīng)時間,是指完成某一功能所需要的時間,一般可以通過“平均響應(yīng)時間”、“百分位數(shù)”等指標(biāo)來考量。
        • 平均響應(yīng)時間(AVG)
        該指標(biāo)反映的是接口的平均處理能力,計算方式是:將接口請求所有的響應(yīng)時間疊加起來,然后除以總的請求次數(shù)。舉個例子:接口A總共發(fā)起了8次請求,其中,有1次3ms,3次5ms,4次6ms,那么此接口的平均響應(yīng)時間就是 (1 * 3 + 3 * 5 + 4 * 6) / 8 = 5.25ms 。
        • 百分位數(shù)(Top Percentile)
        一種統(tǒng)計學(xué)術(shù)語,反映的是超過n%的請求都在m時間內(nèi)返回,一般用TPn=m來描述,比如:TP99=5,表示超過99%的請求都能在5ms內(nèi)返回。它的計算方式是:將接口的響應(yīng)時間按從小到大的順序進(jìn)行排列,取特定百分位的耗時,即為該接口的百分位數(shù)。舉個例子:接口A總共發(fā)起了100次請求,響應(yīng)時間依次是1、2、3、...、100,那么,TP95就是95ms。
        一般而言,百分位數(shù)更能反映接口的整體響應(yīng)情況,因為在高并發(fā)場景中,常常會出現(xiàn)一些長尾請求,如果采用平均響應(yīng)時間去衡量,由于長尾請求會被大量低RT平均掉(此時很多用戶的請求已經(jīng)很慢了),進(jìn)而無法及時感知真實業(yè)務(wù)狀況。舉個例子:接口A有100次請求,其中97次1ms,3次100ms,平均響應(yīng)時間為 (1 * 97 + 3 * 100) / 100 = 3.97ms,此時3.97ms并不能真實反映接口的整體性能,因為其中97次請求RT才1ms。
        (2)并發(fā)能力
        并發(fā)能力一般用QPS或TPS來衡量。QPS指的是每秒請求數(shù),TPS是指每秒事務(wù)數(shù)。一般在做性能評估時,TPS用的比較多。

        1.2 性能優(yōu)化本質(zhì)

        在算法領(lǐng)域,評價一個算法的效率如何,主要會看它的時間復(fù)雜度和空間復(fù)雜度情況。同理,如果將“響應(yīng)時間”比作時間維度的話,“并發(fā)能力”可類比為空間維度。那么,在做性能優(yōu)化時,本質(zhì)上也是從“優(yōu)化時間”、“優(yōu)化空間”、“時空互換(用時間換空間或用空間換時間)”三個方向去思考,然后在空間、時間上不停地做取舍。
        舉一個生活中的例子來說明下。圖1-1是一條長度為5km的道路,道路的限速是50km/h,同時,規(guī)定在任何時刻,車道上有且僅有一輛汽車。那么,在1h內(nèi),從A點(diǎn)出發(fā)到達(dá)B點(diǎn)的汽車最多只有10輛。假設(shè)上級部門想提升這塊路段的車流量,我們該怎么辦?

        圖1-1 單車道限速50km/h

        第一種方式,可以增加車道數(shù)(空間維度):將道路從單車道變?yōu)槎嘬嚨?,比如增加?車道,那么,在1h內(nèi),從A點(diǎn)出發(fā)到達(dá)B點(diǎn)的汽車數(shù)可提量到60輛,見圖1-2。
        圖1-2 六車道限速50km/h
        第二種方式,道路提速(時間維度):將道路限速從50km/h提升到100km/h,那么,在1h內(nèi),從A點(diǎn)出發(fā)到達(dá)B點(diǎn)的汽車數(shù)可提量到20輛,見圖1-3。
        圖1-3 單車道限速100km/h
        二、怎么做性能優(yōu)化

        2.1 系統(tǒng)性思考性能優(yōu)化點(diǎn)

        我們先來看下性能優(yōu)化的落地過程,性能優(yōu)化是由人來執(zhí)行,然后服務(wù)于產(chǎn)品的,人和產(chǎn)品共同參與性能優(yōu)化的落地,見圖2-1。
        圖2-1 性能優(yōu)化落地過程
        從人維度出發(fā),性能優(yōu)化是屬于技術(shù)團(tuán)隊的,技術(shù)團(tuán)隊包括開發(fā)、測試和運(yùn)維,其中,運(yùn)維負(fù)責(zé)提供一些監(jiān)控數(shù)據(jù),測試負(fù)責(zé)提供一些壓測數(shù)據(jù),開發(fā)基于壓測、監(jiān)控數(shù)據(jù),明確具體的優(yōu)化點(diǎn)以及優(yōu)化手段;從產(chǎn)品維度出發(fā),性能優(yōu)化是業(yè)務(wù)功能的一部分,是為了滿足某些業(yè)務(wù)場景。于是,在做性能優(yōu)化時,一般會考慮以下幾點(diǎn):
        (1)本次性能優(yōu)化的業(yè)務(wù)場景是什么,有哪些場景需要優(yōu)化;
        (2)這些場景的運(yùn)維監(jiān)控數(shù)據(jù)、測試壓測數(shù)據(jù)是什么,要優(yōu)化哪里;
        (3)這些數(shù)據(jù)里面反映的系統(tǒng)瓶頸在哪里,如何去優(yōu)化;
        (4)重復(fù)(2)、(3)過程,直至滿足優(yōu)化目標(biāo)。
        結(jié)合性能優(yōu)化的本質(zhì),整個優(yōu)化過程其實就是:先從業(yè)務(wù)需求角度出發(fā),思考待優(yōu)化場景是否值得投入,比如:一個任務(wù)每次需要跑半小時,從技術(shù)層面,可以做下優(yōu)化,但結(jié)合業(yè)務(wù)情況卻發(fā)現(xiàn),此任務(wù)的執(zhí)行頻次是每周一次,如果優(yōu)化此場景需要耗費(fèi)較大人力,那么,這個投入就是不值得的;然后再從技術(shù)實現(xiàn)角度出發(fā),不停地去思考怎么優(yōu)化時間、怎么優(yōu)化空間、怎么犧牲空間換時間、怎么犧牲時間換空間等問題??傊?,我們在做性能優(yōu)化時,需要以一個更全面的視角去看待它,避免進(jìn)入頭痛醫(yī)頭腳痛醫(yī)腳的誤區(qū)。

        2.2 常見性能優(yōu)化方式

        在實際業(yè)務(wù)場景中,一個外部請求進(jìn)入系統(tǒng)后,會先后經(jīng)歷多個軟硬件節(jié)點(diǎn),所有節(jié)點(diǎn)的處理時間加起來才是用戶請求的處理時間,如果其中任意一個節(jié)點(diǎn)性能有問題,系統(tǒng)整體的性能就會上不去。而且,由于節(jié)點(diǎn)自身差異性,其性能提升的方法也會不一樣,但總體概括起來,可以分為兩大類:提升單個請求處理效率;并行處理多個請求。
        2.2.1 提升單個請求處理效率
        這種方式,簡單來說,就是一個外部請求進(jìn)來后,讓其在盡可能短的時間內(nèi)處理完成。常見的方法有以下幾種:
        (1)提升調(diào)用鏈上各節(jié)點(diǎn)的處理速度
        從技術(shù)角度考慮:在數(shù)據(jù)庫層面,可以考慮加索引、讀寫分離、分庫分表等;在應(yīng)用層層面,可以考慮加緩存(本地緩存,分布式緩存,或兩者疊加)、復(fù)雜查詢走ES索引;在代碼編寫時,可以考慮更高效的算法和數(shù)據(jù)結(jié)構(gòu),比如:讀多寫少用數(shù)組、寫多讀少用鏈表、取余采用位運(yùn)算等。
        從業(yè)務(wù)角度考慮:盡量避免重復(fù)查詢;對于一些查詢類操作,盡可能采用批量查詢;上游調(diào)用方盡可能使用更合適的下游接口,比如:下游服務(wù)方有分別返回A、B、AB的三類接口,如果上游使用方僅需要A信息,應(yīng)使用A接口;如果同時需要AB信息,應(yīng)使用AB接口,而不是依次調(diào)用A、B接口,再在內(nèi)存中做聚合。
        (2)請求內(nèi)部做并行化處理
        這種思想,就是將單個請求拆分為多個子請求,各子請求并行處理,最后對子請求結(jié)果合并后返回。在實踐中,我們基于 CompletableFuture 實現(xiàn)了一套并行處理框架,并成功運(yùn)用到了商品詳情頁加載場景中。
        (3)請求處理異步化
        此思想,最典型的方法是采用消息隊列,比如:下單操作時,除了扣減庫存、生成訂單外,還會給用戶發(fā)送支付成功消息、贈送積分等后置操作。對于這些非核心的后置流程,可以采用消息隊列做異步化處理,以此提升下單接口的性能。其他一些方法還有:在進(jìn)程內(nèi),另開一個線程執(zhí)行這些非核心流程;或者先將非核心操作數(shù)據(jù)暫存在某種介質(zhì)(DB表、redis等)中,然后采用定時任務(wù)定期掃描并執(zhí)行這些操作。
        2.2.2 并行處理多個請求
        字面意思來看,就是當(dāng)有多個外部請求進(jìn)來時,可以讓系統(tǒng)內(nèi)部多個節(jié)點(diǎn)分別處理這些請求,或者節(jié)點(diǎn)內(nèi)部做并行處理。比如:節(jié)點(diǎn)采用集群部署,并通過負(fù)載均衡策略,將用戶請求分?jǐn)偟讲煌墓?jié)點(diǎn)進(jìn)行處理;節(jié)點(diǎn)內(nèi)部采用線程池,通過另開線程來實現(xiàn)。

        三、我們是怎么做的

        在具體講述之前,先帶大家一起熟悉下當(dāng)時的業(yè)務(wù)場景:用戶首先訪問直播商品詳情頁,然后購買此商品,緊接著再次訪問詳情頁面時,會出現(xiàn)直播間入口,在進(jìn)入直播間之前,會做一次權(quán)限校驗,校驗通過后,方才可以進(jìn)入直播間與講師進(jìn)行互動。詳細(xì)的流程可見圖3-1 。
        圖3-1 直播間進(jìn)入流程
        從上述流程中,可清晰看出,主要涉及到三種外部請求:查詢直播商品詳情;商品下單;進(jìn)入直播間前做用戶權(quán)限校驗。當(dāng)時通過流量監(jiān)控數(shù)據(jù)以及日志分析發(fā)現(xiàn),性能瓶頸主要在“直播商品詳情加載”這一環(huán)節(jié)。
        直播商詳這塊,主要是因為上游服務(wù)的請求量超過了下游服務(wù)能承受的吞吐量,導(dǎo)致大量RPC調(diào)用超時。具體反應(yīng)的問題點(diǎn)有:
        (1)依賴的部分非核心接口沒有加緩存、做降級,導(dǎo)致整個請求失?。?/span>
        (2)依賴的部分核心接口性能較差,導(dǎo)致后續(xù)請求一直被阻塞,直至超時異常返回;
        (3)下游服務(wù)提供的查詢接口比較重量級,但上游服務(wù)僅需要返參中的部分字段,導(dǎo)致單次查詢RT一直下不去;
        (4)上游調(diào)用方使用了錯誤的下游接口,比如上游調(diào)用方本來可以調(diào)用一次詳細(xì)信息查詢接口,便能獲取所有需要的信息,可實際中,卻先后調(diào)用了兩種查信息的接口,才拿到完整的信息;
        (5)無狀態(tài)查詢接口沒有加緩存,導(dǎo)致了頻繁的RPC調(diào)用。
        針對上述這些問題點(diǎn),我們當(dāng)時主要從以下幾點(diǎn)去做了優(yōu)化:
        優(yōu)化前,我們重新梳理了整個調(diào)用鏈上,接口的強(qiáng)弱依賴關(guān)系,以及每個接口的RT情況
        (1) 針對弱依賴接口,從超時時間、緩存策略、降級策略三個層面進(jìn)行了優(yōu)化
        • RPC調(diào)用超時時間設(shè)置策略
        統(tǒng)計出弱依賴接口 TP99(RT較穩(wěn)定的接口)/ TP95 (RT波動較大接口)的RT,設(shè)置它們的超時時間為 (1 + 50%) (TP99 或 TP95)
        這里講下為什么要這樣設(shè)置超時時間:一般我們會設(shè)置超時時間為2s或3s,但每個接口的RT是不一樣的,比如:接口A的RT穩(wěn)定在100ms內(nèi),那么,如果超時時間是2s,假若接口A超時了,本次RT至少是2s,但如果超時時間設(shè)置為100ms,且我們加了1次重試,那么,本次請求的RT不會超過200ms,同時,重試時接口很大概率會正常返回結(jié)果。
        • 緩存策略
        給接口添加前置緩存。我們采用了公司自研的分布式緩存zanKV,緩存的更新策略是:采用了兩個緩存,緩存A和緩存B(緩存A的失效時間為m分鐘,緩存B為n分鐘,且n>2m),首先從緩存A讀數(shù)據(jù),有則直接返回,沒有則從B讀數(shù)據(jù),并在返回之前,異步啟動一個更新線程,同時更新緩存A和緩存B。
        • 降級策略
        接口接入熔斷降級機(jī)制,并對異常做捕獲,返回默認(rèn)值。
        (2)針對強(qiáng)依賴接口,從超時時間、重試策略、緩存策略三個層面做了優(yōu)化
        • RPC調(diào)用超時時間設(shè)置策略
        統(tǒng)計出強(qiáng)依賴接口 TP99 的RT,設(shè)置它們的超時時間為 (1 + 50%) (TP99)
        • 重試策略
        根據(jù)接口RT波動性,基于dubbo的重試機(jī)制,設(shè)置重試次數(shù)為2或3次。
        • 緩存策略
        對于商品基礎(chǔ)信息,考慮到“緩存預(yù)熱”、“熱點(diǎn)訪問”等問題,接入了公司TMC(透明多級緩存),具體說明可見文檔 https://mp.weixin.qq.com/s/BnWtbetNq076iRRZfnGRrw ;對于其他一些無狀態(tài)查詢信息,采用了本地緩存Guava。
        (3)商品詳情信息聚合操作并行化
        商品詳情頁面是一個聚合類信息展示窗口,它除了商品基礎(chǔ)信息外,還包括A、B、C等內(nèi)容(出于商業(yè)保密性,這里泛化內(nèi)容名稱),且這里的A、B、C和商品基礎(chǔ)信息四者間是沒有任何前后依賴關(guān)系的。當(dāng)時我們將商品詳情加載拆分為了4個子任務(wù),并采用教育后端團(tuán)隊自研的并行處理框架,對子任務(wù)做了并行化處理,并聚合返回,較大提升了接口RT性能。
        (4)查詢類接口能力收攏,下游服務(wù)方提供穩(wěn)定的原子化接口
        在問題點(diǎn)(3)、(4)中有提到,上游調(diào)用方使用了下游不太合適的接口。由于歷史原因,當(dāng)前下游服務(wù)方中有特別多的查詢類接口,且很多查詢類接口在功能上都是重疊的。本次我們針對查詢類接口,按照其返參字段使用場景的不同,提供了三種不同粒度的通用類原子化接口,之后所有的查詢類需求,都會強(qiáng)制要求上游調(diào)用方從這三類接口中選擇。這三類接口如下:
        • 粗粒度:返回最基本字段

        • 中粒度:返回經(jīng)常使用的字段

        • 細(xì)粒度:返回詳細(xì)信息

        四、總結(jié)

        產(chǎn)品功能是持續(xù)迭代的,性能優(yōu)化也不是一蹴而就的事,大家在遇到性能問題時,可以參考本文提到的一些方法,做一些針對性的優(yōu)化。同時,針對同一個節(jié)點(diǎn),在不同的時刻,其優(yōu)化點(diǎn)也可能不一樣,比如:新功能剛上線時,查詢性能的提升可能僅僅通過加索引的方式便能解決,但隨著功能的不斷疊加,后續(xù)的優(yōu)化方向可能是“盡量走批量查詢”、“加緩存”等方向。所以,性能優(yōu)化還是要遵循“具體案例具體分析”這一基本原則。鑒于作者經(jīng)驗有限,我對性能優(yōu)化的理解難免會有不足之處,歡迎大家共同探討,共同提高。
        (附上內(nèi)推郵箱:[email protected],歡迎加入有贊教育團(tuán)隊)

          end





          ?
          瀏覽 16
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          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>
              操逼网av | 亚洲国产日韩在线 | 老师让我她我爽了好久动漫 | 操逼极品骚货网站观看 | 天天狠狠操 | 天天综合人 | 久久久ww | 人人妻人人澡人人爽 | 99热这里只有精品在线观看 | 国产午夜精品一区二区在线观看 |