前言 & 背景
💡Tips:下面的我只是用于临时记录,如果想要整个系统的稳定性得到保障和比较快速清晰定位到问题:还是需要比较完整风控告警机制
我后面是采用了:elk 做日志收集和分析 + python自动脚本 + elastalert 进行了告警
背景:
Linux 服务负载在某段时段突然出现较高的负载 :
排查思路:
某个时段的访问量暴增导致 (业务驱动的正常情况)
定时任务的触发触发 (导致也性能突然拉高–> eg: a 其他服务的定时任务触发导致,可以通过服务调用的方式排查,普遍是 RPC 和 Http 接口调用导致; b 本机上的定时任务,查看定时任务列表,查看 Cpu, 网络,io 等资源最高占用程序)
某个服务的异常导致业务阻塞 ,导致大量的接口阻塞 (mysql, redis, 微服务中的其他服务。。等出现连接异常,死锁,负载过高,导致另外服务等待阻塞,从而负载过高)
被攻击ddos等 (通过 ip 和 nginx 日志排查)
排查日志准备:
主要以 Nginx 日志为主:
每个项目 Nginx 的 access 和 error 日志最好单独保存,按照每日分割,这可以方便以后每次排查快速定位,也可以方便日志的归档和清理;
1
2
3
4
5
6
7
8
http {
...
map $time_iso8601 $logdate {
'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd ;
default 'date-not-found' ;
}
...
}
Nginx 日志适当加入更多的信息:eg : request_time 等
1
2
3
4
5
6
7
8
9
10
http {
...
log_format log_main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$request_time" "$upstream_response_time" '
'"$upstream_connect_time" "$upstream_header_time" '
'"$http_x_forwarded_for" ' ;
...
}
Nginx 日志分析和常用统计:包括IP相关统计、页面访问统计、性能分析、TCP连接统计等相关命令的总结
Linux 基础排查
linux下获取占用内存资源最多的10个进程,可以使用如下命令组合:
1
ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head
linux 下获取php-fpm 子进程数量:
1
ps -ef | grep "php-fpm" | grep "pool" | wc -l
linux统计tcp的各种状态情况 :
1
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合:
1
ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head
linux CURL 分析请求各阶段消耗时间:
准备文件模版(curl.txt)
1
2
3
4
5
6
7
8
9
10
\ n
time_namelookup : %{ time_namelookup }\ n
time_connect : %{ time_connect }\ n
time_appconnect : %{ time_appconnect }\ n
time_pretransfer : %{ time_pretransfer }\ n
time_redirect : %{ time_redirect }\ n
time_starttransfer : %{ time_starttransfer }\ n
----------\ n
time_total : %{ time_total }\ n
\ n
使用curl带以下参数请求
1
curl -w "@curl.txt" -o / dev / null -s https : // www . sogo . com
参数说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
NAMELOOKUP:从开始计算,域名解析完成的耗时
CURLINFO_NAMELOOKUP_TIME. The time it took from the start until the name resolving was completed.
CONNECT:从开始计算,TCP建立完成的耗时
CURLINFO_CONNECT_TIME. The time it took from the start until the connect to the remote host (or proxy) was completed.
APPCONNECT:从开始计算,应用层(SSL,在TCP之上的应用层)连接/握手完成的耗时
CURLINFO_APPCONNECT_TIME. The time it took from the start until the SSL connect/handshake with the remote host was completed. (Added in in 7.19.0)
PRETRANSFER:从开始计算,准备开始传输数据的耗时
CURLINFO_PRETRANSFER_TIME. The time it took from the start until the file transfer is just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved.
STARTTRANSFER:从开始计算,开始传输数据的耗时(libcurl接收到第一个字节)
CURLINFO_STARTTRANSFER_TIME. The time it took from the start until the first byte is received by libcurl.
TOTAL:总的耗时
CURLINFO_TOTAL_TIME. Total time of the previous request.
REDIRECT:整个过程重定向的耗时,如果整个过程没有重定向,这个时间为0
IP 统计
ip访问量统计
1
awk '{print $1}' access . log | sort -n | uniq | wc -l
查看某一段时间段的IP访问量(5-6点)
1
grep "07/Jan/2019:0[5-6]" access . log | awk '{print $1}' | sort | uniq -c | sort -nr | wc -l
查看访问量最频繁的10个IP
1
awk '{print $1}' access . log | sort -n | uniq -c | sort -rn | head -n 10
查看某个IP的访问情况,按照访问量排序
1
grep '172.168.1.10' access . log | awk '{print $7}' | sort | uniq -c | sort -rn | head -n 10
页面统计访问
查看访问最频繁的页面(Top10)
1
awk '{print $7}' access . log | sort | uniq -c | sort -rn | head -n 10
查看访问最频繁的页面(排除php页面)(Top10)
1
grep -v ".php" access . log | awk '{print $7}' | sort | uniq -c | sort -rn | head -n 10
查看页面访问次数超过100次的页面
1
cat access . log | cut -d ' ' -f 7 | sort | uniq -c | awk '{if ($1 > 100) print $0}' | less
查看最近1000条记录,访问量最高的页面
1
tail -1000 access . log | awk '{print $7}' | sort | uniq -c | sort -nr | less
请求量统计
统计每秒的请求数,top10的时间点(精确到秒)
1
awk '{print $4}' access . log | cut -c 14 - 21 | sort | uniq -c | sort -nr | head -n 100
统计每分钟的请求数,top100的时间点(精确到分钟)
1
awk '{print $4}' access . log | cut -c 14 - 18 | sort | uniq -c | sort -nr | head -n 100
统计每小时的请求数,top100的时间点(精确到小时)
1
awk '{print $4}' access . log | cut -c 14 - 15 | sort | uniq -c | sort -nr | head -n 100
性能分析
列出传输时间超过3秒的页面,显示前20条
1
cat access . log | awk '($9 > 3){print $7}' | sort -n | uniq -c | sort -nr | head -20
列出php页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条
1
cat access . log | awk '($9 > 1 && $7~/.php/){print $7}' | sort -n | uniq -c | sort -nr | head -100
TCP链接统计
查看当前TCP连接数
1
netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l
用tcpdump嗅探80端口的访问看看谁最高
1
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F "." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr