应用被oom killer干掉的排查

linux java应用间歇性不可用问题排查:

结论

Java引用,触发了linux内核的oom killer机制,以至于java进程被kill掉。

  1. 现象:

    6月4号,应用现故障时,使用ps -ef|grep java命令查看进程时发现java进程不见了;

    6月5号 在另外一套应用环境进行压测时,也出现了这个现象;

  2. 排查:

    查看日系统日志: /var/log/messages

    6月4号系统日志截图

6月5号系统日志截图

​ 内核日志显示 oom killer 将java进程杀掉。

虚拟机内存现状:

​ 虚拟的内存的总大小是8G,jvm启动参数设置的初始堆内存是4G,最大直接内存15G。

​ 虚拟机中部署的其他应用有:

nginx服务、360entclient、/opt/datadog-agent/embedded/bin/python

​ 在刚启动网关服务后,系统内存已经只剩下几十兆左右的可用内存。此时如果有比较消耗内存的操作,就会触发系统的oom killer。

点此了解oom killer

​ 占用内存的操作,初步怀疑是批量缓存同步操作,

  1. 解决方案:

    以下几种解决方案供参考

    • 增加系统内存
    • 是优化进程,使其占用内存降低。
    • 是可以使用oom_score_adj参数,这个参数会被计算影响到oom_score,改了之后就可以避免进程被杀死(不推荐)。
  2. 具体调整:

    修改网关服务主体jvm启动参数,降低使用内存,降低触发oom killer的可能性。

    ## 修改jvm内存从4g调整到2g
    JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g"
    ## 调整直接直接内存
    JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=1g"
    
    

    以上是本次问题的排查结论,下面是排查过程的记录。

具体排查过程做了简单的记录

下面是具体的问题定位过程,由于对系统的不熟悉和对问题现象行的不明确,导致一致定位不到根本问题。走了些弯路。

问题现象

本次问题排查经过了一些摸索,记录一下:

服务器:20.26.85.230

问题描述:

6月3号:

同事描述:重启nginx或者重启应用后,服务恢复正常。

临时考虑是系统配置问题:

  1. top(top -Hp 进程id)查看cpu和内存使用情况:cpu利用率不高,内存使用率偏高。

  2. ulimit -a 查看句柄数设置,发现普通用户最大句柄数为16384。明显少于规范使用的65535

    试探性的将句柄数设置到65535观察。后来再次出现故障,句柄数调大并未解决问题。

6月4号:

1、jstack 将线程堆栈信息dump下来(jstack pid >> file)。11点后的一个小时,进行了4次的线程信息取样:

总线数量分别是:696、644、650、650

  1. RUNNABLE,线程处于执行中
  2. BLOCKED,线程被阻塞
  3. WAITING,线程正在等待
  4. TIMED_WAITING,这个一般是指这个线程是Timer定期执行任务,但是当前处于waiting状态

线程数量不多,未发现阻塞线程,无线程积压的情况

内存dump:

jmap -dump:format=b,file=jmap. pid

11:42

发现应用会”自动重启“。问了别人后发现,可能是其他项目组的人员进行了重启

1、RUNNABLE,线程处于执行中
2、BLOCKED,线程被阻塞
3、WAITING,线程正在等待
4、TIMED_WAITING,这个一般是指这个线程是Timer定期执行任务,但是当前处于waiting状态

一个同事 的意见是:增加ng日志打印请求、返回信息,怀疑ng和网关服务之间有问题

ng默认不支持打印请求内容:
需要增加lua模块,然后用lua脚本来获取请求和返回的内容并且打印到日志中。

/home/aifgw/nginx/sbin/nginx -s reload

监控ng日志、监控jvm gc (jstat -gcutil 进程id)

发现java进程不见了;

linux的OOM killer

Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉。
因此,发现java进程突然没了,首先要怀疑是不是被linux的OOM killer给干掉了!

查看系统报错日志: /var/log/messages

网关服务原始启动脚本(启动参数设置):

JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g"
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
JAVA_OPT="${JAVA_OPT} -Dcsf.client.name=xxx -Dxxx.server.name=xxx"
JAVA_OPT="${JAVA_OPT} -Dfile.encoding=UTF8 -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib"
JAVA_OPT="${JAVA_OPT} -Dprint.logback.status.enable=false"
JAVA_OPT="${JAVA_OPT} -Dlogback.configurationFile=${BASE_DIR}/conf/logback.xml -javaagent:/home/user/agentlib/log4x-agent.jar"
JAVA_OPT="${JAVA_OPT} -Darea.code="

启动参数中 最小堆、最大堆内存:4G; 直接内存:15G

而系统内存只有8G

应用启动成功后,系统可用内存只有100M的空闲内存。很有可能触发系统的OOM killer。

解决方案:

  • 增加系统内存

  • 是优化进程,使其占用内存降低。

  • 是可以使用oom_score_adj参数,这个参数会被计算影响到oom_score,改了之后就可以避免进程被杀死(不推荐)。

http://www.wowotech.net/memory_management/oom.html

尝试解决方案:

修改配置:

JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dev/shm/oom_%p.log"
## 修改jvm内存从4g调整到2g
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g"

6月5号:

进程被linux oom killer kill掉了

性能压测服务器:20.26.85.228

启动参数:

JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g"
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
JAVA_OPT="${JAVA_OPT} -Dcsf.client.name=xxx -Dxxx.server.name=xxx"
JAVA_OPT="${JAVA_OPT} -Dfile.encoding=UTF8 -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib"
JAVA_OPT="${JAVA_OPT} -Dprint.logback.status.enable=false"
JAVA_OPT="${JAVA_OPT} -Dlogback.configurationFile=${BASE_DIR}/conf/logback.xml -javaagent:/home/user/agentlib/log4x-agent.jar"
JAVA_OPT="${JAVA_OPT} -Darea.code="

你可能感兴趣的:(应用被oom killer干掉的排查)