文档章节

Tomcat报异常:Too many open files 的解决之路

b
 bill_wu
发布于 2018/09/14 06:06
字数 1211
阅读 16
收藏 0

Tomcat报 Jul 21, 2015 8:45:23 AM org.apache.tomcat.util.net.JIoEndpoint$Acceptor runSEVERE: Socket accept failedjava.net.SocketException: Too many open filesat java.net.PlainSocketImpl.socketAccept(Native Method)at java.net.AbstractPlainSoc

Tomcat报
Jul 21, 2015 8:45:23 AM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
SEVERE: Socket accept failed
java.net.SocketException: Too many open files
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
at java.net.ServerSocket.implAccept(ServerSocket.java:530)
at java.net.ServerSocket.accept(ServerSocket.java:498)
at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60)
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:216)
at java.lang.Thread.run(Thread.java:745)
解决的思路:
一眼异常立刻想到ulimit,于是使用
ulimit -a
 查看Linux内核允许的最大资源
open files (-n) 1024
需要调大限制
ulimit -n 65535
经过观察,问题依旧...

通过
lsof|grep tomcat|wc -l
看到tomcat的io居然有1082个,立马想到了nginx与tomcat的不协调造成的,据网络资料显示:tomcat端默认开启了 keepalive,而nginx把连接交给了tomcat并不关系是否关闭,因此tomcat需要等待"connectionTimeout"设置的超 时时间来关闭,所以最好设置“maxKeepAliveRequests”为1,让每个连接只相应一次就关闭,这样就不会等待timeout了。因此设置 tomcat:
<Connector port="8080" protocol="HTTP/1.1"
                maxKeepAliveRequests="1"
              connectionTimeout="20000"
              URIEncoding="UTF-8"
              redirectPort="8443" />
   <!-- A "Connector" using the shared thread pool-->
   <!--
   <Connector executor="tomcatThreadPool"
              port="8080" protocol="HTTP/1.1"
               maxKeepAliveRequests="1"
              connectionTimeout="20000"
              redirectPort="8443" />
重启tomcat,观察,问题依旧!

翻页查看lsof
lsof|grep tomcat|more

发现有大量的memcached的IO,因此把问题定位在memcached上,为了方便观察,新建memcached实例,发现memcached的IO数量逐步增加,最终导致tomcat崩溃!
嗨,终于找到问题了 ^O^

通过code review,发现每次调用memcached的API,都会new一个XMemcachedClient(一个memcached客户端),每次new的时候都会设置一个尺寸的连接池,而连接是预建立的,因此导致memcached的IO数目剧增。

问题终于解决了,memcached的IO数目稳定了,tomcat也运行良好。。。

不经意间,发现memcached的IO数目以连接池的尺寸在递增,心里一落千丈,拔凉拔凉的,貌似还是没解决!

查看tomcat的日志,发现了端倪:
Jul 21, 2015 3:06:40 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MobileService] appears to have started a thread named [Xmemcached-Reactor-0] but has failed to stop it. This is very likely to create a memory leak.
原来在每次重新部署webapp时,tomcat杀不掉XmemcachedClient的连接进程,由于使用的是spring,所以需要在memcachedClient的bean里增加"destroy-method"。
OK,到此为止tomcat的IO以及memcached的IO都稳定了,并在合理范围之内,tomcat的是160左右。
为了担心“maxKeepAliveRequests”的设置对tomcat的性能有影响,暂时删除了“ maxKeepAliveRequests”,需要对tomcat的整体性能优化进行了解才去配置。
小插曲:由于使用了spring框架的监听配置Log4j,如果下面的顺序颠倒了会造成不能写日志的问题
<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
经过一天的推理、怀疑、实验、否定,终于搞定,又过了一次"福尔摩斯"的侦探瘾,作此标记,留给后来人!

今天发现打开的IO仍然在增加,虽然幅度比较少,但最高也达到了960+,因此需要优化Tomcat配置,增加线程池,并配置keepAliveTimeout和maxKeepAliveRequests
<Executor name="mobileThreadPool" namePrefix="catalina-exec-"
maxThreads="600" minSpareThreads="20" maxIdleTime="60000" />
 
<Connector executor="mobileThreadPool" port="8080" protocol="HTTP/1.1"
	connectionTimeout="20000"
	keepAliveTimeout="15000"
	maxKeepAliveRequests="1"
	URIEncoding="UTF-8"
	redirectPort="8443" />

今天使用压力测试,依然出现“Too many open files”,使用ulimit发现“open files (-n)”仍然是1024,那么之前设置的65535是没起作用,而切换到root用户发现却是65535;而在非root用户下
ulimit -n 65535
会报异常:
ulimit: max user processes: cannot modify limit
原来是被 /etc/security/limits.conf 限制了,打开此文件即可看到,对默认用户是有限制的,因此可以加入
*        soft    noproc 65535
*        hard    noproc 65535
*        soft    nofile 65535
*        hard    nofile 65535
 

这样就非root用户就可以设置ulimit为65535了。

设置了ulimit后,我在root下启动tomcat,压力还会容易出现“Too many open files”,但其实使用“lsof -u root|wc -l”并不多,才3000+;root后来我单独建立了个用户来启动,暂时没出现问题。

PS:

/proc/sys/fs/file-max表示kernel中维护的最大文件描述符数目。不管这个系统上有多少了用户登录,有多少个进程在运行,所有打开的文件数目总合都不能超过这个数字。

/etc/security/limit.conf用来设置每个用户最多可以打开的文件数目。

普通用户可以通过ulimit -n 命令来设置hard limit(只能改小) 和soft limit(可以改大和改小).

把上面的内容概括成3条就是:

  1. /proc/sys/fs/file-max 控制整个系统。
  2. /etc/security/limit.conf控制每个用户, 且受到(1)的限制。
  3. ulimit -n用来控制shell及其子进程, 且受到(2)的限制。

本文转载自:http://www.linuxeye.com/Linux/2781.html

b
粉丝 1
博文 27
码字总数 3992
作品 0
广州
私信 提问
Tomcat集群session复制与Oracle的坑。。

问题描述 公司某个系统使用了tomcat自带的集群session复制功能,然后后报了一个oracle驱动包里面的连接不能被序列化的异常。 解决方案 看到这个问题,首先检查整个系统里面的代码有没有用到T...

java技术栈
2017/11/20
0
0
JAVA.NET.SOCKETEXCEPTION: TOO MANY OPEN FILES解决方法

最近随着网站访问量的提高把web服务器移到linux下了,在移服务器的第二天,tomcat频繁的报 java.net.SocketException: Too many open files错误,错误日志达到了100多兆,郁闷了,windows上运...

SunnyWu
2014/11/25
0
0
JAVA.NET.SOCKETEXCEPTION: TOO MANY OPEN FILES

最近随着网站访问量的提高把web服务器移到linux下了,在移服务器的第二天,tomcat频繁的报 java.net.SocketException: Too many open files错误,错误日志达到了100多兆,郁闷了,windows上运...

BryceLoski
05/23
0
0
Tomcat 7优化配置参数

Tomcat的优化主要体现在两方面:内存、并发连接数。 1、内存优化: 优化内存,主要是在bin/catalina.bat/sh 配置文件中进行。linux上,在catalina.sh中添加: JAVA_OPTS="-server -Xms1G -X...

庆沉
2016/10/08
24
0
Tomcat报java.io.IOException: 打开的文件过多

今天后台服务器(Linux)tomcat应用报java.io.IOException: Too many open files 在网上查了一些资料 记录如下: 打开的文件过多,一般来说是由于应用程序对资源使用不当造成,比如没有及时关...

ling118
2018/06/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Element.getBoundingClientRect()

Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。 语法 rectObject = object.getBoundingClientRect(); 值 返回值是一个 DOMRect 对象,这个对象是由该元素的 getC...

JamesView
27分钟前
5
0
设计模式的七大原则

小小小施爷
32分钟前
4
0
Spring Cloud之API 网关Zuul

一、为什么需要网关? 安全性: 1.最主要的一点是网关可以将所有服务的API接口统一聚合,并统一对外暴露。外界系统调用API接口时,都是由网关对外暴露的API接口,外界系统不需要知道微服务系...

尹小狗家的小小喵
34分钟前
4
0
总结:为什么要限制最大连接数?

一个tcp连接需要:1,socket文件描述符;2,IP地址;3,端口;4,内存 原因: 建立连接需要消耗资源,详情查看: https://blog.csdn.net/qj4522/article/details/84892762 https://blog.csd...

浮躁的码农
45分钟前
8
0
我对算卦的认识

现在越来越认识到算卦其实就是帮自己尽快的做一个决定。 有一次看锵锵三人行,有一期一个嘉宾讲了他去算卦的事情。当时他有两个选择,一个是从商,一个是当演员。算卦的结果是当演员,他就放...

我是菜鸟我骄傲
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部