Nginx的访问日志记录每条请求的来龙去脉,通过日志可以分析出很多有用的监控信息,如下面的这些信息。
通过这些信息,可以对请求的各项指标进行监控,这对应用级别的服务来说是非常重要的。下面将会对Nginx日志分析中常见的需求进行说明。
首先需要确认Nginx日志分析应该使用什么类型的工具。与筛选动态upstream管理工具的方式一样,它应该至少满足如下条件。
URI在指定的某段时间内按照请求的响应时间进行升序排列,p99的意思是指在99%这个位置的响应时间,即确认出99%的请求所花费的时间,用于体现服务的响应能力。
在很多业务中,URI会使用正则表达式类型的路由,以“折800商城”的详情页为例:shop.zhe800 .com/products/ze171126205509136896和 shop. zhe800.com/products/ze170814104348738286。这两个网址属于同一个URI服务类型,只是后面的数字不一样,它们在服务中都可以表示为shop.zhe800.com/products/[a-z0-9]+的正则表达式。如果不将这些带有正则表达式的URI进行归类,在汇总时URI会非常分散,从而无法做到准确的定位和报警。因此对URI进行归类分组是非常重要的。
确认是否存在缓存的主要目的是避免出现上线时需要加缓存的服务没加的情况。可以通过日志分析定期梳理这些服务,找到没有添加缓存的服务,然后和业务部门确认是否需要配置缓存。(URI是否有缓存可以通过在响应头中加入特定的头信息进行标识,例如CDN缓存一般有Cache-Control头。)
上述功能的实现不必一蹴而就,可以在使用中通过不断迭代完成,在高并发、多业务模式下的服务均可参考这些需求。但如果Nginx的服务单一且并发程度较低,只需用一些简单的分析工具甚至脚本即可。
下面将会介绍一些工具,利用它们来完成上述各种需求。
ngxtop是用Python语言开发的在线分析工具,它可以对Nginx请求进行实时分析,使用方法也非常简单。
首先,安装ngxtop。ngxtop是Python的包,所以使用Python的pip命令安装即可(ngxtop支持Python 2和Python 3):
# yum install python-pip
# pip install ngxtop
在使用ngxtop时,需要确保Nginx日志格式是默认格式,因为ngxtop是通过对日志格式进行匹配得到数据的,所以格式改变将会导致数据分析异常。如果有新的变量要加入日志格式,请将其添加到默认配置的后面(新的变量在ngxtop中无法被分析,只能将其记录到硬盘上,以方便业务的其他需求),代码如下:
执行分析命令如下:
ngxtop会找到配置文件中access_log的位置,-n的作用是显示所输出URI的行数,默认是10行。ngxtop日志分析结果如图1所示。
图1 ngxtop日志分析结果
从图1中可以看到请求的总量、URI的访问次数、平均发送字节数及HTTP状态码。
ngxtop还支持如下功能。
在网站搭建初期,使用ngxtop对实时分析有很大的帮助,但随着网站规模的扩大、业务的增多,继续使用此工具会遇到瓶颈。总结ngxtop的优缺点如下。
优点:
缺点:
总而言之,它比较适合小型单机网站或临时问题的分析。另外,还有一个工具GoAccess与ngxtop比较类似。
由于ngxtop工具的局限性,特别是它在集群化方面的缺陷,我们需要重新寻找工具,经过筛选决定采用Flume来收集数据完成日志汇总,并利用比较流行的Elasticsearch来进行数据存储。Flume方案的日志分析流程图如图2所示。
图2 Flume方案的日志分析流程图
先说说这个方案的优缺点。
优点:
缺点:
组件的安装和使用方法在网上有很多资料,这里不再赘述。
Flume方案对资源消耗过多,维护成本也高,随着业务的发展,最终会被放弃,取而代之的是一个全新的数据收集和分析工具,这也是本文要介绍的重点内容——智能化nginx_log_ analysis。
现在除进行日志分析外,日志分析工具还需要同时满足高性能、低消耗、迭代方便等需求。看上去确实有点令人头疼,毕竟在开源社区中,能够产品化的Nginx日志分析工具非常少,那么可以自己开发一套工具来实现这些功能。
如果可以在Nginx上将数据格式化后直接通过网络发送给数据库,再由数据库完成分析,这样中间的其他环节(如读取硬盘、格式化日志等)都可以省略了,那么将会极大地降低维护成本。但如何才能让这种设想得以实现呢?这就要用到前面学习过的Ngx_Lua(参见《Nginx实战》的相关章节)了。具体流程分析如下。
最后,将计算后的数据和监控系统打通,以便提供报表和报警的功能。但是,鉴于代码过多,笔者选择将这个系统的所有代码在GitHub上进行了开源,地址是https://github.com/leehomewl/nginx_ log_analysis。
注意:本文不会对所有代码都进行讲解,但会选取一部分代码进行说明,主要目的是让读者了解如何在开发中使用Ngx_Lua来完成架构设计和流程规划,从而提升开发水平。
首先,需要解决日志远程传输的问题,而且要支持集群化,即数据的传输要统一存储、统一计算。
这里需要用到模块lua-resty-logger-socket,它的主要功能是以非阻塞I/O的方式推送数据到远程服务器上。它属于Nginx的log执行阶段,是在请求反馈给客户端后执行的操作,所以在此处传输日志,即使数据推送失败,也不会影响客户端的响应。
Nginx对日志的分析基于时间的维度,如波动的报表、请求PV(Page View,即页面浏览量)的涨幅、平均响应时间的对比等都是在时间的基础上进行的。再如常用的Nagios和Zabbix,在报警和监控中也是以时间为基础的,所以需要找一个时序数据库来支撑数据分析。
在时序数据库的选择上,可以使用InfluxDB,它是一款基于Go语言开发的开源分布式时序、事件和指标数据库,非常适合处理监控数据,它提供了很多函数,这些函数包含了绝大部分的数据计算方式,可以简化数据分析的代码。关于InfluxDB的用法请参考《Nginx实战》的相关章节。
在Nginx中,用来记录后端响应时间的变量是$upstream_response_time,但有时它会有多个值,各值之间以逗号来分隔,这样做是因为受proxy_next_upstream的控制,当后端服务响应异常时会将请求代理到另一台后端服务器上进行响应,所以就出现了多个值。这样会导致存放在数据库中的响应时间字段的部分数据不是数字,InfluxDB函数无法执行计算。为了避免出现这种情况,在Nginx写入时就要将以逗号分隔的数字累加后再插入数据库中。
在Nginx中URI的变量是$uri,它不包含URL中的参数,$uri即服务。之前提到过,如果URI无法区分正则表达式,就会导致计算分散化,从而失去分析和监控的意义。因此需要在Nginx中将这些正则表达式的数据区分出来。
那么如何让Ngx_Lua知道URI是否是正则表达式的呢?这就涉及URI认领的问题了,大致方式如下。
URI认领并非只为了方便数据汇总,它还可以实现更多功能,例如,想要判断某个项目是否使用了新的URI,可以用Ngx_Lua在测试环境下做一层验证,判断请求的URI是否为认领中的服务,如果不是,则为新URI。这样每次上线前都可以提前配置和监控URI。在补充监控时也可以对新增的URI添加其他属性,如配置缓存、监控POST的数据长度范围、进行降级容灾处理等。总之,通过这种方式,可以对URI做非常细致的监控。
关于正则表达式URI的存放和匹配格式,下面举例说明。例如,MySQL中存放了一个路由是/a/b/[0-9]+的URI服务,并由Nginx将该数据读取到内存中进行缓存,当客户端请求Nginx且URI是/a/b/123或/a/b/345时,就会被Ngx_Lua匹配成/a/b/[0-9]+,最后将/a/b/[0-9]+写入InfluxDB,并会用它来完成数据分析。
通过这套流程,就可以得到想要的分析报告了。
注意:以上对MySQL的应用,只是为了区分URI是正则表达式还是精确类型,有些读者的服务可能只有精确的URI,在这种情况下,MySQL是可以去掉的,但如果读者希望使用更多的监控功能,MySQL还是非常重要的,这在《Nginx实战》的相关章节中会有详细的讲解。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有