关于mina框架EMFILE: open too many files exception的处理
做项目的时候,用到了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的处理的更多相关文章
- mina框架详解
转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...
- GPS部标平台的架构设计(三) 基于struts+spring+hibernate+ibatis+quartz+mina框架开发GPS平台
注意,此版本是2014年研发的基于Spring2.5和Struts2的版本,此版本的源码仍然销售,但已不再提供源码升级的服务,因为目前我们开发的主流新版本是2015-2016年近一年推出的基于spri ...
- 基于Java Mina框架的部标808服务器设计和开发
在开发部标GPS平台中,部标808GPS服务器是系统的核心关键,决定了部标平台的稳定性和行那个.Linux服务器是首选,为了跨平台,开发语言选择Java自不待言. 我们为客户开发的部标服务器基于Min ...
- Android Mina框架的学习笔记
Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...
- 基于MINA框架快速开发网络应用程序
1.MINA框架简介 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架.通过使用M ...
- 使用Mina框架开发 QQ Android 客户端
Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步AP ...
- Mina框架断包、粘包问题解决方式
Mina框架断包.粘包问题解决方式 Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(当然.也能够提供JAVA 对象的序 ...
- Mina框架与Spring整合配置文件
Mina框架与Spring的整合事实上非常easy,主要是要弄清楚要注入的属性的名称,进而选择合适的注入方法. 关于Spring的四种注入方法请还有一篇文章:spring依赖注入的四种方式 <? ...
- mina框架tcpt通讯接收数据断包粘包处理
用mina做基于tcp,udp有通讯有段时间了,一直对编码解码不是很熟悉,这次做项目的时候碰到了断包情况,贴一下解决过程, 我接受数据格式如下图所示: unit32为c++中数据类型,代表4个字节,由 ...
随机推荐
- ICSharpCode.SharpZipLib.dll,MyZip.dll,Ionic.Zip.dll 使用
MyZip.dll : 有BUG,会把子目录的文件解压到根目录.. ICSharpCode.SharpZipLib.dll: 把ICSharpCode.SharpZipLib.dll复制一份,重命名为 ...
- VS2010打开项目时,出现“已经在解决方案中打开了具有该名称的项目”问题的解决方案
用的是VSS代码管理.一打开解决方案就看到有个类库不能加载. 解决方法: 直接右键编辑无法加载的类库,或者记事本编辑有问题类库的csproj文件, 删除以下几行: <SccProjectName ...
- Windows2012修改光驱盘符
1.输入diskmgmt.msc打开磁盘管理器 2.找到需要修改的盘符,右键点击修改盘符
- VoLTE、呼叫等待(保持)
VoLTE 的出现是手机通话的革命,VoLTE带来更好通话质量,更快的接通时间,接近0掉线这些特点,还可以一边通话一边上网,一方面VoLTE需要运营商的支持,另外一方面也需要手机终端的支持. 什么手机 ...
- POJ 3709 K-Anonymous Sequence
题目大意:将一个升序的,有N个元素的序列,分组.要求每组的元素不少于K个,计算出组内各元素与最小元素的之差的和,将每组的这个值加起来,其和要最小. N<500000,K<N 分析: dp[ ...
- ADB工具 获取ROOT权限及复制文件方法
adb push d:\tm3_sqlit.db data/zouhao/tm3_sqlit.dbadb pull data/zouhao/tm3_sqlit.db d:\tm3_sqlit.db a ...
- iphone Dev 开发实例10:How To Add a Slide-out Sidebar Menu in Your Apps
Creating the Xcode Project With a basic idea about what we’ll build, let’s move on. You can create t ...
- PLSQL_闪回操作5_Flashback Table
2014-12-09 Created By BaoXinjian
- Report_客制化以PLSQL输出HTML标记实现WEB报表(案例)
2014-05-31 Created By BaoXinjian
- cf380D Sereja and Cinema 组合数学
time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...