Nginx 監控

1、nginx的基礎監控

  • 進程監控
  • 端口監控

注意: 這兩個是必須要加在zabbix監控,加觸發器有問題及時告警。

web 服務器 nginx 以其高性能與抗併發能力越來越多的被用戶使用

作為一款服務器產品,其運行狀態是運維密切關注的,因此,對 nginx 的實時監控就必須要關注的了

nginx 提供了 ngx_http_stub_status_module,ngx_http_reqstat_module模塊,這個模塊提供了基本的監控功能

作為官方企業版的 nginx plus 通過 ngx_http_status_module 提供了更加完善的監控功能: http://demo.nginx.com/status.html

2、監控的主要指標

我們需要對以下主要的指標進行監控:

1、基本活躍指標

Accepts(接受)、Handled(已處理)、Requests(請求數)是一直在增加的計數器。Active(活躍)、Waiting(等待)、Reading(讀)、Writing(寫)隨著請求量而增減。


Nginx 監控

NGINX worker 進程接受 OS 的連接請求時 Accepts 計數器增加,而Handled 是當實際的請求得到連接時(通過建立一個新的連接或重新使用一個空閒的)。這兩個計數器的值通常都是相同的,如果它們有差別則表明連接被Dropped,往往這是由於資源限制,比如已經達到 NGINX 的worker_connections的限制。

2、每秒請求數 -- QPS

按照固定時間間隔採樣請求數據,計算出單位時間的請求量可以看到你的 web 服務器的請求情況

通過持續的 QPS 監控,可以立刻發現是否被惡意攻擊或對服務的可用性進行評估

雖然當問題發生時,通過 QPS 不能定位到確切問題的位置,但是他卻可以在第一時間提醒你環境可能出問題了

3、服務器錯誤率

通過監控固定時間間隔內的錯誤代碼(4XX代碼表示客戶端錯誤,5XX代碼表示服務器端錯誤),可以瞭解到客戶端收到的結果是否是正確的錯誤率突然的飆升很可能是你的網站漏洞發出的信號

如果你希望通過 access log 分析錯誤率,那麼你需要配置 nginx 的日誌模塊,讓 nginx 將響應碼寫入訪問日誌

4、請求處理時間

請求處理時間也可以被記錄在 access log 中,通過分析 access log,統計請求的平均響應時間,通過持續觀察,可以發現上游服務器的問題

3、指標的收集

介紹了這麼多的監控指標,事實上,上面介紹的僅僅是基本的監控指標,針對實際的情況,還有很多指標十分具有監控的必要

那麼,怎麼去收集這些指標進行監控呢?

通過在編譯時加入 nginx 的 ngx_http_stub_status_module 模塊我們可以實時監控以下基本的指標:

1、nginx Stub Status 監控模塊安裝

 先使用命令查看是否已經安裝這個模塊:

<code># -V大寫會顯示版本號和模塊等信息、v小寫僅顯示版本信息
[root@nginx]#./nginx -V

# 或用此使用看:
[root@nginx]#nginx -V 2>&1 | grep -o with-http_stub_status_module 
​/<code>

如果已經安裝,會在顯示的信息中包含 --with-http_stub_status_module信息。如果沒有此模塊,需要重新安裝,編譯命令如下:

<code>./configure –with-http_stub_status_module/<code>

具體的使用方法是在執行 ./configure 時,指定 --with-http_stub_status_module,然後通過配置:

<code>location /nginx-status {
          stub_status           on;
          access_log             on;
        allow 127.0.0.1;
          deny all;
          #auth_basic             "nginxstatus";
          #auth_basic_user_file conf/nginxstaus;
}/<code>

此處默認只有本地訪問,如果遠程查看需要加相關的IP或者乾脆去掉Deny all即可。加密文件可以使用#htpasswd -c /usr/nginx/conf hxb 命令來創建。配置完成後需要重啟Nginx服務。狀態配置只能是針對某個Nginx服務。目前Nginx還無法做到針對單個站點進行監控。

2、nginx 狀態查看

配置完成後在瀏覽器中輸入http://127.0.0.1/nginx-status 查看(或者用 curl localhost/nginx_status),顯示信息如下:

<code>Active connections: 100 
server accepts handled requests
1075 1064 6253
Reading: 0 Writing: 5 Waiting: 95 /<code>

Accepts(接受)、Handled(已處理)、Requests(請求數)是一直在增加的計數器。Active(活躍)、Waiting(等待)、Reading(讀)、Writing(寫)隨著請求量而增減。

名稱描述指標類型Accepts(接受)NGINX 所接受的客戶端連接數資源: 功能Handled(已處理)成功的客戶端連接數資源: 功能Dropped(已丟棄,計算得出)丟棄的連接數(接受 - 已處理)工作:錯誤*Requests(請求數)客戶端請求數工作:吞吐量

4、Stub Status 參數說明

  active connections – 活躍的連接數量

  server accepts handled requests — 總共處理了1075個連接 , 成功創建1064次握手, 總共處理了6253個請求

  每個連接有三種狀態waiting、reading、writing

  reading —讀取客戶端的Header信息數.這個操作只是讀取頭部信息,讀取完後馬上進入writing狀態,因此時間很短。

  writing — 響應數據到客戶端的Header信息數.這個操作不僅讀取頭部,還要等待服務響應,因此時間比較長。

  waiting — 開啟keep-alive後等候下一次請求指令的駐留連接.

  正常情況下waiting數量是比較多的,並不能說明性能差。反而如果reading+writing數量比較多說明服務併發有問題。

Nginx 監控

Nginx 監控

當用戶請求連接Nginx服務器時,accepts計數器會加一。且當服務器處理該連接請求時,handled計數器同樣會加一。一般而言,兩者的值是相等的,除非達到了某些資源極限(如worker_connection的限制)。

用戶連接請求被處理,就會進入 active 狀態。如果該連接沒有其他 request,則進入 waiting 的子狀態;如果有 request,nginx 會讀取 request 的 header,計數器 request 加一,進入 reading 的子狀態。 reading 狀態持續時間非常短,header 被讀取後就會進入 writing 狀態。事實上,直到服務器將響應結果返回給用戶之前,該連接會一直保持 writing 狀態。所以說,writing 狀態一般會被長時間佔用。

一旦 NGINX 成功處理一個連接時,連接會移動到Active狀態,在這裡對客戶端請求進行處理:

Active狀態

Waiting: 活躍的連接也可以處於 Waiting 子狀態,如果有在此刻沒有活躍請求的話。新連接可以繞過這個狀態並直接變為到 Reading 狀態,最常見的是在使用“accept filter(接受過濾器)” 和 “deferred accept(延遲接受)”時,在這種情況下,NGINX 不會接收 worker 進程的通知,直到它具有足夠的數據才開始響應。如果連接設置為 keep-alive ,那麼它在發送響應後將處於等待狀態。 Reading: 當接收到請求時,連接離開 Waiting 狀態,並且該請求本身使 Reading 狀態計數增加。在這種狀態下 NGINX 會讀取客戶端請求首部。請求首部是比較小的,因此這通常是一個快速的操作。 Writing: 請求被讀取之後,其使 Writing 狀態計數增加,並保持在該狀態,直到響應返回給客戶端。這意味著,該請求在 Writing 狀態時, 一方面 NGINX 等待來自上游系統的結果(系統放在 NGINX “後面”),另外一方面,NGINX 也在同時響應。請求往往會在 Writing 狀態花費大量的時間。

通常,一個連接在同一時間只接受一個請求。在這種情況下,Active 連接的數目 == Waiting 的連接 + Reading 請求 + Writing 。

怎麼利用這些參數?

開源的 Nginx 提供的原始參數中,實時性的會比較有用,如 Active connections、Reading、Writing 以及 Waiting。這些數據能夠反映當前 Nginx 的負載情況,方便在服務器出現問題時及時發現問題。而另一些數據由於不是狀態量,Nginx 無法計算當前的量值而改做其統計數,如 accepts、handled 和 requests。

對於維護網站人員,accepts、handled 和 requests 的統計值用處是不大的,值得參考的是短時間內這三者數值的增量。這個短時間可以是一秒,如 accepts_per_second、handled_per_second 和 requests_per_second。一個簡單的做法就是每秒都去讀取這些參數,返回一個和上一秒的差值就行。當然,handled_per_second 替換成 dropped_per_second=accepts_per_second-handled_per_second 就更完美了。

通過這七個參數,就可以從連接到請求全方位的監控起 Nginx 的運行狀態。為了方便檢測,對每次獲取的參數保留下來,然後按時間展現出來。下圖展示了 Nginx 在運行時的參考數據。

Nginx 監控

nginx折線圖

5、Reqstat 模塊監控

描述

  • ngx_http_reqstat_module 模塊
  • 這個模塊計算定義的變量,根據變量值分別統計 nginx 的運行狀況。
  • 可以監視的運行狀況有:連接數、請求數、各種響應碼範圍的請求數、輸入輸出流量、rt、upstream訪問等。
  • 可以指定獲取所有監控結果或者一部分監控結果。
  • 利用變量添加自定義監控狀態。總的監控狀態最大個數為50個。
  • 回收過期的監控數據。
  • 設置輸出格式
  • 跟蹤請求,不受內部跳轉的影響
  • 不要使用與響應相關的變量作為條件,比如"$status"

編譯

默認編入Tengine,可通過 --without-http_reqstat_module 不編譯此模塊,或通過--with-http_reqstat_module=shared 編譯為so模塊。

使用so模塊加載的話,請確保其順序在"ngx_http_lua_module"之後。可以藉助"nginx -m"來確認。

例子

<code>http {
  req_status_zone server "$host,$server_addr:$server_port" 10M;
  req_status_zone_add_indicator server $limit;
   
  server {
      location /us {
          req_status_show;
          req_status_show_field req_total $limit;
      }

      set $limit 0;

      if ($arg_limit = '1') {
          set $limit 1;
      }

      req_status server;
  }
}/<code>
  • 以上例,通過訪問/us得到統計結果
  • 每行對應一個server
  • 每行的默認格式
<code>kv,bytes_in,bytes_out,conn_total,req_total,http_2xx,http_3xx,http_4xx,http_5xx,http_other_status,rt,ups_req,ups_rt,ups_tries,http_200,http_206,http_302,http_304,http_403,http_404,http_416,http_499,http_500,http_502,http_503,http_504,http_508,http_other_detail_status,http_ups_4xx,http_ups_5xx/<code>
  • kv 計算得到的req_status_zone指令定義變量的值,最大長度可配置,默認104B,超長的部分截斷
  • bytes_in 從客戶端接收流量總和
  • bytes_out 發送到客戶端流量總和
  • conn_total 處理過的連接總數
  • req_total 處理過的總請求數
  • http_2xx 2xx請求的總數
  • http_3xx 3xx請求的總數
  • http_4xx 4xx請求的總數
  • http_5xx 5xx請求的總數
  • http_other_status 其他請求的總數
  • rt rt的總數
  • ups_req 需要訪問upstream的請求總數
  • ups_rt 訪問upstream的總rt
  • ups_tries upstram總訪問次數
  • http_200 200請求的總數
  • http_206 206請求的總數
  • http_302 302請求的總數
  • http_304 304請求的總數
  • http_403 403請求的總數
  • http_404 404請求的總數
  • http_416 416請求的總數
  • http_499 499請求的總數
  • http_500 500請求的總數
  • http_502 502請求的總數
  • http_503 503請求的總數
  • http_504 504請求的總數
  • http_508 508請求的總數
  • http_other_detail_status 非以上13種status code的請求總數
  • http_ups_4xx upstream返回4xx響應的請求總數
  • http_ups_5xx upstream返回5xx響應的請求總數
  • 可以用"req_status_show_field"指令定義輸出格式。左側欄是字段的名字。
  • 注,後續會清理這些狀態,因為已經支持了自定義狀態。
  • tsar可解析輸出結果,具體見https://github.com/alibaba/tsar

指令

Syntax: req_status_zone zone_name value size Default: none Context: main

創建統計使用的共享內存。zone_name是共享內存的名稱,value用於定義key,支持變量。size是共享內存的大小。

例子:

<code>req_status_zone server "$host,$server_addr:$server_port" 10M;/<code>

創建名為“server”的共享內存,大小10M,使用“$host,$server_addr:$server_port”計算key。

  • 注意,如果希望用tsar來監控的話,key的定義中請不要使用逗號。

Syntax: req_status zone_name1 [zone_name2 [zone_name3 [...]]] Default: none Context: http、srv、loc

開啟統計,可以指定同時統計多個目標,每一個zone_name對應一個目標。


Syntax: req_status_show [zone_name1 [zone_name2 [...]]] Default: 所有建立的共享內存目標 Context: loc

按格式返回統計結果。可指定返回部分目標的統計結果。


Syntax: req_status_show_field field_name1 [field_name2 [field_name3 [...]]] Default: all the fields, including user defined fields Context: loc

定義輸出格式。可以使用的字段:內置字段,以上面的名字來表示;自定義字段,用變量表示。 'kv'總是每行的第一個字段。


Syntax: req_status_zone_add_indecator zone_name $var1 [$var2 [...]] Default: none Context: http

通過變量增加自定義字段,新增加的字段目前會展現在每行的末尾。


Syntax: req_status_zone_key_length zone_name length Default: none Context: http

定義某個共享內存塊中key的最大長度,默認值104。key中超出的部分會被截斷。


Syntax: req_status_zone_recycle zone_name times seconds Default: none

Context: http

定義某個共享內存塊過期數據的回收。回收在共享內存耗盡時自動開啟。只會回收訪問頻率低於設置值的監控數據。 頻率定義為 times / seconds,默認值為10r/min,即

<code>req_status_zone_recycle demo_zone 10 60;/<code>

6、補充:

查看Nginx併發進程數:ps -ef | grep nginx | wc -l

查看Web服務器TCP連接狀態:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

商業版的 nginx plus 通過他的 ngx_http_status_module 提供了比 nginx 更多的監控指標,可以參看 http://demo.nginx.com/status.html

4、nginx access log 分析

nginx 的 access log 中可以記錄很多有價值的信息,通過分析 access log,可以收集到很多指標

python 編寫的 linux 工具 ngxtop 就實現了對 access log 的分析功能


分享到:


相關文章: