fangpsh's blog

Nginx 监控

nginx

前年读过Scalyr 几篇关于监控的文章,写得挺细致,今天翻收藏夹又发现这个链接,顺便整理一下,主要参考以下2 篇文章:

stub_status

参考ngx_http_stub_status_module 配置stub_status,访问配置好的路径,看到的页面内容如下(如果是Tengine 还会有request_time 等):

Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106 

active connections

Active = Reading + Writing + Waiting
291    = 6       + 179     + 106

三种连接状态的解释如下:

Reading
    Nginx 在读取请求头信息
Writing
    Nginx 在发送响应信息给客户端
Waiting
    空闲的连接。
    2种情况会出现Waiting 的连接:
    1.Nginx 读取完请求,还未发送响应信息之前;
    2.发送完响应信息,等待下一个请求时,HTTP 1.1 的keep-alive 常常会出现这种情况。

这4 个值都应该采集,当 active connection 接近于

阈值:worker_connections * worker_processes

触发报警。

accepts,handled,requests,dropped

accepts 是Nginx 累积接受的连接数,handled 是累计处理完成的连接数。这2个数值一般相等,但是偶尔会发现 handled 值略小于accepts,这说明有一部分请求被dropped:

dropped = accepts - handled

出现dropped 可能是因为达到Nginx 的处理极限,或者用户配置的限制,参考上文active connection 的报警阈值。应该采集accepts 和handled 的值,监控它们之间的差值。

requests 常常比accpts 大好几倍,因为一个连接可能产生多个请求,可以通过采集requests,求出一定时间之内的差值,得到当前的RPS(Requests Per Second),每秒请求数,当请求数暴涨时(活动流量突发,被攻击等情况)能及时发现。

nginx-moduls-vts

Nginx 自带的stub_status 比较简陋,可以考虑加入模块:nginx-module-vts

nginx-module-vts

上图看到的这些值,都可以通过模块提供的接口采集到,绘图、监控,具体参考模块的README.md

日志

访问日志(access.log)

访问日志中最重要的就是监控HTTP 状态码$status,1xx,2xx,3xx,4xx,5xx。按时间段切割计算上报。5xx 大家肯定会重视,不过3xx 和4xx 也需要注意,都是血的教训。
由于需要监控4xx 和3xx,要和业务沟通清楚,不要把业务状态码和HTTP 状态码混在一起。例如用户抽奖的请求,没中奖都返回404,误报严重。

另外还可以采集日志中的$upstream_response_time$request_time 等数值,一段时间内出现响应时间次数大于某个阈值,报警,可以及时发现后端服务异常、过载等情况。

更进一步,就是用fluentd收集访问日志,采用ELKGraylog等做更细致的分析。

错误日志(error.log)

Nginx 的错误日志非常重要,我之前的做法是超过N 条就报警。由于error.log 的内容类型非常多,监控脚本需要过滤掉常见的、已知的错误。报警阈值尽量小,当有意想不到的错误出现时,能及时发现。

进程

在前公司的时候,有一回同事通过salt cmd.run 远程重启了Nginx,跑了一段时间之后,error.log 狂刷日志,发现进程的Max open files是1024。先不提如何避免这种情况,方法很多,但是监控还是可以加上。

ps 过滤出Nginx 进程们的PID,再通过以下命令拿到进程的Max open files 值:

cat /proc/{PID}/limit

将得到的值 和设定的值对比,不匹配即报警。

Nginx 是多进程模型,监控下进程状态,当有异常发生时能更快的发现,进程若处于DZXT等状态需要注意。

其他

  • CPU 各项指标(sys,idle,iowait,si...)
  • 系统负载(load)
  • 磁盘IO
  • 磁盘空间
  • 网卡流量、包量
  • 全连接队列、半连接队列溢出监控
  • 域名过期监控,需要注意域名服务商或者DNSPod 之类的警告邮件,或者写个脚本whois 定期查询,或者设个日历、闹钟
  • SSL 证书有效期监控,可以自己写个脚本监控,使用openssl命令,或者用下面这些在线服务:
  • 定期nginx -t
  • How to monitor NGINX