做项目的时候,用到了mina框架,与server进行交互。由于采用的是短连接+心跳包+断线重连的方式,因此网络不稳定的时候经常会出现断线重连。

那么有时候偶尔会出现EMFILE: open too many files exception的问题,看堆栈信息是出在new socketconnector的时候。

Jacklondon Chen的一篇文章

Apache NIO 框架 Mina 使用中出现 too many open files 问题的解决办法

http://www.cnblogs.com/jacklondon/archive/2011/03/16/1985926.html 提到了这个问题

最近一段时间在用 Apache NIO 框架 Mina, 用起来感觉不错。

我们使用 Apache NIO 作了一个 TCP server, 来处理 TCP 数据包。

只是最近突然发现 server 经常连接不上,每周一两次。用户没有进行屏幕截图就直接重新启动,没有找到第一手的故障现场资料。

开始以为是 JDK 及其他 Java 包 版本问题,连续升级了几次,问题依旧。

后来终于在客户现场抓个现行。屏幕截图、备份日志文件后,逐个 ping/telnet 各个服务器及其端口。发现都没有问题,奇怪了。突然想起,用 netstat 看看网络连接状态(windows server 2008), 发现大量的 127.0.0.1 到 127.0.0.1 的连接,状态为 ESTABLISHED , 端口看起来是逐步增加的。

再看日志文件,发现写出来的是 "too many open files” 导致 socket 连接不能建立。

网上搜索 google ,发现报告此问题的人不少,却没有人有解决方法。Apache Mina 网站上的 FAQ 也提到这个问题,说是要更改 windows 注册表,简直是胡扯。只能自己慢慢调查了。

这是一个类似于内存泄露的问题,只不过这里是 socket 未关闭导致。英文名词为 : “socket leak”。

经过几天的调试,发现了解决办法,特记录下来,供大家参考。

a. 使用到 NioSocketAcceptor 一个,用来 listen ,没有问题。

b. 自定义 IoHandlerAdapter 在 Mina 中是 Singleton, 只创建一次,也没有问题。

c. 自定义 IoHandlerAdapter 中需要有以下代码:

public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        session.close(true);//force close right now
}

public void sessionOpened(IoSession session) throws Exception {
    session.getConfig().setBothIdleTime(180);//set timeout seconds, must
}
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
    session.close(true);//timeout now, close it
}
d. 因代码中使用了类似代理服务器的程序,需要特别处理。这里特别强调一下,Mina 自带的 proxy 程序没有实用价值。它使用的是多个客户端连接,服务器只用一个 NioSocketConnector 转发,这很成问题。如果 connector 断开了,岂不是影响很大?因此需要改成每个 客户端连接 对应一个 connector 的转发模式。

e. NioSocketConnector 并非 thread safe, 这点 Mina 文档中只字不提。很让人抓狂。

f. 系统中使用了以下 Mina NIO 的 Java 对象:

NioSocketAcceptor 用来 listen, 1个,配 1 个 IoHandlerAdapter

每次 1 客户 socket 连接,对应1 个 IoSession, 创建 1 个 NioSocketConnector 连接后端服务器,然后自动创建一个 IoSession 作为当前客户 socket 的 peer (同伴),也就是两个 IoSession 有对应关系。

g. 无论是客户 socket 连接的 IoSession 还是 peer IoSession , 在 sessionClosed 中需要调用 peer.close(false); 这里的 close(false) 不是立即关闭,而是让 peer 发完数据再关闭。这是由 NIO 这种异步操作特性决定的。这里不会造成死循环: client IoSession 调用 peer.close(false), 而 peer 反过来调用 client IoSession.close(false)。好像 Mina 做了特别处理。

h. 特别的提醒,NioSocketConnector 也要关闭。函数名是 dispose()。这点特别重要。这次出现 too many open files 的问题根源在这里。而 Mina 文档中只字不提。而 NioSocketConnector 与 peer IoSession 使用 127.0.0.1 端随机端口连接,匪夷所思。

而 peer IoSession 关闭后,没有关闭 NioSocketConnector , 也没有给它发 close event, 或者让它进入 exception, 这种设计也不好。 IoSession 关闭后,留着 NioSocketConnector 也是无用,还白白成了一个 ESTABLISHED 状态的连接,导致 socket leak。 这似乎就是所谓的半开 socket ? 还是觉得 Mina 这种设计不好。

上面写的是问题故障解决办法,特与大家分享。希望其它碰到此问题的人,少走点弯路。

最后总结,Mina 总体设计不错,代码质量也还好,我报告过一次 bug, 开发团队也能很快回复。只是发现文档欠缺,例子都是“示意”,意思意思而已,不能直接用起来。上手有些门槛。

重点是 h。原本重连的时候紧紧是new 一个connnector重连服务器,没有把之前的connector关闭,现在加上关闭connector,connector.dispose()会

阻塞线程,需要在线程中处理。

关于mina框架EMFILE: open too many files exception的处理的更多相关文章

  1. mina框架详解

     转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...

  2. GPS部标平台的架构设计(三) 基于struts+spring+hibernate+ibatis+quartz+mina框架开发GPS平台

    注意,此版本是2014年研发的基于Spring2.5和Struts2的版本,此版本的源码仍然销售,但已不再提供源码升级的服务,因为目前我们开发的主流新版本是2015-2016年近一年推出的基于spri ...

  3. 基于Java Mina框架的部标808服务器设计和开发

    在开发部标GPS平台中,部标808GPS服务器是系统的核心关键,决定了部标平台的稳定性和行那个.Linux服务器是首选,为了跨平台,开发语言选择Java自不待言. 我们为客户开发的部标服务器基于Min ...

  4. Android Mina框架的学习笔记

    Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...

  5. 基于MINA框架快速开发网络应用程序

    1.MINA框架简介 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架.通过使用M ...

  6. 使用Mina框架开发 QQ Android 客户端

    Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步AP ...

  7. Mina框架断包、粘包问题解决方式

    Mina框架断包.粘包问题解决方式 Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(当然.也能够提供JAVA 对象的序 ...

  8. Mina框架与Spring整合配置文件

    Mina框架与Spring的整合事实上非常easy,主要是要弄清楚要注入的属性的名称,进而选择合适的注入方法. 关于Spring的四种注入方法请还有一篇文章:spring依赖注入的四种方式 <? ...

  9. mina框架tcpt通讯接收数据断包粘包处理

    用mina做基于tcp,udp有通讯有段时间了,一直对编码解码不是很熟悉,这次做项目的时候碰到了断包情况,贴一下解决过程, 我接受数据格式如下图所示: unit32为c++中数据类型,代表4个字节,由 ...

随机推荐

  1. PHP 生成指定大小随机图片

    PHP 生成指定大小随机图片 <?php $image_width = 100; $image_height = 100; $image_str = ''; if (isset($_GET['w ...

  2. form表单reset重置按钮

    如果ajax提交完数据,后想清空表单内容 ,以前都是用这个方法$("#id").val(""); 一个一个清空的,其实可以在form表单中加个隐藏的<in ...

  3. 【freemaker】之循环,判断,对象取值

    entity: public class Employee { private Integer id; private String name; private Integer age; privat ...

  4. 【mysql】之MySQL导入sql脚本错误:2006 - MySQL server has gone away

    到如一些小脚本很少报错,但最近导入一个10+M的SQL脚本,却重复报错: Error occured at:2014-03-24 11:42:24Line no.:85Error Code: 2006 ...

  5. item2,实现singleton模式

    单例模式? 只能实现一个实例的类成为单例. ============== muduo库中单例模式实现 #include<boost/noncopyable.hpp> //#include ...

  6. 2. scala中的数组

    一. 数组声明 定长数组 scala> new Array[String](5) res1: Array[String] = Array(null, null, null, null, null ...

  7. Javascript之UI线程与性能优化

    在浏览器中,Javascript执行与UI更新是发生在同一个进程(浏览器UI线程)中的.UI线程的工作基于一个简单的队列系统,任务会被保存到队列中直到进程空闲时被提取出来执行.所以Javascript ...

  8. Chrome开发者工具详解(2)

    Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Network面板.Timeline面板.Profiles面板.Application面板.Sec ...

  9. PLSQL_Database Link的基本概念和用法(概念)

    2014-06-08 Created By BaoXinjian

  10. Python 结巴分词(1)分词

    利用结巴分词来进行词频的统计,并输出到文件中. 结巴分词github地址:结巴分词 结巴分词的特点: 支持三种分词模式: 精确模式,试图将句子最精确地切开,适合文本分析: 全模式,把句子中所有的可以成 ...