如何排查雪崩式故障

@蛋疼的axb

2015.01.22

内容概述

  • 介绍
  • 思路
  • 工具
  • 启发

介绍

现象

某个/某些集群出现:

  • 接口大规模超时
  • 内存溢出
  • 程序/系统僵死

原因

  1. 系统处理能力到达临界值
  2. 依赖链上的其它系统被拖垮

I/O超时
数据出错

调用关系
调用关系

复杂调用关系
复杂调用关系

实际情况
实际情况

如何排查

  • 找到出问题的时间点
  • 找到第一条异常
  • 找到系统的瓶颈点
  • 找出到达瓶颈的原因
  • 重现问题
  • 修复

系统瓶颈

  • cpu
  • 内存
  • 硬盘
  • 网络带宽

应用瓶颈

  • 配置(线程数、fd数等)
  • 外部资源
  • 宕机/崩溃

区分原因和现象

  • 查询量增长了一倍
  • 线程池满了
  • MC请求变慢了
  • 网络抖动
  • 代码出现死锁
  • 应用OOM了

为什么

  • 线程池为什么满了
  • MC请求为什么变慢了
  • 网络为什么抖动
  • 应用为什么OOM了

为什么_会引发_达到瓶颈

  • 为什么查询量增长了一倍会引发CPU达到瓶颈

为什么_没有引发_达到瓶颈

  • 为什么另一台机器查询量增长了一倍没有引发CPU达到瓶颈

工具

系统监控

  • 内部监控系统
  • sar -f

系统性能分析

perf tools
perf tools

JVM性能分析

  • jstat
  • jstack
  • jmap
  • btrace
  • wtool

日志分析

  • 每秒调用量
zgrep 'ms/get' localhost_access_log.20150122-22.txt.gz | awk '{count[$5]++}END{for(k in count){print k"--"count[k]}}'|sort |less
  • 每秒平均响应时间
zgrep 'ms/get' localhost_access_log.20150122-22.txt.gz | awk '{sum[$5]+=int($3);count[$5]++}END{for(k in count){print k"--"sum[k]/count[k]}}'|sort |less
  • 提取日志关键字
2015-01-28 01:23:57 269 [INFO] ApiServlet API REQUEST, UID:7654321, url:/path/to/url.json, remote:88.88.88.88:28122, queryStr:source=12345678&since_mid=0&count=50&is_encoded=0, nameValues:xxxxxx
cat groupchat.log |sed -n -r 's/.*url:(.*), remote:.* queryStr:.*(source=[0-9]+).*/\1 \2/p'

复现

  • 最小系统复现
  • tcpcopy

减少变量

  • 操作系统 cat /etc/redhead-releases
  • 内核 uname -a
  • jvm java -version
  • cpu cat /proc/cpuinfo
  • 内存 free -m
  • 硬盘 df -h
  • 网卡 ethtool eth0

通道机

  • 批量执行

启发

防御式编程

  • 防超时=>防宕机
  • 防堆积=>超时控制
  • 防雪崩=>业务解耦,快速降级

开关到故障方恨少

  • 资源降级
  • 逻辑降级
  • 接口降级
  • 服务降级

故障演练

  • 压测
  • 可靠降级

日志

  • 上下文信息
  • 分步耗时

保留现场

  • 应用
  • 日志
  • jstack
  • gclog
  • heap dump
  • core dump

避免黑盒查问题

  • 看源码
  • 看官方文档
  • 少看路人博客
  • http://grepcode.com

监控报警

  • 系统
  • 应用

thanks