在做运维工作时,或多或少都会遇到访问出错或缓慢问题,这里以两个小的例子来简单说明下这类问题的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的结合。