在做运维工作时,或多或少都会遇到访问出错或缓慢问题,这里以两个小的例子来简单说明下这类问题的troubleshooting的思路。
一、用户查询平台故障一例
查询平台结构
nginx:80----------ip1/ip2 java------jdbc---(haproxy)--ip3(3000)+ip4(3000)hiveserver2---hdfs
从后端应用开始查:
1、通过hive cli运行sql,检测hadoop运行job的状态,正常。
2、由于应用使用jdbc的方式连接hiveserver2,使用beeline测试hiveserver2的状态,正常。
连接方法:
!connect jdbc:hive2:/xxxx:30000/cdnlog
3、查看应用状态,由于是java应用,因此第一时间使用jstat查看下gc信息。发现因为s0和old区100%导致应用在做频繁的full gc,定位到是存在内存泄露的问题,通过jmap打印相关堆栈信息来进一步分析。
jstat -gcutil 14266 1000 1000
S0 S1 E O P YGC YGCT FGC FGCT GCT
100.00 0.00 100.00 100.00 21.65 596 77.267 629 2817.783 2895.050
100.00 0.00 100.00 100.00 21.65 596 77.267 629 2817.783 2895.050
100.00 0.00 100.00 100.00 21.65 596 77.267 629 2817.783 2895.050
4、再来看nginx的访问日志,可以明显看到nginx首先proxy到ip1,当响应超时后再proxy到ip2,因此从日志中可以看到两个status和upstream response time.
截取的一段日志:"8.999, 0.008" "ip1:8081, ip2:8081" "502, 200" "9.007"
存在的问题:
没有有效的java监控(包括性能监控和日志监控)
二、推荐域名访问故障问题
故障现象:
用户访问缓慢,一个url有时响应超过3s,并且会有一定的几率abort.
域名整个的访问流程:
client-----cdn-----内部cdn节点-----源站(F5--nginx---java----redis---db)
从用户端开始入手:
1)通过curl xxxx --trace-time --verbose来查看访问时间的变化情况,单一请求时间3s,渐变点在用户等待服务器响应上
2)用户与cdn服务器连通性没有问题(延迟5ms以内,无丢包),这点从client―cdn建立连接耗时也可以看出来(5ms)
3)源站nginx响应时间2ms,说明后端应用正常,源站到cdn节点延迟是50ms,无丢包,同时看到在cdn内部经过3多层代理,这就导致cdn内部任何一层有问题都会产生慢速响应
4)调整cdn策略为一层代理,问题得到缓解不过还是有一定比例的慢速响应
5)跳过cdn节点,直接指向源站来进行访问测试,发现有一定的几率abort
6)在client端通过tcpdump抓包,发现client---server连接建立正常,但是server端有一定的概率会返回RST给client,造成abort的产生
即用户到F5正常,由F5到后端nginx出现问题,最终定位到是由于F5配置出错导致proxy到了错误的server上。
【存在问题】
1、RST不会在服务器上产生日志,是tcp层面的问题,还没到应用层,因此通过监控nginx的访问日志无法发现这种问题,需要对client端的性能做监控
2、F5的配置有些问题,对于后面机器的检测,只是使用了ping的方法,没有检测端口导致有一部分的请求会分发到有问题的机器(比较理想的请求使用url的应用层检测)
【小结】
对于这类问题,可以通过两种方式来troubleshooting,从应用出发和从client端出发。
两种方法的思路都是一样的,首先要清楚的了解整个的访问链,然后对访问进行分解,对每一步都进行检测分析。
同时要注意服务器qos和用户端qos的结合。