关于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个字节,由 ...
随机推荐
- 按后退键退出Android程序
主要的目的是按后退键的时候,让程序能够退出. 实现起来的思路: 1.捕获后退键被按了这个事件. Java代码 @Override public boolean onKeyDown(int keyCo ...
- HttpSessionBindingListener和HttpSessionAttributeListener区别 - gengkunpeng的专栏 - 博客频道 - CSDN.NET
分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 HttpSession ...
- datagridview 不显示行号的问题
环境:C#,Winform 场景: 窗体上有两个tab页A.B,每个tab页上都有一个DatagridView.窗体加载后,显示tab A选项卡.序号正常显示,但点击B选项卡后,DatagridVie ...
- 【MySQL】索引长度的一些限制
有同学问到InnoDB的索引长度问题,简单说几个tips. MySQL的每个单表中所创建的索引长度是有限制的,且对不同存储引擎下的表有不同的限制. myisam表,单列索引,最大长度不能超过 1000 ...
- Ignoring HTTPS certificates
Our Development setups won't have valid or trusted certificates. When do you want test our webserver ...
- div里面的内容超出自身高度时,显示省略号
1.给DIV设置属性:width: 200px; text-overflow: ellipsis; overflow: hidden; 当div里面的内容总宽度找过 200PX的时候,超出的部分会以“ ...
- 从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中
//从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中 //作者:sandy //时间:2015-10-10 #inclu ...
- mat(Eclipse Memory Analyzer tool)之二--heap dump分析
文章中的shallow.retained关键字的说明见:GC是如何回收时的判断依据.shallow size.retained size 在本文中,将介绍MAT(Eclipse Memory Anal ...
- js上移、下移、置顶、置底功能实现
实现页面上列表内容上移.下移.置顶.置底 功能,主要实现思路是节点操作,比如说:上移,直接把点击项移动到前一个节点,以此类推,当然实际代码实现还要加些判断,如当前点击操作项是否已经是置底或置底了,如果 ...
- Java多线程之银行出纳员仿真
package concurrent; import java.util.LinkedList; import java.util.PriorityQueue; import java.util.Qu ...