<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ā)的性能優(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)時你們是怎么處理的呢?接下來,我會重點從性能優(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)就卡頓、甚至宕機等等。可以說,性能優(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點出發(fā)到達(dá)B點的汽車最多只有10輛。假設(shè)上級部門想提升這塊路段的車流量,我們該怎么辦?

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

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

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

          我們先來看下性能優(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ā)、測試和運維,其中,運維負(fù)責(zé)提供一些監(jiān)控數(shù)據(jù),測試負(fù)責(zé)提供一些壓測數(shù)據(jù),開發(fā)基于壓測、監(jiān)控數(shù)據(jù),明確具體的優(yōu)化點以及優(yōu)化手段;從產(chǎn)品維度出發(fā),性能優(yōu)化是業(yè)務(wù)功能的一部分,是為了滿足某些業(yè)務(wù)場景。于是,在做性能優(yōu)化時,一般會考慮以下幾點:
          (1)本次性能優(yōu)化的業(yè)務(wù)場景是什么,有哪些場景需要優(yōu)化;
          (2)這些場景的運維監(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)化此場景需要耗費較大人力,那么,這個投入就是不值得的;然后再從技術(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é)點,所有節(jié)點的處理時間加起來才是用戶請求的處理時間,如果其中任意一個節(jié)點性能有問題,系統(tǒng)整體的性能就會上不去。而且,由于節(jié)點自身差異性,其性能提升的方法也會不一樣,但總體概括起來,可以分為兩大類:提升單個請求處理效率;并行處理多個請求。
          2.2.1 提升單個請求處理效率
          這種方式,簡單來說,就是一個外部請求進(jìn)來后,讓其在盡可能短的時間內(nèi)處理完成。常見的方法有以下幾種:
          (1)提升調(diào)用鏈上各節(jié)點的處理速度
          從技術(shù)角度考慮:在數(shù)據(jù)庫層面,可以考慮加索引、讀寫分離、分庫分表等;在應(yīng)用層層面,可以考慮加緩存(本地緩存,分布式緩存,或兩者疊加)、復(fù)雜查詢走ES索引;在代碼編寫時,可以考慮更高效的算法和數(shù)據(jù)結(jié)構(gòu),比如:讀多寫少用數(shù)組、寫多讀少用鏈表、取余采用位運算等。
          從業(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)了一套并行處理框架,并成功運用到了商品詳情頁加載場景中。
          (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é)點分別處理這些請求,或者節(jié)點內(nèi)部做并行處理。比如:節(jié)點采用集群部署,并通過負(fù)載均衡策略,將用戶請求分?jǐn)偟讲煌墓?jié)點進(jìn)行處理;節(jié)點內(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)的問題點有:
          (1)依賴的部分非核心接口沒有加緩存、做降級,導(dǎo)致整個請求失敗;
          (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)用。
          針對上述這些問題點,我們當(dāng)時主要從以下幾點去做了優(yōu)化:
          優(yōu)化前,我們重新梳理了整個調(diào)用鏈上,接口的強弱依賴關(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。
          • 降級策略
          接口接入熔斷降級機制,并對異常做捕獲,返回默認(rèn)值。
          (2)針對強依賴接口,從超時時間、重試策略、緩存策略三個層面做了優(yōu)化
          • RPC調(diào)用超時時間設(shè)置策略
          統(tǒng)計出強依賴接口 TP99 的RT,設(shè)置它們的超時時間為 (1 + 50%) (TP99)
          • 重試策略
          根據(jù)接口RT波動性,基于dubbo的重試機制,設(shè)置重試次數(shù)為2或3次。
          • 緩存策略
          對于商品基礎(chǔ)信息,考慮到“緩存預(yù)熱”、“熱點訪問”等問題,接入了公司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)定的原子化接口
          在問題點(3)、(4)中有提到,上游調(diào)用方使用了下游不太合適的接口。由于歷史原因,當(dāng)前下游服務(wù)方中有特別多的查詢類接口,且很多查詢類接口在功能上都是重疊的。本次我們針對查詢類接口,按照其返參字段使用場景的不同,提供了三種不同粒度的通用類原子化接口,之后所有的查詢類需求,都會強制要求上游調(diào)用方從這三類接口中選擇。這三類接口如下:
          • 粗粒度:返回最基本字段

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

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

          四、總結(jié)

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

            end





            ?
            瀏覽 16
            點贊
            評論
            收藏
            分享

            手機掃一掃分享

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

            手機掃一掃分享

            分享
            舉報
            <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>
                    大香蕉综合娱乐网 | 一区二区三区韩国av夜夜骚 | 小宝精品一区二区三区 | 免费看男女日逼吧 | 黄色a一级片免费看 |