摘要:众所周知,Nginx是目前最流行的Web Server之一,也广泛应用于负载均衡、反向代理等服务,但使用过程中可能因为对Nginx工作原理、变量含义理解错误,或是参数配置不当导致Nginx工作异常。本文介绍的就是福建开机广告Nginx的参数location处理静态文件配置不当引发的nginx日志骤增到14G的问题排期过程。

一、问题现象及系统介绍

现象:12月15日 21:02分,正在外面吃宵夜,手机收到监控平台的一条“服务器磁盘空间<20%”报警短信。

系统介绍:为了看此文的童鞋更好理解我下面介绍的东西,这里我先简单介绍下福建开机广告系统。

整个系统可以分为管理平台与API两个部分:

管理平台完成素材(包括下面提到素材图片名也是有放到缓存里的)、广告、策略、排期制作和下发等工作,提供接口将广告策略、用户分组等信息同步到API;

API向机顶盒/EPG提供广告接口,采集广告请求日志,当STB访问EPG,EPG调用广告请求接口获取广告策略(地区、分组、平台、黑白名单等策略),并在匹配到策略的时候进行展示;

API节点我们是放在其中6台服务器的23个tomcat里面,使用nginx实现负载请求分发;图片服务器我们是放在另外的3台服务器,也是使用的nginx实现的负载请求分发。相信大家对nginx都不陌生,这里我就不在赘述。

二、问题排查过程

2.1 初步分析

判断一:可能是crontab未执行

一看是Nginx所在服务器,初步判断可能是crontab异常,没有定期清除5天以前的日志导致(这里说明下:我们线上的nginx日志是每天凌晨切割access.log日志,然后通过crontab实现只保留最近五天日志)。

2.2 深入分析:

判断二:可能图片同步出问题

回到家,打开SHH客户端 查看/data/nginx_log目录查看,发现access.log只有近五天的日志,「排除原以为是crontab异情况」。

然后发现error_log很大,命令du -h error_log一看都有14G了,tail -200 error_log发现全是“/usr/local/nginx/html/resources/material/img/1511488532192.JPG”图片请求失败的记录,于是赶紧清空error_log,排除短信空间报警。

心想,难道是图片没有同步?

为验证我的猜想,我打开浏览器访问这张图片:http://IP:port/resources/material/img/1511488532192.JPG(上面IP指的是nginx所在服务器IP,port是nginx.conf配置图片分发端口),请求几次返回都是404。

于是切换到主图片服务器查看,发现这张大写图片存在,切换到其他两台从图片服务器,发现也是存在的(这里说明下:我们系统的素材图片都是通过管理平台以接口的形式下发主图片服务器,主图片服务器再通过inotify+sync同步到其他两台从图片服务器),「排除图片同步异常情况」。

判断三:可能是请求不到大写后缀图片导致

因为看到图片服务器目录下,唯有这几张大写后缀图片是请求异常的,那改成小写会怎么样呢?接着改了下三台图片服务器的图片大写后缀为小写后缀。再打开浏览器请求,发现请求正常了,继而判断可能运营人员在管理平台制作广告的时候上传了大写后缀的格式的图片,同步到API和数据库的缓存,那么导致有广告请求的从缓存查询到的图片地址也就是大写的了。

顺着这个思路,我先到登录到数据库改了下素材表图片大写后缀为小写后缀,再登录redis,准备改缓存,info命令一看,傻眼了,136万的key数量,而我又不记得具体广告策略key,

由于没办法查找,那就只能flushall清空缓存,重启ad-cache工程(这里说明下:ad-cache工程的作用主要就是两个,一是把当前符合要求的用户、广告策略等相关信息初始加载到缓存,另一个是启一个定时任务,每小时加载当前时段的策略到缓存),然后在查看tail -f error_log查看日志,发现还在增加之前那种大写后缀图片请求失败的错误,「排除图片后缀大写情况」。

判断四:可能是nginx配置不当导致

这么操作完还是不行,当时着实有点懵逼,我心想当时已经把广告请求所有涉及到会查询图片大写后缀的地方改过来了,为什么还是会有大写后缀图片请求失败的记录?但转念一想会不是nginx的配置有问题?

为验证我的判断,我先sz命令从图片服务器上下载了一张名为“1511488578911.JPG”的大写后缀格式的图片,然后通过管理平台上传这个“1511488578911.JPG”图片素材,发现这张图片是可以预览的。由此更加确信就是nginx某些参数配置不当导致。vim命令查看配置nginx.conf,当定位到图片请求配置这里的时候,

发现location ~是表示区分大小写的,而后面全是配置小写后缀格式,于是加上JPG,使用/usr/local/nginx/sbin/nginx -s reload命令重载nginx的配置,打开浏览器发现可以查看到这张图片了,再切换到nginx日志目录,tail -f error_log,发现日志没有再增加,至此问题终于解决。

三、问题反思

反思一:要做到知其然并且知其所以然

对Nginx工作原理、参数含义理解不深,从而参数配置不当,导致产生nginx日志骤增这种问题产生。

反思二:缺少一个快速定位问题的系统或工具,导致排查的时间比较长。

当时在作出判断三的时候,因为没在公司,不记得广告策略缓存key,导致不得不直接执行flushall命令直接清空缓存,再重新刷入缓存,这样做其实是有风险的,因为把广告策略、用户、分组等信息从缓存清空之后,用户的广告请求只能直接去查询数据库,这样响应的时间肯定会慢了,而且缓存中还存了广告请求的日志记录,直接flushall就会丢失部分的广告请求数据,影响到PV、UV统计。所以当时也是想就是有一个系统,在浏览器直接输入一个用户名或是图片名,就能从数据库和缓存查询到中涉及到相关联的数据,以可视化的形式在页面展示,这样定位问题也就可以更快定位问题了。

四、引申

语法规则: location [=|~|~*|^~] /uri/ { … }

= 开头表示精确匹配

^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。

~ 开头表示区分大小写的正则匹配

~* 开头表示不区分大小写的正则匹配

!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则

/ 通用匹配,任何请求都会匹配到。

多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):

首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

例子,有如下匹配规则:

[plain] view plain copy

location = / {

#规则A

}

location = /login {

#规则B

}

location ^~ /static/ {

#规则C

}

location ~ \.(gif|jpg|png|js|css)$ {

#规则D

}

location ~* \.png$ {

#规则E

}

location !~ \.xhtml$ {

#规则F

}

location !~* \.xhtml$ {

#规则G

}

location / {

#规则H

}

那么产生的效果如下:

访问根目录/, 比如http://localhost/ 将匹配规则A

访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H

访问 http://localhost/static/a.html 将匹配规则C

访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用,而 http://localhost/static/c.png 则优先匹配到 规则C

访问 http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。

访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。

访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。

记一次生产环境Nginx日志骤增的问题排查过程的更多相关文章

  1. 记一次生产环境nginx图片上传不了的问题

    在server节点目录下配置: client_max_body_size 8M; client_body_buffer_size 8M; 不过还是不能上传就执行下面这条命令: cd /var/lib/ ...

  2. Nginx 日志分析及性能排查

    Nginx 日志分析及性能排查 2017-03-04 Linux爱好者 (点击上方公众号,可快速关注) 作者:-外星人- my.oschina.net/362228416/blog/844713 如有 ...

  3. 记一次生产环境thrift服务的配置问题

    问题现象 有客户反馈我们的产品有时反应很慢,处理会出现超时. 问题分析过程 1.第一反应可能是用户增加,并发量太大了,询问了运营,最近用户注册数据并没有猛增. 2.分析access日志,发现有隔一段时 ...

  4. 记一次生产环境axis2服务特别慢的问题。

    情况如下: 某服务,在测试环境测试的时候整个响应过程也就0.5s左右,测试环境和生产环境axis2版本一致,tomcat版本一致,但是生产环境需要差不多20S. 后来,越来越慢,导致服务一起来,整个生 ...

  5. 记一次生产环境tomcat线程数打满情况分析

    前言 旨在分享工作中遇到的各种问题及解决思路与方案,与大家一起学习. -- 学无止境, 加油 ! Just do it ! 问题描述 运行环境描述 tomcat-8.5 单节点(该应用集群20个节点) ...

  6. 生产环境nginx配置文件(带https安全认证)

    #user www www; worker_processes 2; error_log logs/error.log info; pid /usr/local/nginx/nginx.pid; wo ...

  7. 生产环境nginx上传文件报错413 Request Entity Too Large

    修改nginx配置文件/etc/nginx/nginx.conf 在http{}中添加 client_max_body_size 100m; 意思是设置上传文件大小

  8. 记一次生产环境presto删表失败的问题

    场景,开发用java程序连接presto创建一个表,这个表在hdfs的权限为: 然后用presto去删除这个表 报错,没有权限删除,查看上一级目录权限,发现权限正常 直连hive删表 发现正常. 然后 ...

  9. 生产环境-jvm内存溢出-jprofile问题排查

    首先线上开启了dump的参数 dump的内容有2G,先进行压缩打包,传输至本地(scp) tar -czvf dump.tar java_pid4824.hprof  使用Jprofile打开dump ...

随机推荐

  1. tab面板,html+css

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  2. 登山(Climb)

    题目: Rocky山脉有n个山峰,一字排开,从西向东依次编号为1, 2, 3, --, n.每个山峰的高度都是不一样的.编号为i的山峰高度为hi.  小修从西往东登山.每到一座山峰,她就回头观望自己走 ...

  3. Unity3D游戏GC优化总结---protobuf-net无GC版本优化实践

    protobuf-net优化效果图 protobuf-net是Unity3D游戏开发中被广泛使用的Google Protocol Buffer库的c#版本,之所以c#版本被广泛使用,是因为c++版本的 ...

  4. 【复习】VueJS之内部指令

    Vuejs 源码:https://github.com/zhuangZhou/vuejs 下载Vue.js 官网:http://vuejs.org live-server使用 live-server是 ...

  5. Python3 下实现 Tencent AI 调用

    1.背景 a.鹅厂近期发布了自己的AI api,包括身份证ocr.名片ocr.文本分析等一堆API,因为前期项目用到图形OCR,遂实现试用了一下,发现准确率还不错,放出来给大家共享一下. b.基于py ...

  6. unity android相互调用

    简介 有一些手机功能,Unity没有提供相应的接口,例如震动,例如不锁屏,例如GPS,例如... 有太多的特殊功能Unity都没有提供接口,这时候,我们就需要通过使用Android原生的ADT编辑器去 ...

  7. scrapy初试水 day03(递归调用)

    import scrapyfrom scrapy.http import Requestfrom scrapy.spider import Rulefrom scrapy.linkextractors ...

  8. Java面向对象编程基础

    一.Java面向对象编程基础 1.什么是对象?Object 什么都是对象! 只要是客观存在的具体事物,都是对象(汽车.小强.事件.任务.按钮.字体) 2.为什么需要面向对象? 面向对象能够像分析现实生 ...

  9. 揭秘 HashMap 实现原理(Java 8)

    HashMap 作为一种容器类型,无论你是否了解过其内部的实现原理,它的大名已经频频出现在各种互联网面试中了.从基本的使用角度来说,它很简单,但从其内部的实现来看(尤其是 Java 8 的改进以来), ...

  10. 小白关于python 对象和内存的关系的一些感悟和疑惑,望大神指教

    首先你输入了一个字符串,这个字符串是有大小的,电脑将其放在内存中,自动给其一个起始指针指向这个字符串的首位置,然后,你将这个字符串赋值给一个变量,这个对象又在内存中开辟出一个空间,这个变量会自动连接这 ...