最近一段时间在用 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, 开发团队也能很快回复。只是发现文档欠缺,例子都是“示意”,意思意思而已,不能直接用起来。上手有些门槛。
发表于 http://jacklondon.cnblogs.com,转载请注明出处。
-----------------
标签: NIO, Mina, socket leak
绿色通道:好文要顶关注我收藏该文与我联系
Jacklondon Chen
关注 - 0
粉丝 - 2
+加关注
1
0
(请您对文章做出评价)
« 博主前一篇:刚发布新的 web 单点登录系统,欢迎下载试用,欢迎提建议
» 博主后一篇:PostgreSQL 数据库在 Windows Server 2008 上安装注意事项
posted @ 2011-03-16 12:43 Jacklondon Chen 阅读(956) 评论(9) 编辑 收藏
评论
回复 引用 查看
#1楼2011-08-04 12:58 | zeitgeist
博主好,
我遇到了与你相似问题,问题还没解决,
我想问下上面步骤c 中的代码是写在客户端的还是写在服务器端
回复 引用 查看
#2楼[楼主]2011-08-05 19:18 | Jacklondon Chen
@zeitgeist
我这边代码都是服务器端代码,没有客户端代码。上面 h 提到NioSocketConnector.dispose(),我忘了写明在哪里调用,我会尽快更新补上。
不知道您的代码,是否也是类似于代理服务器。
回复 引用 查看
#3楼[楼主]2011-08-11 12:57 | Jacklondon Chen
引用zeitgeist:
博主好,
我遇到了与你相似问题,问题还没解决,
我想问下上面步骤c 中的代码是写在客户端的还是写在服务器端
我这边是在 IoHandlerAdapter 子类中,关闭对应的 connector:
@Override
public void sessionClosed(IoSession session) throws Exception {
IoConnector con = (IoConnector) session.getAttribute(SsoMinaUtils.IO_SESSION_CONTEXT_KEY_IO_CONNECTOR);
SsoMinaUtils.closeQuietly(con);
回复 引用 查看
#4楼2011-08-12 22:42 | zeitgeist
@Jacklondon Chen
博主你好
非常感谢你给的答复。我的服务现在暂时没有什么问题,但是我还是有2个 问题。
1 在你的文章中 h 步骤中提到的 NioSocketConnector也要关闭的,不知道你指的是在什么情况下关闭,肯定不是在IoSession关闭时关闭吧。
2 本人对Mina只是刚接触,对你说的代理服务器不是很清楚。我应该没用到。
我的服务大概是这样的
服务端:用来提供搜索服务,搜索功能依靠lucene.
客户端:tomcat服务器执行的代码作为客户端,发出搜索请求。
由于服务中其他模块的影响暂时只能将以上两部分放到同一个服务器上。
不知道这样的做法有什么缺陷,麻烦博主能够给出一些建议。
再次感谢能够博主热心回复。
回复 引用 查看
#5楼2011-08-19 10:37 | happyblue
引用zeitgeist:
@Jacklondon Chen
博主你好
非常感谢你给的答复。我的服务现在暂时没有什么问题,但是我还是有2个 问题。
1 在你的文章中 h 步骤中提到的 NioSocketConnector也要关闭的,不知道你指的是在什么情况下关闭,肯定不是在IoSession关闭时关闭吧。
2 本人对Mina只是刚接触,对你说的代理服务器不是很清楚。我应该没用到。
我的服务大概是这样的
服务端:用来提供搜索服务,搜索功能依靠lucene.
客户端:tomcat服务器执行的代码作为客户端,发出搜索请求。
由于服务中其他模块的影响暂时只能将以上两部分放到同一个服务器上。
不知道这样...
NioSocketConnector关闭的问题主要出现在 你的服务器即作为Mina的服务端同时也作为mina的客户端跟其他服务打交道的时候
回复 引用 查看
#6楼[楼主]2011-08-19 13:32 | Jacklondon Chen
引用zeitgeist:
@Jacklondon Chen
博主你好
非常感谢你给的答复。我的服务现在暂时没有什么问题,但是我还是有2个 问题。
1 在你的文章中 h 步骤中提到的 NioSocketConnector也要关闭的,不知道你指的是在什么情况下关闭,肯定不是在IoSession关闭时关闭吧。
2 本人对Mina只是刚接触,对你说的代理服务器不是很清楚。我应该没用到。
我的服务大概是这样的
服务端:用来提供搜索服务,搜索功能依靠lucene.
客户端:tomcat服务器执行的代码作为客户端,发出搜索请求。
由于服务中其他模块的影响暂时只能将以上两部分放到同一个服务器上。
不知道这样...
zeitgeist,如果你的服务器端只提供搜索服务,那么应该不需要用 mina.
不太清楚你所说的客户端用 tomcat 是什么架构。
据我个人理解,如果你的服务器端和客户端,都是用 tomcat ,那么这两个系统中,根本不需要做什么通讯。Web/HTTP 协议中,本来就可以在页面中链接来链接去的。
回复 引用 查看
#7楼2011-09-09 10:24 | zj6882917
博主你好,很高兴看到你的这篇博文,我的项目也有这个问题,但是这个bug只有windows 2008上产生,在rh6.0上面是没有的。代码是相同的。
再有就是,我在开发环境中断住IoHandlerAdapter子类中的exceptionCaught和sessionIdle,在没有任何客户连入的情况下,依然会长时间产生多个127.0.0.1的本地连接,但是exceptionCaught和sessionIdle事件从来没有被触发过。所以我貌似没办法用你的办法修补我服务中的问题。
请博主指点迷津。
回复 引用 查看
#8楼[楼主]2011-09-09 22:08 | Jacklondon Chen
引用zj6882917:
博主你好,很高兴看到你的这篇博文,我的项目也有这个问题,但是这个bug只有windows 2008上产生,在rh6.0上面是没有的。代码是相同的。
再有就是,我在开发环境中断住IoHandlerAdapter子类中的exceptionCaught和sessionIdle,在没有任何客户连入的情况下,依然会长时间产生多个127.0.0.1的本地连接,但是exceptionCaught和sessionIdle事件从来没有被触发过。所以我貌似没办法用你的办法修补我服务中的问题。
请博主指点迷津。
能略微透漏一下你用 mina 写什么样的程序么?代理服务器?socket 服务器?socket 客户端?
回复 引用 查看
#9楼2011-10-30 13:53 | zj6882917
@Jacklondon Chen
引用Jacklondon Chen:
引用zj6882917:
博主你好,很高兴看到你的这篇博文,我的项目也有这个问题,但是这个bug只有windows 2008上产生,在rh6.0上面是没有的。代码是相同的。
再有就是,我在开发环境中断住IoHandlerAdapter子类中的exceptionCaught和sessionIdle,在没有任何客户连入的情况下,依然会长时间产生多个127.0.0.1的本地连接,但是exceptionCaught和sessionIdle事件从来没有被触发过。所以我貌似没办法用你的办法修补我服务中的问题。
请博主指点迷津。
能略微透漏一下你用...
感谢楼主关注我的恢复,我是用mina作socket服务器,在windows 2008下后非常多的本地端口连接本地端口的tcp连接,不知为何。
在rh6上面曾经发现过too many open files 问题,但是是因为我的代码问题,呵呵,有一路数据忘记close的缘故。
分享到:
相关推荐
总结来说,本教程将引导你从理论到实践,掌握Java NIO的基本原理,理解Mina框架的使用,以及如何在SpringBoot环境中整合Mina实现高效的网络通信。通过这些知识的学习,你将具备开发高并发、高性能网络应用的能力。
标题中的“Apache MINA框架相关资料”涵盖了对MINA框架的全面学习材料,包括中文参考手册、源码分析、API文档和与Spring框架的整合指南。 1. **中文参考手册**(Apache_Mina_Server_2.0中文参考手册V1.0.pdf):这...
Apache Mina是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个"apache-mina-2.0.4.rar"压缩包包含的是Apache Mina 2.0.4版本的源代码,是深入理解和定制Mina的...
本学习资料将深入探讨Apache NIO的核心概念、组件以及其在实际开发中的应用。 首先,我们要理解NIO的基本理念。传统的BIO模型在进行I/O操作时,如果一个线程正在读取或写入数据,那么这个线程会一直被阻塞,直到I/O...
标题中的“apache下的mina框架”表明我们将探讨的是Apache软件基金会下的这个项目。 MINA的核心特性在于它的异步事件驱动模型,这使得它在处理大量并发连接时表现出色。这种模型基于Java NIO(Non-blocking I/O),...
Apache Mina 框架是一个强大的网络通信应用框架,它主要针对基于TCP/IP和UDP/IP的协议栈,同时也支持Java对象序列化和其他通信方式。Mina 的核心设计目标是帮助开发者快速构建高性能、高可扩展性的网络应用。它采用...
Apache MINA(Multipurpose Infrastructure for Network Applications)是一个高性能、异步事件驱动的网络应用程序框架,主要用Java语言编写。MINA旨在简化网络编程,特别是TCP/IP和UDP/IP协议的应用开发,如HTTP、...
在这个"网络编程(socket、NIO、mina)---demo"的主题中,我们将深入探讨三个关键概念:Socket编程、非阻塞I/O(Non-blocking I/O,简称NIO)以及Apache Mina框架。这些技术广泛应用于构建高性能、高并发的网络应用...
在标题"apache-mina-2.0.4.rar_Mina框架_SerialAddress_mina_mina apache down"中,我们关注到"SerialAddress",这在Mina框架中是一个关键概念。 1. **Mina框架**:Mina的核心在于其非阻塞I/O模型,基于Java NIO...
Apache Mina是一个高性能的网络应用框架,主要用于简化网络服务的开发,如TCP/IP和UDP通信。在Mina中,ByteBuffer的使用是至关重要的,因为它提供了高效的数据读写机制。本篇将深入探讨Java NIO(非阻塞I/O)中的...
apache-mina-2.0.4 架包 源码 学习教程.apache mina是Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序...
在MINA中,log4j用于收集和输出框架运行过程中的调试信息、警告和错误,帮助开发者追踪和解决问题。 3. **slf4j-api-1.5.11.jar**:简单日志门面(SLF4J)是一个为各种日志框架提供一个抽象层的API,允许最终用户在...
MINA框架(Multipurpose Infrastructure for Network Applications)是基于Java NIO设计的网络应用程序框架,其特点是采用松耦合架构,支持灵活的过滤器机制,同时单元测试也更为容易实现。MINA允许自定义线程数量,...
深入理解Apache_Mina_(1)----_Mina的几个类 深入理解Apache_Mina_(2)----_与IoFilter相关的几个类 深入理解Apache_Mina_(3)----_与IoHandler相关的几个类 深入理解Apache_Mina_(4)----_IoFilter和IoHandler的区别和...
Apache MINA(Multipurpose Infrastructure for Network Applications)是一个高度可扩展且高性能的网络应用程序框架,主要用于简化网络编程,尤其是TCP/IP和UDP/IP协议的应用。MINA的设计目标是为开发者提供一个...
MINA(Multipurpose Infrastructure for Network Applications)框架是Apache软件基金会的一个开源项目,它提供了一种高级的、事件驱动的网络应用程序框架,用于简化基于Java的网络编程,特别是使用非阻塞I/O(Non-...
在本教程中,我们将深入探讨如何整合Spring Boot与Mina框架,同时介绍Java NIO(非阻塞I/O)的基础知识。Spring Boot以其简洁、快速的起步方式深受开发者喜爱,而Mina则是一个强大的网络通信框架,常用于构建高性能...
Apache Mina之所以能够成为一个广泛使用的框架,很大程度上是因为它解决了开发者在处理大量网络连接时所面临的问题,并提供了一种易于理解、易于扩展的编程模型。通过理解这一区别,开发者可以更加明白Mina框架在...