Java基础、中级、高级、架构面试资料

Mina打开文件过多问题解决方案

JAVA herman 4737浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日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打开文件过多问题解决方案