Java进程故障排查(CPU资源占用高,接口响应超时,功能接口停滞等)

  • 时间:
  • 浏览:0

# 原因分析分析系统不可用情况汇报(频率较大):

    1)代码中某个位置读取数据量较大,原因分析分析系统内存耗尽,进而无缘无故跳出Full GC次数太多,系统缓慢;

    2)代码蕴含比较消耗CPU的操作,原因分析分析CPU严重不足,系统运行缓慢;

# 原因分析分析某功能运行缓慢(不至于原因分析分析系统不可用):

    3)代码某个位置有阻塞性的操作,原因分析分析调用整体比较耗时,但无缘无故跳出比较随机;

    4)某系统多多线程 已经 有一种原因分析分析进入WAITTING情况汇报,此时该功能整体不可用,但无法复现;

    5)已经 锁使用不当,原因分析分析多个系统多多线程 进入死锁情况汇报,原因分析分析系统整体比较缓慢。

# 说明

    对于后有一种情况汇报而言,是具有一定阻塞性操作,CPU和系统内存使用情况汇报都有高,但功能却很慢,本来通过查看资源使用情况汇报是无法查看出具体难题的!

### 对于线上系统无缘无故产生的运行缓慢难题,已经 原因分析分析线上系统不可用。首不难 做的是导出jstack和内存信息,重启服务器,尽快保证系统的高可用

### 导出jstack信息

为正确处理重复赘述,此操作将在底下的"排查步骤"章节中体现!

### 导出内存堆栈信息

# 查看要导出的Java项目的pid

# jps -l

or

# ps -ef |grep java

# 导出内存堆栈信息

jmap -dump:live,format=b,file=heap8 <pid> # heap8是自定义的文件名

# 运行导出的堆栈文件

# ls

heap8

# hostname -I

10.2.2.162

# jhat -port 9998 heap8

# 浏览器访问http://10.2.2.162:9998/

# 环境说明

    因平台做了线上推广,原因分析分析管理平台门户网页进统计页面请求超时,随进服务器操作系统查看负载信息,load average超过了4,负载较大,PID为7163的系统多多线程 cpu资源占用较高。

# 定位故障

# 正确处理思路:

    找出CPU占用率高的系统多多线程 ,再通过系统多多线程 栈信息找出该系统多多线程 当时正在运行的难题代码段。

# 操作如下:

# 查看高占用的"系统多多线程 "中占用高的"系统多多线程 "

# top -Hbp 7163 | awk '/java/ && $9>50'

# 将16298的系统多多线程 ID转换为16进制的系统多多线程 ID

# printf "%x\n" 16298

3faa

# 通过jvm的jstack查看系统多多线程 信息并保存以供研发后续分析

# jstack 7163 | grep "3faa" -C 20 > 7163.log

# 重点说明

通过排查步骤,可得排查难题时要掌握的信息如下:

    1)资源占用高对应的系统多多线程 a的PID;

    2)系统多多线程 a对应的资源占用高且最频繁的系统多多线程 b的ID;

    3)将系统多多线程 b的ID转换为16进制的ID。

## 通过"排查步骤"章节可基本定位难题,后续请见下文!

确认难题及正确处理

# jstack $pid | grep "3faa" -C 20 # 3faa指的是高占用系统多多线程 中的高占用的系统多多线程 对应的16进制id

# 查看过是数据库的难题,排查思路:先打印所有在跑的数据库系统多多线程 ,检查后发现并跟进情况汇报找到难题表;

# 打印MySQL现有系统多多线程 信息文件

# mysql -uroot -p -e "show full processlist" > mysql_full_process.log

# 过滤出查询最多的表

grep Query mysql_full_process.log

# 统计查询最多的表的数据量

> use databases_name;

> select count(1) from table_name;

# 结合MySQL日志信息,可判断难题是查询时间过长原因分析分析,排查后发现表未创建索引;

> show create table table_name\G

# 询问研发,确认数据不重要,检查字段由时间字段,根据时间确认只保留另4个 月的数据;

> delete from table_name where xxxx_time < '2019-07-01 00:00:00' or xxxx_time is null;

# 创建索引

> alter table table_name add index (device_uuid);

# 确认索引否是创建

> show create table table_name;

总结

    正确处理后系统多多线程 的CPU占用降至正常水平,本次排查主要用到了jvm系统多多线程 查看及dump系统多多线程 完全信息的操作,确认是由数据库难题原因分析分析的原因分析分析,并对数据库进行了清理并创建了索引。

    在正确处理难题后,又查询了一下数据库相关难题的优化,通常的优化土办法还是再加索引。该土办法再加参数具体如下:

innodb_buffer_pool_size=4G

## 通过"排查步骤"章节可基本定位难题,后续请见下文!

确认难题及正确处理

# 行态说明

对于Full GC较多的情况汇报,有以下行态:

    1)系统多多线程 的多个系统多多线程 的CPU使用率都超过50%,通过jstack命令可看过大帕累托图是垃圾回收系统多多线程 ;

    2)通过jstat查看GC情况汇报,可看过Full GC次数非常多,并数值在不断增加。

# 3faa指的是高占用系统多多线程 中的高占用的系统多多线程 对应的16进制id;

# jstack $pid | grep "3faa" -C 20

说明:VM Thread指垃圾回收的系统多多线程 。故基本可取舍,当前系统缓慢的原因分析分析主本来我垃圾回收过于频繁,原因分析分析GC停顿时间较长。

# 查看GC情况汇报(50指间隔50ms,4指查询次数)

# jstat -gcutil $pid 50 4

说明:FGCFull GC数量,其值无缘无故在增加,图中显现高达6783,进一步证实是已经 内存溢出原因分析分析的系统缓慢。

# 因笔者是运维,故确认了难题后,Dump内存日志后交由研发正确处理代码层面难题!

总结

# 对于Full GC次数过大,主要有以下有一种原因分析分析:

    1)代码中一次性获取絮状对象,原因分析分析内存溢出(可用Eclipse的Mat工具排查);

    2)内存占用不高,但Full GC数值较大,已经 是显示的System.gc()调用GC次数太多,可通过再加 -XX:+DisableExplicitGC 来禁用JVM 对显示 GC 的响应。

情况汇报说明

    某个接口访问无缘无故时要3~4s甚至更长时间也能返回。一般而言,其消耗的CPU和内存资源太多,通过上述土办法排查难题无法行通。

    已经 接口耗时较长难题不定时无缘无故跳出,原因分析分析通过jstack命令得到系统多多线程 访问的堆栈信息,根据其信息本来我一定能定位到原因分析分析耗时操作的系统多多线程 (概率事件)。

定位思路

    在排除网络因素后,通过压测工具对难题接口不断加大访问力度。当该接口蕴含某个位置是比较耗时的,已经 访问的频率高,将原因分析分析大多数的系统多多线程 都阻塞于该阻塞点。

    通过分析多个系统多多线程 日志,能得到相同的TIMED_WAITING堆栈日志,基本上就可定位到该接口中较耗时的代码的位置。

# 示例

# 代码蕴含比较耗时的阻塞操作,通过压测工具得到的系统多多线程 堆栈日志,如下:

说明:由图可得,多个系统多多线程 都阻塞在了UserController的第18行,说明此时另4个 阻塞点,也是原因分析分析该接口较缓慢的原因分析分析。

# 总体性的分析思路

当Java应用无缘无故跳出难题时,正确处理步骤如下:

    通过 top 命令定位异常系统多多线程 pid,再 top -Hp <pid> 命令定位出CPU资源占用较高的系统多多线程 的id,并将其系统多多线程 id转换为十六进制的表现形式,再通过 jstack <pid> | grep <id> 命令查看日志信息,定位具体难题。

# 此处根据日志信息分析,可分为有一种情况汇报,如下:

# A情况汇报    

    A.a)若用户系统多多线程 正常,则通过该系统多多线程 的堆栈信息查看比较消耗CPU的具体代码区域;

    A.b)若是VM Thread,则通过 jstat -gcutil <pid> <interval> <times> 命令查看当前GC情况汇报,但会 通过 jmap -dump:live,format=b,file=<filepath> <pid> 导出当前系统内存数据,用Eclipse的Mat工具进行分析,进而针对比较消耗内存的代码区进行相关优化。

# B情况汇报

    若通过top命令查看过CPU和内存使用率不高,则可考虑以下有一种情况汇报。

    B.a)若是不定时无缘无故跳出接口耗时过长,则可通过压测土办法增大阻塞点无缘无故跳出的概率,从而通过jstack命令查看堆栈信息,找到阻塞点;

    B.b)若是某功能访问时无缘无故无缘无故跳出停滞(异常)情况汇报,重启后又正常了,一起去也无法复现。此时可通太多次导出jstack日志的土办法,对比并定位出较长时间位于听候情况汇报的用户系统多多线程 ,再从中筛选出难题系统多多线程 ;

    B.c)若通过jstack命令查看过死锁情况汇报,则可检查产生死锁的系统多多线程 的具体阻塞点,进而相应正确处理。