从理论到案例,请盘下这篇Nginx监控运维干货

应用研发部 2019-01-17 10:12:51
Nginx是一个开源、免费、高性能的HTTP和反向代理服务器,也可以用于IMAP/POP3代理服务器。充分利用Nginx的特性,可以有效解决流量高并发请求、cc攻击等问题。

 

本文探讨了电商场景下Nginx的监控方案,并将使用过程中遇到的问题和解决方案与大家一起分享。

 

一、对于Nginx你一定了解的基础

 

1、特性
 

 

作为Web服务器,Nginx不免要与Apache进行比较。相比Apache服务器,Nginx因其采用的异步非阻塞工作模型,使其具备高并发、低资源消耗的特性,高度模块化设计使Nginx具备很好的扩展性;在处理静态文件、反向代理请求等方面,Nginx表现出很大的优势。

 

2、常见的使用方式
 

 

Nginx可以作为反向代理服务器来转发用户请求;并能够在处理请求的过程中实现后端实例负载均衡,实现分发请求的功能;也可将Nginx配置为本地静态服务器,处理静态请求。

 

二、对于Nginx你需要懂得的监控

 

1、监控指标梳理
 

 

Nginx处理请求的全过程应被监控起来,以便我们及时发现服务是否能够正常运转。Nginx处理请求的过程被详细地记录在access.log以及error.log文件中,我们给出以下需要监控的关键指标:

 

 

2、监控实践
 

 

从延迟、错误、流量以及饱和度四个指标对Nginx监控实践进行说明。

 

延迟监控:

 

延迟监控主要关注对$request_time的监控,并绘制tp指标图,来确认tp99指标值。另外,我们还可以增加对$upstream_response_time指标的监控,来辅助定位延迟问题的原因。

 

下图展示了过去15min内Nginx处理用户请求的时间:

 

 

可以看出用户90%的请求可以在0.1s内处理完成,99%的请求可以在0.3s内完成。根据tp指标值,并结合具体业务对延迟的容忍度,来设置延迟的报警阈值。

 

错误监控:

 

Nginx作为web服务器,不但要对Nginx本身运行状态进行监控,还必须对Nginx的各类错误响应进行监控,HTTP错误状态码以及error.log中记录的错误详细日志都应被监控起来以协助解决问题。

 

1)基于HTTP语义的Nginx端口监控

单纯的Nginx端口监控无法反映服务真实运行状态,我们要关注的是Nginx本身存活以及是否可以正常提供服务;基于我们的实践,我们推荐用语义监控代替端口监控,即从Nginx本机以http://local_ip:port/的方式进行访问,校验返回的数据格式、内容及HTTP状态码是否符合预期。

 

2)错误码监控

必须添加对诸如500/502/504等5xx服务类错误状态码的监控,它们告诉我们服务本身出现了问题。

 

5xx类错误每分钟出现的频率应该在个位数,太多的5xx应及时排查问题并解决;4xx类错误,在协助解决一些非预期的权限错误、资源丢失或性能等问题上可以给予帮助;可以选择性得对301/302重定向类监控,应对特殊配置跳转的监控,如后端服务器返回5xx后,Nginx配置重定向跳转并返回跳转后的请求结果。

 

状态码监控

 

3)对错误日志监控

Nginx内部实现了对请求处理错误的详细记录,并保存在error.log文件中。错误类型有很多种,我们主要针对关键的、能体现服务端异常的错误进行采集并监控,以协助我们进行故障定位:

 

 

错误日志信息

 

流量监控:

 

1)Nginx所接受请求总量的监控

关注流量波动周期,并捕获流量突增、突降的情况;通常稳态下流量低峰和高峰浮动20%需要关注下原因;对于有明显波动周期的服务,我们也可以采用同环比增涨/降低的告警策略,来及时发现流量的变化。

 

下图为京东云某平台一周内的流量波动图:

 

pv流量图

 

流量存在明显低峰和高峰并有天级别的周期性,基于网站运行特性,根据低峰、高峰的值来监控网站流量的波动,并通过自身的监控仪表盘配置网站关键页面的流量图,以协助故障排查:

 

关键流量图

 

2)对网卡IO等机器级别流量的进行监控

可以及时发现服务器硬件负载的压力,当Nginx被用于搭建文件服务器时,此监控指标需要我们尤为关注。

 

网卡流量图

 

饱和度监控:

 

Google SRE中提到,饱和度应关注服务对资源的利用率以及服务在当前运行情况下还可以承受多少负载。

 

Nginx是低资源消耗的高性能服务器,但诸如在电商场景下,新产品抢购则会在短时间内造成cpu利用率、请求连接数、磁盘写入的飙升;cpu利用率还要考虑通过worker_cpu_affinity绑定worker进程到特定cpu核心的使用情况,处理高流量时,该配置可以减少cpu切换的性能损耗。

 

Nginx可以接受的最大连接数在配置文件nginx.conf中由worker_processes和worker_connections 两个参数的乘积决定;通过Nginx自带的模块http_stub_status_module 可以对Nginx的实时运行信息进行监控:

 

 

因我们更关心当前Nginx运行情况,不对已处理的请求做过多关注,所以我们只对如下指标进行采集监控:

 

指标含义

 

三、基于开源软件搭建Nginx可视化监控系统

 

1、采用Elasticsearch + Logstash + Kibana搭建可视化日志监控

 

针对以上四个监控黄金指标,搭建的ELK栈仪表盘,设置常用的Nginx日志过滤规则,以便可以快速定位分析问题:

 

ELK栈架构图

 

ELK仪表盘

 

2)采用Kibana + Elasticsearch + Rsyslog + Grafana搭建可视化日志监控

 

相较于kibana能快速地对日志进行检索,Grafana则在数据展示方面体现了更多的灵活性,某些情况下二者可以形成互补:

 

Grafana可视化架构图

 

Grafana仪表盘

 

我们在实践中实现上述两种架构的Nginx日志可视化监控:

 

  • 从需求本身来讲,ELK栈模型可以提供实时的日志检索,各种日志规则的过滤和数据展示,基本可以满足Nginx日志监控的需求;

  • Grafana架构模型无法进行日志检索和浏览,但提供了角色权限的功能,来防护一些敏感数据的访问;

  • 另外,Grafana更为丰富的图表类型和数据源支持,使其具有更多的应用场景。

 

四、基于Nginx监控发现并定位问题案例

 

案例1:大流量冲击

 

问题:某平台,进行了一次新产品的抢购活动。活动期间因流量飙升导致商品详情页、下单等核心功能处理耗时增加的情况:

 

PV飙升图

 

解决:订单监控及Nginx的PV、请求时间等监控指标发出报警后,运维人员迅速通过自建的ELK监控仪表盘,关注网站流量变化,查看用户请求top IP、top URL;发现存在大量黄牛的恶意抢购行为,导致服务后端处理延时。因此,我们通过降低高防产品、Nginx限流配置中相关接口防攻击阈值,及时拦截了对系统负载造成压力的刷单行为,保障了新品促销活动顺利开展。

 

案例2:Nginx错误状态码警示服务异常

 

问题:某平台进行后端服务器调整,某个Nginx的upstream指向的后端服务器配置错误,指向了一个非预期的后端服务;当错误的配置被发布到线上后,网站开始出现概率性的异常,并伴有500和302错误状态码数量的飙升。

 

302错误码统计

 

解决:Nginx错误状态码告警后,通过ELK平台过滤302错误码下用户请求的URL,发现请求错误的URL均与后端的某个模块相关,该请求都被重定向到了网站首页;进一步定位发现,某台Nginx的指向了错误的后端服务器,导致服务器返回大量500错误,但因Nginx配置中对500错误做了重定向,并因此产生了很多302状态码。

 

在后续改进中,我们通过升级Nginx,采用openresty+lua方式来对后端服务器进行健康监测,以动态更新upstream中的server,可以快速摘除异常的后端服务器,达到快速止损的目的:

 

配置upstream健康监测

 

案例3:nginx服务器磁盘空间耗尽导致服务异常

 

问题:Nginx作为图片服务器前端,某天其中一实例在生产环境无任何变更的情况下收到报警提示:500状态码在整体流量中占比过高。

 

解决:快速将此机器从生产环境中摘除,不再提供服务;

经排查Nginx错误日志发现如下报错:

 

open() "/home/work/upload/client_body_temp/0000030704" failed (28: No space left on device);

 

Nginx处理请求时,会将客户端POST长度超过client_body_buffer_size请求的部分或者全部内容暂存到client_body_temp_path目录,当磁盘空间被占满时,产生了以上的报错。

 

最终,我们确认了本次异常是产品后升级支持上传的图片大小由15MB改为50MB,并且运营方进行了新产品推广活动,用户上传图片量激增快速打满磁盘空间所致。

 
活动预告