基于Nginx日志的异常监控策略

基于Nginx日志的异常监控策略

Nginx作为所有HTTP请求的入口,是非常重要的一层。本文主要介绍如何利用 Nginx日志实时监控每个业务的请求异常。​

这篇文章基于我之前的的一篇 《基于Lua+Kafka+Heka的Nginx Log实时监控系统》 整理而来。


你可以扫描文章末尾的二维码关注我的关注我的公众号,内容大多会是后端技术、前端工程、DevOps,偶尔会有一些大数据相关,会推荐一些好玩的东西。希望你会喜欢~


Nginx 由于其出色的性能,在互联网中被广泛应用,它通常会作为 HTTP 接入层负责分流及静态文件处理。因此,每天会产生大量的日志,而这些日志是可以产生很多价值的,比如用来做用户行为分析、服务性能质量分析,以及本文要介绍的异常监控。
一条访问日志通常会记录用户请求来源、目标资源、设备信息、响应状态等,这里主要关注异常的响应状态码如500,另外一个是upstream_response_time,它反映了后端服务的响应速度。所以,这里主要是做两件事情:1. 监控错误;2. 监控慢的响应。最终的目标是要监测到哪个模块出了什么异常,问题出现在哪台机器上。

小流量场景的应对方案

我先假设目前只有一个 Nginx 节点且QPS 不高,不用太考虑性能问题,那么最简单的做法是写个脚本每分钟计算一下500状态码的数量,超过预设阀值则发送告警邮件,邮件内容要尽量详细,比如模块名、错误数量、告警级别等,并且把异常的日志输出到另外一份文件方便排查。慢响应的监控同理,根据 upstream_response_time 计算出慢的数量,以及平均值。

大流量场景的应对方案

以上的做法基本够一些小流量场景使用,但是当单节点无法满足需求及遇到大流量时,这种方案就会有些吃力了,比如性能上,比如指标的聚合计算。针对新的应对方案,我简单画了一张图:

基于Nginx日志的异常监控策略

这个方案中自下而上依次是 Nginx集群 -> 日志采集 -> 消息队列 -> 指标计算与输出 -> 可视化 。下面我分别介绍一下各阶段的做法。

日志采集

可选择的工具比较多,比如 logstash、flume 等,我推荐使用 lua-resty-kafka 模块编写Lua扩展将数据按照一定格式拼接后写入消息队列。而且也完全可以关掉 Nginx 本身的日志开关,减少磁盘消耗。

消息队列

可以选择 Redis 或者 Kafka,主要取决于你们是否需要对日志做其它的利用。Redis 轻量级一些,Kafka的优势是高吞吐量、分布式架构, 并且除了做异常监控,还可以将数据放到 Hadoop/离线数据仓库中做用户行为分析。

异常监控计算

这一步其实和最开始的简单方案的类似,需要实现指标计算、告警发送和异常数据输出保存。如果日志采集时使用了logstash,那么这一步也推荐使用logstash保持一致,具体做法我就不多说了,看官方文档吧。但如果是使用Lua扩展采集的自定义格式数据,我推荐使用Heka来做。Heka使用Go语言编写,性能不错,内置丰富的插件可以满足大部分的需求。若不满足需求,可以使用Go或者Lua自行开发扩展。在Filter阶段做指标计算,有错误时向Heka消息流中写入告警消息,SMTPOuter匹配到告警消息后通过自定义的Encoder定制好邮件内容后发送,使用ElasticSearchOutput匹配异常数据写入ES节点。

可视化

前面使用Message Matcher Syntax匹配异常数据写入到Elasticsearch后, 搭建一个Kibana。这样在收到告警邮件后,就可以进入Kibana后台查看异常的Log。还可以定制一些图表以查看系统的错误趋势情况。

其它改进

  1. 我建议不要直接使用 Heka 发送邮件,不然可能会遇到邮件轰炸。可以通过 HTTP 接口将告警消息写到另外一个服务,在那里做一些告警策略和频率控制,以及恢复检查。

  2. 需要对 Heka 进程监控,支持自动重启,不然进程挂了都不知道;

总结

这个方案的主要开发点在Nginx Lua扩展和 Heka 的扩展。Nginx Lua 相对简单些,然后就是熟悉Heka的整个消息处理的流程和机制,以及如何开发插件。另一个比较坑的是Heka的错误提示不全,而且调试不方便,有时完全靠猜,不过好在它本身并没有多复杂,有些问题看一看源代码就明白了。


微信扫描二维码,关注我。

我会写一些是后端技术、前端工程、DevOps相关的文章,偶尔会有一些大数据相关,也会推荐一些好玩的东西。希望你会喜欢~

基于Nginx日志的异常监控策略

一切,源于喜欢。