nginx监控

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx监控相关的知识,希望对你有一定的参考价值。

                        nginx监控

第一:nginx的基础监控:

1.进程监控

2.端口监控

在这里nginx的基础监控就不详细说了,注意的是:这两个是必须要加的。并且对于zabbix而言的话,一定要加上触发器的。有问题必须报警。

第二:nginx的特殊监控:

1.利用nginx的stub_status模块监控:

    location /ngn_status
    {
        stub_status on;
        access_log off;
    }

(1)nginx的每分钟的总请求数

curl -s http://127.0.0.1/ngn_status| grep connection | awk -F ":" ‘{print $2}‘

(2)nginx的活跃数的链接数

accepts_handled=`curl -s http://127.0.0.1/ngn_status| awk ‘$1~/^s/ {for (i=1;i<=2;i++) {print;getline}}‘ |awk ‘{print $1,$2,$3}‘ | grep -v server`
accepts=`echo $accepts_handled | awk {print $1}`
handled=`echo $accepts_handled | awk {print $2}`
echo `expr $accepts - $handled`

(3)nginx的丢弃数连接数

#每分钟的总请求数,zabbix上需要配置减法哦!!
all_requests=`curl -s http://127.0.0.1/ngn_status| awk ‘$1~/^s/ {for (i=1;i<=2;i++) {print;getline}}‘ |awk ‘{print $1,$2,$3}‘ | grep -v server | awk ‘{print $3}‘`
echo $all_requests

2.日志监控

(1):nginx的日志监控前提:

i.规范nginx的格式,规范日志格式。这是很多团队容易忽略的地方,有时候多一个空格会让日志分析的复杂度大为增加。

nginx的日志格式:

log_format  main   ‘$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent $request_time $upstream_response_time $upstream_addr "$http_referer" "$http_user_agent" "$http_x_forwarded_for"‘;

详解:                          $remote_addr 记录客户端的ip地址,如有代理会记录代理的ip地址   

                          $remote_user                      记录客户端用户名称                     
                          [$time_local]                     来访时间                                                                                                                                                                                  
                          "$request"                        记录请求的url与http协议 
                          $status                           记录请求状态                                                                                                                                                        
                          $body_bytes_sent                  记录发送给客户端文件主题的大小, 这一个可以用于监控某个文件,图片占用多大的带宽
                          $request_time                     整个请求的总时间
                          $upstream_response_time           请求过程中upstream响应的时间
                          $upstream_addr                    真正提供服务的ip地址
                          "$http_referer"                   用来记录从那个页面链接访问过来的
                          "$http_user_agent"                记录客户端浏览器的相关信息
                          "$http_x_forwarded_for"‘;         记录客户端访问的真实ip地址
这里特别解释一下 :remote_addr与
http_x_forwarded_for

remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问
这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。正如上面所述,当你使用了代理时,web服务器就不知道你的真实IP了,为了避免这个情况,代理服务器通常会增加一个叫做x_forwarded_for的头信息,把连接它的客户端IP(即你的
上网机器IP)加到这个头信息里,这样就能保证网站的web服务器能获取到真实IP

ii.nginx做日志切割,如果nginx没有做日志切割的话,会很大,造成监控误报的情况

nginx的日志切割有很多种方式方法,例如:利用系统自带的logrotate切割nginx日志,按天shell+crontab来切。

我用的是shell+crontab,

脚本:

#!/bin/bash
#nginx日志切割脚本

#设置备份日志文件存放目录
before_log="/var/log/nginx/before_log/"

#生成日志文件存放目录
admin_log_path="/var/log/nginx/game_admin/"
game_new_log_path="/var/log/nginx/game_new/"
game_wap_new_log_path="/var/log/nginx/game_wap_new/"
kf_log_path="/var/log/nginx/kf/"
nginx_master_log_path="/var/log/nginx/nginx_master/"
wap_wsds_log_path="/var/log/nginx/wap_wsds/"
wsds_log_path="/var/log/nginx/wsds/"
#设置pid文件
nginx_pid_path="/run/nginx.pid"

#定义日期
yesterday=`date -d "yesterday" +"%Y%m%d"`
mkdir -p ${before_log}${yesterday} 

#重命名访问日志文件
mv ${admin_log_path}access.log ${before_log}${yesterday}/access_admin.log
mv ${game_new_log_path}access.log ${before_log}${yesterday}/access_game_new.log
mv ${game_wap_new_log_path}access.log ${before_log}${yesterday}/access_game_wap_new.log
mv ${kf_log_path}access.log ${before_log}${yesterday}/access_kf.log
mv ${nginx_master_log_path}access.log ${before_log}${yesterday}/access_nginx_master.log
mv ${wap_wsds_log_path}access.log ${before_log}${yesterday}/access_wap_wsds.log
mv ${wsds_log_path}access.log ${before_log}${yesterday}/access_wsds.log

#重命名错误日志文件
mv ${admin_log_path}error.log ${before_log}${yesterday}/error_admin.log
mv ${game_new_log_path}error.log ${before_log}${yesterday}/error_game_new.log
mv ${game_wap_new_log_path}error.log ${before_log}${yesterday}/error_game_wap_new.log
mv ${kf_log_path}error.log ${before_log}${yesterday}/error_kf.log
mv ${nginx_master_log_path}error.log ${before_log}${yesterday}/error_nginx_master.log
mv ${wap_wsds_log_path}error.log ${before_log}${yesterday}/error_wap_wsds.log
mv ${wsds_log_path}error.log ${before_log}${yesterday}/error_wsds.log

#向nginx主进程发信号重新打开日志
kill -USR1 `cat ${nginx_pid_path}`

结合crontab每天的0点0分执行该脚本:

00 00 * * * root /bin/bash /opt/script/cut_nginx_log.sh

(2)nginx的日志监控:

i.nginx平均每秒处理的请求数

cat main.log | awk {sec=substr($4,2,20);reqs++;reqsBySec[sec]++;} END{print reqs/length(reqsBySec)}

ii.nginx的请求在哪一个时间是峰值,以级峰值大小(这个如果日志分析中有的话,就不需要加监控了)

cat main.log | awk {sec=substr($4,2,20);requests[sec]++;} END{for(s in requests){printf("%s %s\n", requests[s],s)}} | sort -nr | head -n 10

iii.nginx处理请求的时间

每分钟nginx处理请求的平均时间,zabbix每分钟检测一次 

DATE=/bin/date
one_minute_ago=`$DATE -d "1 minute ago" | awk {print $4} | awk {sub(/...$/,"")}1`
all_times=`cat $log | grep $one_minute_ago | awk -F " {print $13} | awk {print $1}`
all_number=`cat $log | grep $one_minute_ago | awk -F " {print $13} | awk {print $1} | wc -l`sum=0
for i in `echo $all_times`
do
    sum=$(echo "$sum + $i" | bc)
done
ding=0.0
if [ $(echo "$sum == $ding"|bc) -eq 1 ];then
    echo "sum" 
else
    every_num=`gawk -v x=$sum -v y=$all_number BEGIN{printf x/y}`
    echo $every_num 
fi

iv.nginx的请求去访问哪里了??

less main.log | grep 15:59 | awk {upServer=$13;upTime=$12;if(upServer == "-"){upServer="Nginx"};if(upTime == "-"){upTime=0};upTimes[upServer]+=upTime;count[upServer]++;totalCount++;} END{for(server in upTimes){printf("%s %s%s %ss %s\n", count[server], count[server]/totalCount *100, "%", upTimes[server]/count[server], server)}}

v.nginx的日志中是否有被爬虫的痕迹

cat main.log | egrep spider|bot | awk {name=$17;if(index($15,"spider")>0){name=$15};spiders[name]++} END{for(name in spiders) {printf("%s %s\n",spiders[name], name)}} | sort -nr

vi.nginx中出现次数最多的真实ip次数(可以根据实际情况,将xx分钟的大于xx的次数的ip地址找出来)

awk {print $NF} main.log | sort -n |uniq -c | sort -nr 

vii.nginx中日志的图片占用的带宽大小,以及图片被xx分钟被访问的次数超过xx次进行报警(根据情况扩展)

cat main.log |awk {url=$7; requests[url]++;bytes[url]+=$10} END{for(url in requests){printf("%sKB/req %s %s\n", bytes[url] /requests[url] / 1024, requests[url], url)}} | sort -nr

viii.nginx的日志中出现4xx,5xx监控(同样可扩展)(注意:4xx,5xx同时可用这个,写监控脚本的时候用传参的方式哦)

cat main.log | awk {print $9} | grep 4[0-9][0-9] | wc -l

 

 

以上是关于nginx监控的主要内容,如果未能解决你的问题,请参考以下文章

java nginx监控服务程序调度算法实现的代码

zabbix监控nginx进程

zabbix3.0.4监控nginx服务

nginx.conf 忽略了 nginx-ingress 配置映射片段

nginx添加访问监控(只是学习和了解)

将 nginx rtmp 片段发送到 WebRTC