定时频繁的查询es导致Too many open files 与 java.lang.OutOfMemoryError

在使用es的过程中遇到了两个问题:

一、 java.net.SocketException: Too many open files

出现这种问题一般是因为打开过多的句柄(或者请求链接),超出系统设定的句柄数。我这里是因为系统定时的去调用es,导致超出系统设定的请求链接次数。

一般解决方法:

1、查看句柄限制数量

ulimit -a

2、临时(重启后失效):

ulimit -n 1024000(非root用户限制到4096)   

3、永久生效(需要重启)
vim /etc/security/limits.conf
#在最后加入

* soft nofile 1024000 
* hard nofile 1024000

二、java.net.SocketException: Unexpected end of file from server

java.lang.OutOfMemoryError: Java heap space

一般解决方法:
oom问题的原因是内存不足的造成的,oom的话可以从代码优化,以及系统调优两个方面解决。最好的是优化代码,实在不行再去系统调优。

上面给出了问题出错的问原因,可造成问题的根本原因是什么呢?以及如何解决呢?

分析:一开始只出现了第一个问题,以为是句柄数不够,结果我增加了句柄数,第一个问题解决了但是出现了oom内存溢出的问题,于是:
1、我增大系统启动时的XMX_SIZE参数,分配更多的运行内存,我设置的是XMX_SIZE=2048m,但是发现不行
2、我使用了线程池异步调用es,还是不行,线程池仅仅减少了内存的消耗,也不行
3、因为在查询es的过程中我用到了rest调用第三方接口,考虑是不是rest消耗了性能,所以我使用了rest的线程池,减少内存的消耗,还是不行。
4、优化代码
上面的方法不是解决问题的根本方法!必须优化业务代码。
我分析代码后发现,我每次查询es都会创建es连接实例RestHighLevelClient,RestHighLevelClient连接实例是长连接,每个长连接如果没有关闭会占用一定的内存,所以随着时间的增加,长连接越来越多,这是非常消耗性能的!最终必然导致OOM!
所以我在系统初始化的时候创建了一个连接实例,后面所有的查询都是使用同一个连接实例,而不是每次都创建,所以问题解决了!定时频繁的查询es导致Too many open files 与 java.lang.OutOfMemoryError_第1张图片

你可能感兴趣的:(Bug汇总,java,jvm,开发语言)