故障快速定位手册
在系统运维过程中,当收到明确的故障告警时,
存储容量包括服务器磁盘空间、NAS盘空间、数据库表空间、数据库数据盘空间等。服务器空间告警主要原因有日志及临时业务文件占用磁盘较多同时清理策略缺失或者策略不合理导致;数据库表空间告警只要是业务表数据量大,同时表中带有大字段都会导致表空间增长过快。尤其要关注跑批及放量期间流水表中的大字段的增长情况。
当应用及数据库服务器的CPU的使用率超过90%时会收到故障管理流程。应用CPU使用率高的场景有业务高并发导致的CPU使用率高,该场景下一般等业务高峰期结束以后即可恢复。才外还有日志异常输出、程序中不合理的循环、内存溢出等也会导致应用服务器CPU使用率高的。数据库CPU高的场景主要是有跑批中对大批量的数据进行dml操作导致。
在应用运行过程中程序往内存里读入大量的数据时,同时内存又没有及时回收就会导致内存溢出。内存溢出最为常见的场景有数据库大表的全表或大量数据查询导致,其次文件读写也会导致部分内存溢出。
数据库并发场景下因事务控制不合理或者数据库操作不合理导致死锁,尤其是对表进行大数据量delete操作时,会导致严重的死锁,或者并发跑批时多个线程对同一资源进行操作时也会导致死锁。
当应用CPU占用过高或者内存溢出时,新进的业务因申请不到服务器的资源,导致线程等待从而引起接口超时;除此之外慢SQL也会导致接口超时;还有就是外部接口响应超时也会导致
针对具体容量告警事项,服务器容量可登录具体的服务器查看
可能原因包含业务逻辑问题(死循环)、频繁GC以及线程上下文切换过多。
排查步骤
1、使用top定位到占用cpu过高的进行PID
top
2、通过ps aux | grep PID命令
ps -mp pid -o THREAD,tid,time | sort -rn
3、将需要的线程ID转换为16进制格式
printf "%x\n" tid
4、打印线程的堆栈信息 到了这一步具体看堆栈的日志来定位问题了
jstack pid |grep tid -A 30
5、执行 “jmap -dump:format=b,file=filename 进程ID”,导致某进程下内存heap输出到文件中,可以通过eclipse的mat工具查看内存中有哪些对象比较多。
原因
1、代码中可能存在大对象分配
2、可能存在内存泄露,导致在多次GC之后,还是无法找到一块足够大的内存容纳当前对象。
解决方法
1、检查是否存在大对象的分配,最有可能的是大数组分配
2、通过jmap命令,把堆内存dump下来,使用mat工具分析一下,检查是否存在内存泄露的问题
3、如果没有找到明显的内存泄露,使用 -Xmx 加大堆内存
4、还有一点容易被忽略,检查是否有大量的自定义的 Finalizable 对象,也有可能是框架内部提供的,考虑其存在的必要性
报错信息:
java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: Metaspace
原因
永久代是 HotSot 虚拟机对方法区的具体实现,存放了被虚拟机加载的类信息、常量、静态变量、JIT编译后的代码等。
JDK8后,元空间替换了永久代,元空间使用的是本地内存,还有其它细节变化:
字符串常量由永久代转移到堆中
和永久代相关的JVM参数已移除
出现永久代或元空间的溢出的原因可能有如下几种:
1、在Java7之前,频繁的错误使用String.intern方法
2、生成了大量的代理类,导致方法区被撑爆,无法卸载
3、应用长时间运行,没有重启
解决方法
永久代/元空间 溢出的原因比较简单,解决方法有如下几种:
1、检查是否永久代空间或者元空间设置的过小
2、检查代码中是否存在大量的反射操作
3、dump之后通过mat检查是否存在大量由于反射生成的代理类
4、放大招,重启JVM
报错信息:
java.lang.OutOfMemoryError : unable to create new native Thread
原因
出现这种异常,基本上都是创建的了大量的线程导致的,以前碰到过一次,通过jstack出来一共8000多个线程。
解决方法
1、通过 *-Xss *降低的每个线程栈大小的容量
2、线程总数也受到系统空闲内存和操作系统的限制,检查是否该系统下有此限制:
/proc/sys/kernel/pid_max
/proc/sys/kernel/thread-max
max_user_process(ulimit -u)
/proc/sys/vm/max_map_count
--锁表查询SQL
SELECT object_name, machine, s.sid, s.serial#
FROM gv$locked_object l, dba_objects o, gv$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid;
根据脚本查询到对应锁表的事务,定位到业务代码,排查业务逻辑。现场联系dba杀掉锁表进程,保障业务进行。
根据日志分析接口超时的位置,一般超时的原因如下
解决方法
例:慢SQL排查分析过程:
针对原因不明确的故障,通过checkList逐一排查