天天看點

性能優化與測試:系統監控、應用監控的思路

起始

在實際的性能分析中,一個很常見的現象是,明明發生了性能瓶頸,但當你登入到伺服器中想要排查的時候,卻發現瓶頸已經消失了。或者說,性能問題總是時不時地發生,但卻很難找出發生規律,也很難重制。

而要解決這個問題,就要搭建監控系統,把系統和應用程式的運作狀況監控起來,并定義一系列的政策,在發生問題時第一時間告警通知。一個好的監控系統,不僅可以實時暴露系統的各種問題,更可以根據這些監控到的狀态,自動分析和定位大緻的瓶頸來源,進而更精确地把問題彙報給相關團隊處理。要做好監控,最核心的就是全面的、可量化的名額,這包括系統和應用兩個方面。

從系統來說,監控系統要涵蓋系統的整體資源使用情況,比如我們前面講過的 CPU、記憶體、磁盤和檔案系統、網絡等各種系統資源。

而從應用程式來說,監控系統要涵蓋應用程式内部的運作狀态,這既包括程序的 CPU、磁盤 I/O 等整體運作狀況,更需要包括諸如接口調用耗時、執行過程中的錯誤、内部對象的記憶體使用等應用程式内部的運作狀況。

系統監控

USE 法

在開始監控系統之前,你肯定最想知道,怎麼才能用簡潔的方法,來描述系統資源的使用情況。你當然可以使用專欄中學到的各種性能工具,來分别收集各種資源的使用情況。不過不要忘記,每種資源的性能名額可都有很多,使用過多名額本身耗時耗力不說,也不容易為你建立起系統整體的運作狀況。

在這裡,我為你介紹一種專門用于性能監控的 USE(Utilization Saturation and Errors)法。

USE 法把系統資源的性能名額,簡化成了三個類别,即使用率、飽和度以及錯誤數。

  • 使用率,表示資源用于服務的時間或容量百分比。100% 的使用率,表示容量已經用盡或者全部時間都用于服務。
  • 飽和度,表示資源的繁忙程度,通常與等待隊列的長度相關。100% 的飽和度,表示資源無法接受更多的請求。
  • 錯誤數表示發生錯誤的事件個數。錯誤數越多,表明系統的問題越嚴重。

這三個類别的名額,涵蓋了系統資源的常見性能瓶頸,是以常被用來快速定位系統資源的性能瓶頸。這樣,無論是對 CPU、記憶體、磁盤和檔案系統、網絡等硬體資源,還是對檔案描述符數、連接配接數、連接配接跟蹤數等軟體資源,USE 方法都可以幫你快速定位出,是哪一種系統資源出現了性能瓶頸。

性能名額

那麼,對于每一種系統資源,又有哪些常見的性能名額呢?回憶一下我們講過的各種系統資源原理,并不難想到相關的性能名額。這裡,我把常見的性能名額畫了一張表格,友善你在需要時檢視。

性能優化與測試:系統監控、應用監控的思路

不過,需要注意的是,USE 方法隻關注能展現系統資源性能瓶頸的核心名額,但這并不是說其他名額不重要。諸如系統日志、程序資源使用量、緩存使用量等其他各類名額,也都需要我們監控起來。隻不過,它們通常用作輔助性能分析,而 USE 方法的名額,則直接表明了系統的資源瓶頸。

監控系統

掌握 USE 方法以及需要監控的性能名額後,接下來要做的,就是建立監控系統,把這些名額儲存下來;然後,根據這些監控到的狀态,自動分析和定位大緻的瓶頸來源;最後,再通過告警系統,把問題及時彙報給相關團隊處理。

可以看出,一個完整的監控系統通常由資料采集、資料存儲、資料查詢和處理、告警以及可視化展示等多個子產品組成。是以,要從頭搭建一個監控系統,其實也是一個很大的系統工程。

不過,幸運的是,現在已經有很多開源的監控工具可以直接使用,比如最常見的 Zabbix、Nagios、Prometheus 等等。

下面,我就以 Prometheus 為例,為你介紹這幾個元件的基本原理。如下圖所示,就是 Prometheus 的基本架構:

性能優化與測試:系統監控、應用監控的思路

(圖檔來自 prometheus.io)

先看資料采集子產品。最左邊的 Prometheus targets 就是資料采集的對象,而 Retrieval 則負責采集這些資料。從圖中你也可以看到,Prometheus 同時支援 Push 和 Pull 兩種資料采集模式。

  • Pull 模式,由伺服器端的采集子產品來觸發采集。隻要采集目标提供了 HTTP 接口,就可以自由接入(這也是最常用的采集模式)。
  • Push 模式,則是由各個采集目标主動向 Push Gateway(用于防止資料丢失)推送名額,再由伺服器端從 Gateway 中拉取過去(這是移動應用中最常用的采集模式)。

第二個是資料存儲子產品。為了保持監控資料的持久化,圖中的 TSDB(Time series database)子產品,負責将采集到的資料持久化到 SSD 等磁盤裝置中。TSDB 是專門為時間序列資料設計的一種資料庫,特點是以時間為索引、資料量大并且以追加的方式寫入。

第三個是資料查詢和處理子產品。剛才提到的 TSDB,在存儲資料的同時,其實還提供了資料查詢和基本的資料處理功能,而這也就是 PromQL 語言。PromQL 提供了簡潔的查詢、過濾功能,并且支援基本的資料處理方法,是告警系統和可視化展示的基礎。

第四個是告警子產品。右上角的 AlertManager 提供了告警的功能,包括基于 PromQL 語言的觸發條件、告警規則的配置管理以及告警的發送等。不過,雖然告警是必要的,但過于頻繁的告警顯然也不可取。是以,AlertManager 還支援通過分組、抑制或者靜默等多種方式來聚合同類告警,并減少告警數量。

最後一個是可視化展示子產品。Prometheus 的 web UI 提供了簡單的可視化界面,用于執行 PromQL 查詢語句,但結果的展示比較單調。不過,一旦配合 Grafana,就可以建構非常強大的圖形界面了。介紹完了這些元件,想必你對每個子產品都有了比較清晰的認識。接下來,我們再來繼續深入了解這些元件結合起來的整體功能。比如,以剛才提到的 USE 方法為例,我使用 Prometheus,可以收集 Linux 伺服器的 CPU、記憶體、磁盤、網絡等各類資源的使用率、飽和度和錯誤數名額。然後,通過 Grafana 以及 PromQL 查詢語句,就可以把它們以圖形界面的方式直覺展示出來。

性能優化與測試:系統監控、應用監控的思路

最後總結

系統監控的核心是資源的使用情況,這既包括 CPU、記憶體、磁盤、檔案系統、網絡等硬體資源,也包括檔案描述符數、連接配接數、連接配接跟蹤數等軟體資源。而要描述這些資源瓶頸,最簡單有效的方法就是 USE 法。

USE 法把系統資源的性能名額,簡化為了三個類别:使用率、飽和度以及錯誤數。 當這三者之中任一類别的名額過高時,都代表相對應的系統資源可能存在性能瓶頸。

基于 USE 法建立性能名額後,我們還需要通過一套完整的監控系統,把這些名額從采集、存儲、查詢、處理,再到告警和可視化展示等貫穿起來。這樣,不僅可以将系統資源的瓶頸快速暴露出來,還可以借助監控的曆史資料,來追蹤定位性能問題的根源。

應用監控

應用監控名額

跟系統監控一樣,在建構應用程式的監控系統之前,首先也需要确定,到底需要監控哪些名額。特别是要清楚,有哪些名額可以用來快速确認應用程式的性能問題。

應用程式的核心名額,不再是資源的使用情況,而是請求數、錯誤率和響應時間。

這些名額不僅直接關系到使用者的使用體驗,還反映應用整體的可用性和可靠性。有了請求數、錯誤率和響應時間這三個黃金名額之後,我們就可以快速知道,應用是否發生了性能問題。但是,隻有這些名額顯然還是不夠的,因為發生性能問題後,我們還希望能夠快速定位“性能瓶頸區”。是以,在我看來,下面幾種名額,也是監控應用程式時必不可少的。

第一個,是應用程序的資源使用情況,比如程序占用的 CPU、記憶體、磁盤 I/O、網絡等。使用過多的系統資源,導緻應用程式響應緩慢或者錯誤數升高,是一個最常見的性能問題。

第二個,是應用程式之間調用情況,比如調用頻率、錯誤數、延時等。由于應用程式并不是孤立的,如果其依賴的其他應用出現了性能問題,應用自身性能也會受到影響。

第三個,是應用程式内部核心邏輯的運作情況,比如關鍵環節的耗時以及執行過程中的錯誤等。由于這是應用程式内部的狀态,從外部通常無法直接擷取到詳細的性能資料。是以,應用程式在設計和開發時,就應該把這些名額提供出來,以便監控系統可以了解其内部運作狀态。

有了應用程序的資源使用名額,你就可以把系統資源的瓶頸跟應用程式關聯起來,進而迅速定位因系統資源不足而導緻的性能問題;

  • 有了應用程式之間的調用名額,你可以迅速分析出一個請求處理的調用鍊中,到底哪個元件才是導緻性能問題的罪魁禍首;
  • 而有了應用程式内部核心邏輯的運作性能,你就可以更進一步,直接進入應用程式的内部,定位到底是哪個處理環節的函數導緻了性能問題。

基于這些思路,我相信你就可以建構出,描述應用程式運作狀态的性能名額。再将這些名額納入我們上一期提到的監控系統(比如 Prometheus + Grafana)中,就可以跟系統監控一樣,一方面通過告警系統,把問題及時彙報給相關團隊處理;另一方面,通過直覺的圖形界面,動态展示應用程式的整體性能。

全鍊路監控

業務系統通常會涉及到一連串的多個服務,形成一個複雜的分布式調用鍊。為了迅速定位這類跨應用的性能瓶頸,你還可以使用 Zipkin、Jaeger、Pinpoint 等各類開源工具,來建構全鍊路跟蹤系統。比如,下圖就是一個 Jaeger 調用鍊跟蹤的示例。

性能優化與測試:系統監控、應用監控的思路

(圖檔來自 Jaeger 文檔)

全鍊路跟蹤可以幫你迅速定位出,在一個請求處理過程中,哪個環節才是問題根源。比如,從上圖中,你就可以很容易看到,這是 Redis 逾時導緻的問題。

全鍊路跟蹤除了可以幫你快速定位跨應用的性能問題外,還可以幫你生成線上系統的調用拓撲圖。這些直覺的拓撲圖,在分析複雜系統(比如微服務)時尤其有效。

日志監控

性能名額的監控,可以讓你迅速定位發生瓶頸的位置,不過隻有名額的話往往還不夠。比如,同樣的一個接口,當請求傳入的參數不同時,就可能會導緻完全不同的性能問題。是以,除了名額外,我們還需要對這些名額的上下文資訊進行監控,而日志正是這些上下文的最佳來源。

對比來看,

名額是特定時間段的數值型測量資料,通常以時間序列的方式處理,适合于實時監控。

而日志則完全不同,日志都是某個時間點的字元串消息,通常需要對搜尋引擎進行索引後,才能進行查詢和彙總分析。

對日志監控來說,最經典的方法,就是使用 ELK 技術棧,即使用 Elasticsearch、Logstash 和 Kibana 這三個元件的組合。

如下圖所示,就是一個經典的 ELK 架構圖:

性能優化與測試:系統監控、應用監控的思路

(圖檔來自elastic.co)

Logstash 負責對從各個日志源采集日志,然後進行預處理,最後再把初步處理過的日志,發送給 Elasticsearch 進行索引。

Elasticsearch 負責對日志進行索引,并提供了一個完整的全文搜尋引擎,這樣就可以友善你從日志中檢索需要的資料。

Kibana 則負責對日志進行可視化分析,包括日志搜尋、處理以及絢麗的儀表闆展示等。

下面這張圖,就是一個 Kibana 儀表闆的示例,它直覺展示了 Apache 的通路概況。

性能優化與測試:系統監控、應用監控的思路

值得注意的是,ELK 技術棧中的 Logstash 資源消耗比較大。是以,在資源緊張的環境中,我們往往使用資源消耗更低的 Fluentd,來替代 Logstash(也就是所謂的 EFK 技術棧)。

應用程式的監控,可以分為名額監控和日志監控兩大部分:

名額監控主要是對一定時間段内性能名額進行測量,然後再通過時間序列的方式,進行處理、存儲和告警。

繼續閱讀