本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
最近在使用mina开发过程中遇到了打开文件过多问题,一大堆的java.io.IOException: Too many open files。网上搜索问题的解决方案,大多都是修改Linux系统的配置,提高程序打开文件的数量。
然而并没有什么卵用,因为你程序上的根本问题没有得到解决,再怎么设置都会有瓶颈。
打开文件过多,造成的原因,一般有以下两种情况:
1.打开的文件没有关闭
2.通讯连接没有完全关闭
有人可能有疑问了,为什么打开文件过多和通讯有什么关系。这也正是很多人出现问题不知道是通讯造成的原因,而错误盲目的乱改代码。真正的原因是因为Linux系统上一个socket就是一个打开的文件,因此过多的socket未被完全关闭,就会造成打开文件过多。
那么如何彻底的关闭Mina的socket连接呢,看以下代码:
public void test(){ IoConnector connector = null; IoSession session = null; try { if (null == session || null == session.getRemoteAddress() || !session.isConnected()) { connector = new NioSocketConnector(); // 连接服务器动作,超时时间为3秒 connector.setConnectTimeoutMillis(3000L); connector.getSessionConfig().setUseReadOperation(true); // 创建接收数据的过滤器 DefaultIoFilterChainBuilder chain = connector.getFilterChain(); // 设置通信协议 chain.addLast("codec", new ProtocolCodecFilter(new AppClientCodecFactory())); /** update by Herman.Xiong at 2014年11月21日 16:34:15 新增心跳处理 */ //chain.addLast("keepAlive", new ControlHeatbeat()); // 设定客户端的消息处理器:一个AppClientHandler对象 connector.setHandler(new AscJavaClientHandler()); // 连结到服务器: ConnectFuture cf = connector.connect(new InetSocketAddress("10.10.2.215", 6001)); // 等待连接创建完成 cf.awaitUninterruptibly(); // 获取会话 session = cf.getSession(); session.write(message).awaitUninterruptibly(); //由于上面已经设置setUseReadOperation(true),故IoSession.read()方法才可用 ReadFuture readFuture = session.read(); //因其内部使用BlockingQueue,故Server端用之可能会内存泄漏,但Client端可适当用之 if(readFuture.awaitUninterruptibly(90, TimeUnit.SECONDS)){ //等到收到消息 log.info(readFuture.getMessage());//获取收到的消息 }else{ log.warn("读取[/" + ipAddress + ":" + port + "]超时"); } } }catch (Exception e) { log.error("通讯异常!"+e.getMessage(),e); }finally{ // 等待连接关闭 if (null != session) { session.close(true); session.getService().dispose(); session=null; } // 关闭客户端线程 if (null != connector) { connector.dispose(); connector=null; } } }
很多人就是因为没有写session.getService().dispose();和connector.dispose();导致文件句柄泄漏的。当总的文件句柄数超过系统设置值(ulimit -n 查看同一个进程允许的最大文件句柄数),则抛出异常“java.io.IOException: Too many open files",导致无法创建新的连接,服务器挂掉。
版权声明:本文为博主原创文章,未经博主允许不得转载。原文地址http://www.xttblog.com/?p=446
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » Mina打开文件过多问题解决方案