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 的分析功能


分享到:


相關文章: