首页 » 网站推广 » oom异常php技巧_体验了一把线上CPU100及应用OOM的排查和解决过程

oom异常php技巧_体验了一把线上CPU100及应用OOM的排查和解决过程

访客 2024-12-07 0

扫一扫用手机浏览

文章目录 [+]

下面是我碰着的问题,以及一些大略的排查思路,如有不对的地方,欢迎留言谈论。
如果你已经碰着 InMemoryReporterMetrics 导致的OOM问题,并已经办理,则可忽略此文。
若你对CPU100%以及线上运用OOM排查思路不清楚,可以浏览下本文。

oom异常php技巧_体验了一把线上CPU100及应用OOM的排查和解决过程

问题征象

【告警关照-运用非常告警】

oom异常php技巧_体验了一把线上CPU100及应用OOM的排查和解决过程
(图片来自网络侵删)

大略看下告警的信息:谢绝连接,反正便是做事有问题了,请不要太在意马赛克。

环境解释

Spring Cloud F版。

项目中默认利用 spring-cloud-sleuth-zipkin 依赖得到 zipkin-reporter。
剖析的版本创造是 zipkin-reporter版本是 2.7.3 。

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-zipkin</artifactId></dependency>版本:2.0.0.RELEASE

版本解释

问题排查

通过告警信息,知道是哪一台做事器的哪个做事涌现问题。
首先登录做事器进行检讨。

1、检讨做事状态和验证康健检讨URL是否ok

这一步可忽略/跳过,与实际公司的的康健检讨干系,不具有通用性。

①查看做事的进程是否存在。

ps -ef | grep 做事名 ps -aux | grep 做事名

②查看对应做事康健检讨的地址是否正常,检讨 ip port 是否精确

是不是告警做事检讨的url配置错了,一样平常这个不会涌现问题

③验证康健检讨地址

这个康健检讨地址如:http://192.168.1.110:20606/serviceCheck 检讨 IP 和 Port 是否精确。

#做事正常返回结果curlhttp://192.168.1.110:20606/serviceCheck{"appName":"test-app","status":"UP"}#做事非常,做事挂掉curlhttp://192.168.1.110:20606/serviceCheckcurl:(7)couldn'tconnecttohost2、查看做事的日志

查看做事的日志是否还在打印,是否有要求进来。
查看创造做事OOM了。

OOM缺点

tips:java.lang.OutOfMemoryError GC overhead limit exceeded

oracle官方给出了这个缺点产生的缘故原由和解决方法:Exception in thread thread_name: java.lang.OutOfMemoryError: GC Overhead limit exceeded Cause: The detail message "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress. After a garbage collection, if the Java process is spending more than approximately 98% of its time doing garbage collection and if it is recovering less than 2% of the heap and has been doing so far the last 5 (compile time constant) consecutive garbage collections, then a java.lang.OutOfMemoryError is thrown. This exception is typically thrown because the amount of live data barely fits into the Java heap having little free space for new allocations. Action: Increase the heap size. The java.lang.OutOfMemoryError exception for GC Overhead limit exceeded can be turned off with the command line flag -XX:-UseGCOverheadLimit.

缘故原由:大概意思便是说,JVM花费了98%的韶光进行垃圾回收,而只得到2%可用的内存,频繁的进行内存回收(最最少已经进行了5次连续的垃圾回收),JVM就会曝出ava.lang.OutOfMemoryError: GC overhead limit exceeded缺点。

上面tips来源:java.lang.OutOfMemoryError GC overhead limit exceeded缘故原由剖析及办理方案

3、检讨做事器资源占用状况

查询系统中各个进程的资源占用状况,利用 top 命令。
查看出有一个进程为 11441 的进程 CPU 利用率达到300%,如下截图:

CPU爆表

然后 查询这个进程下所有线程的CPU利用情形:

top -H -p pid 保存文件:top -H -n 1 -p pid > /tmp/pid_top.txt

#top-H-p11441PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND11447test2004776m1.6g13mR92.420.374:54.19java11444test2004776m1.6g13mR91.820.374:52.53java11445test2004776m1.6g13mR91.820.374:50.14java11446test2004776m1.6g13mR91.420.374:53.97java....

查看 PID:11441 下面的线程,创造有几个线程占用cpu较高。

4、保存堆栈数据

1、打印系统负载快照top -b -n 2 > /tmp/top.txttop -H -n 1 -p pid > /tmp/pid_top.txt

2、cpu升序打印进程对应线程列表ps -mp-o THREAD,tid,time | sort -k2r > /tmp/进程号_threads.txt

3、看tcp连接数 (最好多次采样)lsof -p 进程号 > /tmp/进程号_lsof.txtlsof -p 进程号 > /tmp/进程号_lsof2.txt

4、查看线程信息 (最好多次采样)jstack -l 进程号 > /tmp/进程号_jstack.txtjstack -l 进程号 > /tmp/进程号_jstack2.txtjstack -l 进程号 > /tmp/进程号_jstack3.txt

5、查看堆内存占用概况jmap -heap 进程号 > /tmp/进程号_jmap_heap.txt

6、查看堆中工具的统计信息jmap -histo 进程号 | head -n 100 > /tmp/进程号_jmap_histo.txt

7、查看GC统计信息jstat -gcutil 进程号 > /tmp/进程号_jstat_gc.txt8、生产对堆快照Heap dumpjmap -dump:format=b,file=/tmp/进程号_jmap_dump.hprof 进程号

堆的全部数据,天生的文件较大。

jmap -dump:live,format=b,file=/tmp/进程号_live_jmap_dump.hprof 进程号

dump:live,这个参数表示我们须要抓取目前在生命周期内的内存工具,也便是说GC收不走的工具,一样平常用这个就行。

拿到涌现问题的快照数据,然后重启做事。

问题剖析

根据上述的操作,已经获取了涌现问题的做事的GC信息、线程堆栈、堆快照等数据。
下面就进行剖析,看问题到底出在哪里。

1、剖析cpu占用100%的线程

转换线程ID

从jstack天生的线程堆栈进程剖析。

将 上面线程ID 为11447 :0x2cb711444 :0x2cb411445 :0x2cb511446 :0x2cb6转为 16进制(jstack命令输出文件记录的线程ID是16进制)。
第一种转换方法 :

$printf“0x%x”11447“0x2cb7”

第二种转换方法 : 在转换的结果加上 0x即可。

查找线程堆栈

$cat11441_jstack.txt|grep"GCtaskthread""GCtaskthread#0(ParallelGC)"os_prio=0tid=0x00007f971401e000nid=0x2cb4runnable"GCtaskthread#1(ParallelGC)"os_prio=0tid=0x00007f9714020000nid=0x2cb5runnable"GCtaskthread#2(ParallelGC)"os_prio=0tid=0x00007f9714022000nid=0x2cb6runnable"GCtaskthread#3(ParallelGC)"os_prio=0tid=0x00007f9714023800nid=0x2cb7runnable

创造这些线程都是在做GC操作。

2、剖析天生的GC文件

S0S1EOMCCSYGCYGCTFGCFGCTGCT0.000.00100.0099.9490.5687.868759.30732235313.1395322.446S0:幸存1区当前利用比例S1:幸存2区当前利用比例E:Eden Space(伊甸园)区利用比例O:Old Gen(老年代)利用比例M:元数据区利用比例CCS:压缩利用比例YGC:年轻代垃圾回收次数FGC:老年代垃圾回收次数FGCT:老年代垃圾回收花费韶光GCT:垃圾回收花费总韶光

FGC 十分频繁。

3、剖析天生的堆快照

利用 Eclipse Memory Analyzer 工具。
下载地址:https://www.eclipse.org/mat/downloads.php

剖析的结果:

看到堆积的大工具的详细内容:

问题大致缘故原由,InMemoryReporterMetrics 引起的OOM。
zipkin2.reporter.InMemoryReporterMetrics @ 0xc1aeaea8Shallow Size: 24 B Retained Size: 925.9 MB

也可以利用:Java内存Dump(https://www.perfma.com/docs/memory/memory-start)进行剖析,如下截图,功能没有MAT强大,有些功能需收费。

4、缘故原由剖析和验证

由于涌现了这个问题,查看涌现问题的这个做事 zipkin的配置,和其他做事没有差异。
创造配置都一样。

然后看在试着对应的 zipkin 的jar包,创造涌现问题的这个做事依赖的 zipkin版本较低。

有问题的做事的 zipkin-reporter-2.7.3.jar其他没有问题的做事 依赖的包 :zipkin-reporter-2.8.4.jar

将有问题的做事依赖的包版本升级,在测试环境进行验证,查看堆栈快照创造没有此问题了。

缘故原由探索

查 zipkin-reporter的 github:搜索 相应的资料https://github.com/openzipkin/zipkin-reporter-java/issues?q=InMemoryReporterMetrics找到此 下面这个issues:https://github.com/openzipkin/zipkin-reporter-java/issues/139

修复代码和验证代码:https://github.com/openzipkin/zipkin-reporter-java/pull/119/files比拟两个版本代码的差异:

大略的DEMO验证:

//修复前的代码:privatefinalConcurrentHashMap<Throwable,AtomicLong>messagesDropped=newConcurrentHashMap<Throwable,AtomicLong>();//修复后的代码:privatefinalConcurrentHashMap<Class<?extendsThrowable>,AtomicLong>messagesDropped=newConcurrentHashMap<>();

修复后利用 这个key :Class<? extends Throwable> 更换 Throwable。

大略验证:

办理方案

将zipkin-reporter 版本进行升级即可。
利用下面依赖配置,引入的 zipkin-reporter版本为 2.8.4 。

<!--zipkin依赖包--><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave</artifactId><version>5.6.4</version></dependency>

小建议:配置JVM参数的时候还是加高下面参数,设置内存溢出的时候输出堆栈快照.

-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=path/filename.hprof参考文章

记一次sleuth发送zipkin非常引起的OOMhttps://www.jianshu.com/p/f8c74943ccd8

彩蛋

附上:百度搜索还是有点坑

上面便是本次文章的全部内容,感谢你的阅读,希望对你有帮助,也欢迎你点赞留言和转发~

关注我,不迷路,及时获取有趣有料内容,See you next good day~

标签:

相关文章

php常量怎么用技巧_PHP 常量详解教程

PHP 常量常量是单个值的标识符(名称)。在脚本中无法改变该值。有效的常量名以字符或下划线开头(常量名称前面没有 $ 符号)。注释...

网站推广 2024-12-09 阅读0 评论0