如何快速實現一個基於 Nginx 網站的監控場景

小明所在的一家小型互聯網創業公司一直將應用運行在阿里雲上。該應用採用通用的分佈式 Nginx+App 架構為用戶提供電商數據統計的 webservice 服務。應用運行至今除偶發各類 Bug,性能問題以外,情況還算良好。

如何快速實現一個基於 Nginx 網站的監控場景

最近,小明的老闆給小明佈置了一個任務,希望把應用服務監控起來,以提高應用運行質量。老闆的需求有三點:

  1. 先以應用服務監控為抓手,能
  • 實時統計應用各類服務的調用次數
  • 基於 a,實時統計各類服務各類返回值的次數,如 200,404,500,等。
  • 基於 b,如果某類返回值調用超限,進行實時報警。

  1. 提供歷史查詢功能,能返回任意時段任意服務任意返回值調用次數統計。
  2. 以後未來公司各類定製的業務監控能快速擴展到該系統上,如各接口響應統計時間,用戶特徵統計等。

“方案儘量多快好省,而且搭建的監控平臺最好就在阿里雲上,數據不要外放在第三方雲上,主要是為了公網流量成本和以後大數據分析作準備”,老闆最後提到。

技術選項

小明接到任務以後開始著手進行技術選型。擺在他面前貌似可行的有三個選擇,傳統 OLAP 式處理方式,搜索引擎,以及實時計算方式。

如何快速實現一個基於 Nginx 網站的監控場景

在調研現狀和眾多技術後,他發現,

  1. 由於公司業務規模不小,白天峰段的平均 QPS 已經上百,而且業務還在快速增長,因此將每秒上百次調用信息每次直接存放到數據庫中再實時查詢肯定不合適,成本太高且不適合擴展。
  2. 阿里雲提供搜索引擎服務,錯誤統計功能基本能滿足老闆需求。但是不確定因素有兩個。一方面搜索引擎價格存儲成本偏高(搜索引擎需要引入索引存儲),而且各類聚合查詢如接口響應時間統計等查詢響應時間不太好保證,另一方面考慮到實時報警還需要編寫 API 不停進行各類調用的錯誤次數的輪詢,性能和成本都不太確定。
  3. 基於實時計算的架構,可以將線上所有日誌通過服務,返回值錯誤類型,和時間等維度在內存中進行實時的聚合計算,然後再持久化到存儲中。一方面實時計算效率高,聚合後的結果大小會比原始數據大大減少,因此持久化成本低,實時能保證;另一方面還可以在內存中實時校驗報警策略,讓報警的性能開銷足夠小。

綜上考慮,基於實時計算的架構看來最能滿足當前公司的需求。決定了以後,小明開始思考進一步架構設計。

架構設計

決定了基於實時計算的技術以後,小明開始進行架構設計。通過參考各類技術網站,他發現要架構一個靠譜的網站監控方案,需要的組件以下缺一不可。

  • 數據通道:負責將數據從 Nginx 拉取出來,傳送到搜索引擎。數據通道同時肩負數據堆積和數據重算的任務。
  • 計算引擎:基於 Nginx 服務,錯誤碼,時間的維度的聚合實時計算邏輯需要基於選定的引擎進行編寫。計算引擎最好能同時負責一些報警的邏輯。
  • 存儲:存放最終 Nginx 監控結果的地方。考慮到監控結果雖然表結構簡單,但是各種維度查詢比較多,最好是類似於 OLAP 的存儲類型。
  • 展示門戶:針對所有 Nginx 監控結果作各類維度的快速分析和展示。
如何快速實現一個基於 Nginx 網站的監控場景

好在針對前三個組件,阿里雲提供了一些現成的產品組件,小明不需要自己手動一個個去搭建,因此入門門檻還不算高。

  • 數據通道這塊,小明在阿里雲上選取了一款類似於 Kafka 的數據通道,在支持性能和消息堆積等特性的同時,在數據接入上提供了一定的簡便性。
  • 計算引擎上,小明為了簡易入手,選擇了一款基於 spark-stream 計算引擎組件,可以上面直接寫 SQL 語句進行實時計算編排而不需要自己寫流式計算程序。
  • 存儲方面,由於沒有太強事物需求,而且在容量上要求較高,小明選擇了一款類似 Hbase 的雲上存儲產品。
  • 展示門戶方面,沒有直接對應產品。小明撓了撓頭,決定還是隻能自己突擊一下前段編程技術,基於開源展示框架來編寫一個簡單的查詢門戶。

跟老闆申請了預算以後,小明開始陸續開通各類產品進行開發測試。預計一個月完成任務,

漫漫開發路程

開通流程很簡單。花了半天不到,kafka、storm、hbase 的租戶集群到手。可惜常言道,開發項目 80% 的時間花費在最終 20% 的坑上。項目過了一個月,但是功能尚未完成 70%。小明在自己的技術博客上默默的記錄下以下踩過的坑。

集成故障排查成本

由於需要集成的組件包括數據通道,實時計算層,後臺存儲,並在代碼中集成推送數據邏輯以及報警查詢邏輯。每個環節稍有出錯將造成整個鏈路阻塞,調試成本顯得非常高。

日誌清洗

開發期間為了獲取到相關應用為了調整對於日誌的推送邏輯,需要在每臺 Nginx 日誌內容變更以後再在每個服務端變更 API 的推送邏輯,變更過程冗長且容易出錯。

持久化表設計

除了要針對監控項做出適合的表庫設計,並儘量避免索引熱點以外,還需要考慮當數據結果由於實時計算層不穩定重複計算時如何保證數據庫寫入冪等性,這對錶結構設計是一個不小的挑戰。

延遲數據合併

如果由於應用原因導致 Nginx 日誌數據被延遲發送,如何保證比如晚到 1 個小時的數據能被實時計算引擎準確計算並將結果合併到之前的結果。

報警

針對所有結果需要設置定時任務每分鐘對數據進行遍歷查詢。比如針對任何返回 500 調用錯誤超過 5% 佔比的服務,需要所有服務進行多次的調用結果進行遍歷查詢。如何不遺漏所有的服務錯誤檢查的同時保證高效率查詢也是個不小的挑戰。

報警準確性

有的時候由於日誌延遲,上一分鐘部分服務器正常日誌還沒采集全,導致局部 500 調用錯誤的服務暫時超過 5%,類似錯誤是否需要報警?如果報警,有可能誤報,不報警的話,可能漏報,怎麼處理呢?

如何統計 UV、TopN

以 UV 為例。如果要跨任意時間度查詢 UV,則常規手段還需要在數據庫中存入每單位時間(如分鐘級別)的全量 IP 訪問信息。這對於存儲利用率來講顯然是無法接受的。有沒有更優化的方案?

針對錯誤場景的診斷方法

針對各類返回值 500 的調用錯誤,業務方提出希望出現 500 錯誤時能根據時間和調用服務維度查詢到詳細的調用入參和其他詳情,其場景和日誌搜索類似。對於類似新加入需求,貌似通過實時聚合計算和存儲不能直接辦到。需要對日誌另闢蹊徑另行處理。

以上問題還不包括前段展示的各類問題。

掐指一算,兩個月晃眼過了。項目還沒弄完一半,小明有點急了。

另外一種新的思路

小明晚上約了自己的同門師兄老丹搓串。就著小酒,小明把自己最近的煩心事從頭到尾跟老丹說了一遍。

老丹聽了一拍大腿:“小明,你這就奧特了。其實在阿里雲上有一款雲產品, 叫做業務實時監控,簡稱 ARMS,基本上你遇到的這些問題,在 ARMS 上已經提供了一站式的解決方案,你只需要快速接入即可。”。

“噢,是麼?我們業務的監控邏輯很多都是基於 Nginx 日誌定製,ARMS 具備接入 Nginx 日誌的能力,並允許讓我定製業務監控能力麼?“小明問道。

“當然。ARMS 上不僅提供監控 Nginx 的任務模板,本身自帶報警和監控報表,同時還全程開放定製能力。如果你要增加自己的業務監控邏輯,或者刪除或修改自己不要的通用監控邏輯,直接在其平臺上定製即可。”老丹答道。

如何快速實現一個基於 Nginx 網站的監控場景

“聽起來不錯。最終結果除了報表和報警外,公司的下游業務平臺也能用麼?”

“可以的,ARMS 提供 API, 下游系統直接對接數據 API 即可,跟你在雲上直接讀數據庫沒什麼本質區別。”

“聽起來不錯,看來我的項目有救了,我趕緊去看看。”

實現一個基於 Nginx 的網站監控場景

1. ARMS 的 Nginx 監控方案概述和準備

目前在監控領域上比較流行的數據處理方法有很多種,例如,搜索引擎,時間序列數據庫,實時計算,甚至是大數據離線計算,等。

ARMS 採用的是實時計算+列式存儲。這種方案的優勢是數據實時性高,而且對於固定的數據查詢接口查詢效率非常塊。在 Nginx 的監控方案中,其架構概要如下所示, 藍色部分為 ARMS 所集成的 Nginx 監控開箱即用的黑盒。

如何快速實現一個基於 Nginx 網站的監控場景

由於 ARMS 的分析是針對 Nginx 的 access.log 日誌,因此對 Nginx 日誌有一定要求,需要用戶在 nginx.config 中配置出打印內容,包括:“$upstream_response_time” “$request_time” 等代表請求消耗時間的日誌信息。如下例:

 log_format main '$remote_addr - $remote_user [$time_local] $status ''"$request" $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"''"$upstream_response_time" "$request_time" "$ user_cookie_id"' ; 

這樣的話,打印出的日誌,大致如下表所示。

58.211.119.29 144288 - [16/Mar/2017:21:47:07 +0800] "POST http://arms.console.aliyun.com/api/query.json?action=DataQueryAction&eventSubmitDoQueryData=1" 200 594 "https://arms.console.aliyun.com/" "127.0.0.1:8080" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4" "0.144" "0.144" "EX866MB1-Y70JO57WM37ST3HWDVFK3-JWPNH30J-Z"58.211.119.29 148219 - [16/Mar/2017:21:47:08 +0800] "POST http://arms.console.aliyun.com/api/query.json?action=DataQueryAction&eventSubmitDoQueryData=1" 200 583 "https://arms.console.aliyun.com/" "127.0.0.1:8080" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4" "0.148" "0.148" "EX866MB1-Y70JO57WM37ST3HWDVFK3-JWPNH30J-Z"

完成上述日誌配置定製以後,即可開始在 ARMS 上進行配置。以下篇幅從 ARMS 數據集,報警,和交互大盤,三個部分進行配置概要描述。關於數據源如何添加到ARMS可參見文檔,在此不贅述。

2. 基於 ARMS 的 Nginx 監控 數據集實現

在 Nginx 監控模板中,用戶數據分為兩類,一類是指標,相當於數據倉庫中的 Measure;一類是維度,相當於數據倉庫中的 Dimension。

對於Nginx監控,最常見的指標為以下幾類指標:

頁面的 PV, UV

  • PV: 頁面的 PV 通過對 access.log 中的每一條日誌做 coun t來統計,
  • UV: 通過日誌中代表用戶 ID 的對應的 $cookie_id 來做 count distinct 來統計。對應的 cookie_id 需要開發人員進行手動統計。

頁面響應時間

  • 平均頁面響應時間: 在 ARMS 中通過對$request_time做sum操作來統計出total_request_time,然後在通國際 total_request_time / pv 來得到某維度下的瓶平均響應時間。
  • 最大響應時間: 則對單條日誌 request_time 進行 max 統計。

頁面流量

  • 平均頁面流量和最大頁面流量:針對 $body_bytes_sent 來進行統計。統計方式和頁面響應時間類似,不贅述。

對於 Nginx 監控,最常見的維度有以下幾類:

  • 頁面 URL: $request。用戶可以針對特定 URL 進行訪問統計,甚至可以在不同 URL 之間進行訪問排行。
  • 頁面返回狀態
    :$status。用戶可以針對不同的返回值維度進行統計,如僅統計 200 返回值的正常頁面訪問情況,或是非 200 返回值的錯誤頁面訪問情況。
  • 瀏覽器類型:根據 $http_user_agent 統計出的用戶的瀏覽器客戶端,如 Chrome, Sofari, IE, Firefox, 甚至 Curl 命令,等。用戶可以根據此類維度統計客戶端的分佈情況。
  • 用戶 ID:根據 $cook_id 統計出的用戶的使用習慣,如哪一類頁面被哪一些用戶經常訪問,等。

對於 ARMS 的數據集設計,其實就是針對用戶感興趣的 Nginx 監控結果,進行各類維度的排列組合。

  • 例如,以頁面URL維度,統計 UV, PV,頁面響應時間,則可以統計出不同頁面的各自的UV, PV和頁面響應時間,甚至根據例如PV進行TopN排行。

下圖是一個數據集配置的例子,該數據集配置出兩個維度: URL 和 Status (支持由 URL 下鑽到 Status 的查詢方式),分別統計兩個指標:PV 和 UV。這樣用戶可以依次下鑽頁面路徑和返回值來查詢 PV, UV 情況。

如何快速實現一個基於 Nginx 網站的監控場景

下圖是另個數據集配置的例子,該數據集配置出和上例相同但是順序相反的兩個維度: Status 和 URL (支持由 Status下鑽到 URL 的查詢方式),分別統計兩個指標:PV,平均響應時間,最高響應時間 。其中,平均調用時間是複合指標,由總體調用時間 / PV 間接得出。

如何快速實現一個基於 Nginx 網站的監控場景

3. 基於 ARMS 的 Nginx 監控報警實現

常見的 Nginx 報警有以下幾種:

  • 某類頁面的響應時間過長。
  • 某類頁面的錯誤率頁面過高。
  • 使用 ARMS 的原生報警的一些特性天然支持 Nginx 監控報警的各種場景。以下舉例。
  • 支持某類指標的維度下鑽遍歷
  • 例如檢查(遍歷)所有頁面維度的響應時間是否超過 100ms.
  • 支持不同指標之間的複合計算
  • 典型如錯誤碼為 5xx 佔總調用的佔比,通過不同指標複合計算而得。
  • 支持各種其他報警高級報警配置
  • 包括最近 N 分鐘同比,環比,最大,最小值比較,等。例如,最近5分鐘同比PV下跌50%這種典型的場景。

以下例子結合以上三個特點,介紹了一種如何在 ARMS 定義”任意 URL 調用一分鐘 500 返回佔比超過 10%”的報警定義例子,如下所示。

如何快速實現一個基於 Nginx 網站的監控場景

4. 基於 ARMS 的 Nginx 監控大盤配置

監控大盤一般有以下幾個用途:

  • 掛在作戰室,全面掌控運行狀態。
  • 用於實時查看,並下鑽分析每個具體用戶或網頁的網站實際使用情況。

針對 Nginx 監控,ARMS 可以基於類似用戶維度,頁面維度,IP 維度,甚至地域維度,展示不同的數據。以展示用戶總體UV,

V 為例,假設對應的數據集為”整站 UV PV”,則配置如下:

如何快速實現一個基於 Nginx 網站的監控場景

集成各類 UV, PV,響應時間等統計的最終交互式大盤效果圖如下:

如何快速實現一個基於 Nginx 網站的監控場景

5. 馬上快速上手

以上各類 Nginx 監控場景,目前在 ARMS 上已有成熟商業模板支持,用戶只需要在 ARMS 首頁點擊 “新建標準模板監控”,並選擇 Nginx 高級模板,即可。

如何快速實現一個基於 Nginx 網站的監控場景


分享到:


相關文章: