性能優化涉及面很廣。一般而言,性能優化指降低響應時間和提高系統吞吐量兩個方面,但在流量高峰時候,性能問題往往會表現為服務可用性下降,所以性能優化也可以包括提高服務可用性。在某些情況下,降低響應時間、提高系統吞吐量和提高服務可用性三者相互矛盾,不可兼得。例如:增加緩存可以降低平均響應時間,但是處理線程數量會因為緩存過大而有所限制,從而降低系統吞吐量;為了提高服務可用性,對異常請求重復調用是一個常用的做法,但是這會提高響應時間并降低系統吞吐量。
對于很多像美團這樣的公司,它們的系統會面臨如下三個挑戰:1. 日益增長的用戶數量,2. 日漸復雜的業務,3. 急劇膨脹的數據。這些挑戰對于性能優化而言表現為:在保持和降低系統TP95響應時間(指的是將一段時間內的請求響應時間從低到高排序,高于95%請求響應時間的下確界)的前提下,不斷提高系統吞吐量,提升流量高峰時期的服務可用性。這種場景下,三者的目標和改進方法取得了比較好的一致。本文主要目標是為類似的場景提供優化方案,確保系統在流量高峰時期的快速響應和高可用。
文章第一部分是介紹,包括采用模式方式講解的優點,文章所采用案例的說明,以及后面部分用到的一些設計原則;第二部分介紹幾種典型的“性能惡化模式”,闡述導致系統性能惡化,服務可用性降低的典型場景以及形成惡化循環的過程;第三部分是文章重點,闡述典型的“性能優化模式”,這些模式或者可以使服務遠離“惡化模式”,或者直接對服務性能進行優化;文章最后一部分進行總結,并對未來可能出現的新模式進行展望。
介紹
模式講解方式
關于性能優化的文章和圖書已有很多,但就我所知,還沒有采用模式的方式去講解的。本文借鑒《設計模式》("Design Patterns-Elements of Reusable Object-Oriented Software")對設計模式的闡述方式,首先為每一種性能優化模式取一個貼切的名字,便于讀者快速理解和深刻記憶,接著講解該模式的動機和原理,然后結合作者在美團的具體工作案例進行深度剖析,最后總結采用該模式的優點以及需要付出的代價。簡而言之,本文采用“命名-->原理和動機-->具體案例-->缺點和優點”的四階段方式進行性能優化模式講解。與其他方式相比,采用模式進行講解有兩個方面的優點:一方面,讀者不僅僅能夠掌握優化手段,而且能夠了解采用該手段進行性能優化的場景以及所需付出的代價,這有利于讀者全面理解和靈活應用;另一方面,模式解決的是特定應用場景下的一類問題,所以應用場景描述貫穿于模式講解之中。如此,即使讀者對原理不太了解,只要碰到的問題符合某個特定模式的應用場景(這往往比理解原理要簡單),就可以采用對應的手段進行優化,進一步促進讀者對模式的理解和掌握。
案例說明
文章的所有案例都來自于美團的真實項目。出于兩方面的考慮,作者做了一定的簡化和抽象:一方面,系統可以優化的問題眾多,而一個特定的模式只能解決幾類問題,所以在案例分析過程中會突出與模式相關的問題;另一方面,任何一類問題都需要多維度數據去描述,而應用性能優化模式的前提是多維度數據的組合值超過了某個臨界點,但是精確定義每個維度數值的臨界點是一件很難的事情,更別說多維度數據組合之后臨界點。因此有必要對案例做一些簡化,確保相關取值范圍得到滿足。基于以上以及其他原因,作者所給出的解決方案只是可行性方案,并不保證其是所碰到問題的最佳解決方案。
案例涉及的所有項目都是基于Java語言開發的,嚴格地講,所有模式適用的場景是基于Java語言搭建的服務。從另外一方面講,Java和C++的主要區別在于垃圾回收機制,所以,除去和垃圾回收機制緊密相關的模式之外,文章所描述的模式也適用于采用C++語言搭建的服務。對于基于其他語言開發的服務,讀者在閱讀以及實踐的過程中需要考慮語言之間的差別。
設計原則
必須說明,本文中各種模式所要解決的問題之所以會出現,部分是因為工程師運用了某些深層次的設計原則。有些設計原則看上去和優秀的設計理念相悖,模式所解決的問題似乎完全可以避免,但是它們卻被廣泛使用。“存在即合理”,世界上沒有完美的設計方案,任何方案都是一系列設計原則的妥協結果,所以本文主要關注點是解決所碰到的問題而不是如何繞過這些設計原則。下面對文中重要的設計原則進行詳細闡述,在后面需要運用該原則時將不再解釋。
最小可用原則
最小可用原則(快速接入原則)有兩個關注點:1. 強調快速接入,快速完成;2. 實現核心功能可用。這是一個被普遍運用的原則,其目標是縮短測試周期,增加試錯機會,避免過度設計。為了快速接入就必須最大限度地利用已有的解決方案或系統。從另外一個角度講,一個解決方案或系統只要能夠滿足基本需求,就滿足最小可用原則的應用需求。過度強調快速接入原則會導致重構風險的增加,原則上講,基于該原則去設計系統需要為重構做好準備。
經濟原則
經濟原則關注的是成本問題,看起來很像最小可用原則,但是它們之間關注點不同。最小可用原則的目標是通過降低開發周期,快速接入而實現風險可控,而快速接入并不意味著成本降低,有時候為了實現快速接入可能需要付出巨大的成本。軟件項目的生命周期包括:預研、設計、開發、測試、運行、維護等階段。最小可用原則主要運用在預研階段,而經濟原則可以運用在整個軟件生命周期里,也可以只關注某一個或者幾個階段。例如:運行時經濟原則需要考慮的系統成本包括單次請求的CPU、內存、網絡、磁盤消耗等;設計階段的經濟原則要求避免過度設計;開發階段的經濟原則可能關注代碼復用,工程師資源復用等。
代碼復用原則
代碼復用原則分為兩個層次:第一個層次使用已有的解決方案或調用已存在的共享庫(Shared Library),也稱為方案復用;第二個層次是直接在現有的代碼庫中開發,也稱之為共用代碼庫。
方案復用是一個非常實用主義的原則,它的出發點就是最大限度地利用手頭已有的解決方案,即使這個方案并不好。方案的形式可以是共享庫,也可以是已存在的服務。方案復用的例子參見避免蚊子大炮模式的具體案例。用搜索引擎服務來解決查找附近商家的問題是一個性能很差的方案,但仍被很多工程師使用。方案復用原則的一個顯著優點就是提高生產效率,例如:Java之所以能夠得到如此廣泛應用,原因之一就是有大量可以重復利用的開源庫。實際上“Write once, run anywhere”是Java語言最核心的設計理念之一。基于Java語言開發的代碼庫因此得以在不同硬件平臺、不同操作系統上更廣泛地使用。
共用代碼庫要求在同一套代碼庫中完成所有功能開發。采用這個原則,代碼庫中的所有功能編譯時可見,新功能代碼可以無邊界的調用老代碼。另外,原代碼庫已存在的各種運行、編譯、測試、配置環境可復用。主要有兩個方面地好處:1. 充分利用代碼庫中已有的基礎設施,快速接入新業務;2. 直接調用原代碼中的基礎功能或原 主站蜘蛛池模板: 唐海县| 安塞县| 晋城| 郎溪县| 井研县| 神木县| 当雄县| 舟山市| 息烽县| 皮山县| 慈溪市| 米林县| 上饶市| 双江| 罗平县| 永昌县| 大田县| 郧西县| 宝丰县| 安阳市| 靖远县| 会宁县| 扬州市| 伊宁县| 通江县| 图木舒克市| 长子县| 贺兰县| 旌德县| 江山市| 谷城县| 伊宁市| 台南市| 昭平县| 华容县| 巨野县| 宁武县| 东兴市| 右玉县| 宜兰县| 大化|