新接手的项目,测试反馈页面同时点击速度快些请求就会报错,返回nginx 502。
Failed to complete processing of a request ,看报错的意思是处理请求失败导致的OOM。本人也在前台点击测试,确实有这个问题,关键是请求也不多,怎么会导致OOM呢?
通过arthas查看服务器的CPU还是很稳定的,就是内存比较吃紧,fullGC比较频繁。
接下来我通过jmap命令导出对应进程的dump日志,命令如下:
jmap -dump:format=b,file=\data\dump_pid3380.hprof 3380
下载对应的dump日志,通过MAT(Memory Analyzer Tool)工具查看分析对应的dump日志,结果如下:
重点关注下Histogram、Dominator Tree、Top Consumers、Duplicate Classes、Leak Suspects
名称解释:
可以看到两个泄露疑点,都占了400M,指向的都是普通的接口请求,这是为啥?接下来我们看下关联树。
通过shallow heap(浅堆)和retained heap(保留堆)的大小判断可以看到最大的其实是byte类型。我们展开org.apache.coyote.http11.Http11OutputBuffer对象,进一步查看空间占用情况。
PS:名词解释:
shallow heap
:对象本身的大小,如果是数组或集合则是各个元素的总大小。
retained heap
:对象本身的大小 + 引用的其他对象的大小。
可以看到都存储在java.nio.HeapByteBuffer对象中。
名词解释:Heap BufferQ(堆缓冲区)
这是最常用的类型,ByteBuf将数据存储到JVMO的堆空间中,并且将实际的数据存放到byte array中来实现。
通过相关类初步可以判定是请求相关的问题,请求返回的头信息并且不包含消息体,剩下的都是000也就是空内容。就是请求返回头的数据缓冲区过大导致.而且属于tomcat包下面,但项目用的是SpringBoot内置的Tomat,按理不会有这种问题,我们继续向下查看。
查看最大占比的内存消费都指向了tomcat下面的包,最大的一些对象看到基本上都是100MB,还都与请求相关,所以接下来查看是不是哪里配置了这个,因为都是100MB还指向接口也太巧了。
查看配置文件找到了元凶:
这max-http-header-size
居然被配置成了100MB,默认值是8KB,所以我暂且把这块注释掉,让它使用默认值,Jenkins重新构建发布项目后,同时多人测试验证,没有再出现nginx 502问题,应用程序也没有再出现OOM异常。之前为啥会把max-http-header-size配置这么大目前我还不知道啥原因,猜测是有啥特殊需求要传大header?正常也不应该把大数据放在请求头里面,后续有需要再继续调整优化了。
本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位指出。
主页:共饮一杯无的博客汇总👨💻保持热爱,奔赴下一场山海。🏃🏃🏃