这几天在解决一个用mina开发的高并发通信过程中产生的一个bug。
模拟场景为:
通过定时触发启动线程模拟高并发短连接测试,测试的服务端有2个,一个是服务有起,一个没起,客户端和服务端均在同一服务器上。执行一段时间后linux主机上通过lsof命令查看,发现有递增的文件句柄,pipe和eventpoll。
抛出的异常如下:
-
2012
-
10
-
13
10
:
09
:
48
-org.apache.mina.core.service.SimpleIoProcessorPool.<init>(SimpleIoProcessorPool.java:
197
)
-
Failed to create a new
instance of org.apache.mina.transport.socket.nio.NioProcessor:
null
-
java.lang.reflect.InvocationTargetException
-
at sun.reflect.GeneratedConstructorAccessor110.newInstance(Unknown Source)
-
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27
)
-
at java.lang.reflect.Constructor.newInstance(Constructor.java:513
)
-
at org.apache.mina.core.service.SimpleIoProcessorPool.<init>(SimpleIoProcessorPool.java:180
)
-
at org.apache.mina.core.service.SimpleIoProcessorPool.<init>(SimpleIoProcessorPool.java:112
)
-
at org.apache.mina.core.polling.AbstractPollingIoConnector.<init>(AbstractPollingIoConnector.java:93
)
-
at org.apache.mina.transport.socket.nio.NioSocketConnector.<init>(NioSocketConnector.java:56
)
-
at com.develop.webplatform.funnel.client.JobClient.sendMessage(JobClient.java:39
)
-
at com.develop.webplatform.funnel.client.JobClient.sendJob(JobClient.java:126
)
-
at com.develop.webplatform.funnel.extend.JobExecRemotelyBySocket.execJobByTask(JobExecRemotelyBySocket.java:66
)
-
at com.develop.webplatform.funnel.JobManager.execJobByTask(JobManager.java:27
)
-
at com.develop.webplatform.quartz.job.TaskJob.executeInternal(TaskJob.java:38
)
-
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86
)
-
at org.quartz.core.JobRunShell.run(JobRunShell.java:223
)
-
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549
)
-
Caused by: org.apache.mina.core.RuntimeIoException: Failed to open a selector.
-
at org.apache.mina.transport.socket.nio.NioProcessor.<init>(NioProcessor.java:61
)
-
... 15
more
-
Caused by: java.io.IOException: Too many open files
-
at sun.nio.ch.IOUtil.initPipe(Native Method)
-
at sun.nio.ch.EPollSelectorImpl.<init>(EPollSelectorImpl.java:49
)
-
at sun.nio.ch.EPollSelectorProvider.openSelector(EPollSelectorProvider.java:18
)
-
at java.nio.channels.Selector.open(Selector.java:209
)
-
at org.apache.mina.transport.socket.nio.NioProcessor.<init>(NioProcessor.java:59
)
-
... 15
more
原代码中,关于客户端连接的代码如下:
-
final
NioSocketConnector connector =
new
NioSocketConnector();
-
final
String[] result =
new
String[
1
];
-
connector.getFilterChain().addLast("codec"
,
-
new
ProtocolCodecFilter(
new
ObjectSerializationCodecFactory()));
-
connector.setHandler(handler);
-
-
-
connector.setConnectTimeoutMillis(defaultConnectTimeOut);
-
ConnectFuture connectFuture = connector.connect(address);
-
connectFuture.awaitUninterruptibly();
-
if
(connectFuture.isDone()) {
-
if
(!connectFuture.isConnected()) {
-
logger.info("fail to connect "
+ logInfo);
-
-
throw
new
Exception();
-
}
-
}
经过分析,导致主机文件句柄泄露的原因为,客户端发起服务端连接时,会请求系统分配相关的文件句柄,在原代码中,仅仅判断是否连接成功,而未对连接失败进
行资源释放,从而造成文件句柄泄露。当总的文件句柄数超过系统设置值(ulimit -n
查看同一个进程允许的最大文件句柄数),则抛出异常“java.io.IOException: Too many open
files",导致无法创建新的连接,服务器挂掉。
更改后的代码如下:
-
final
NioSocketConnector connector =
new
NioSocketConnector();
-
final
String[] result =
new
String[
1
];
-
connector.getFilterChain().addLast("codec"
,
-
new
ProtocolCodecFilter(
new
ObjectSerializationCodecFactory()));
-
connector.setHandler(handler);
-
-
-
connector.setConnectTimeoutMillis(defaultConnectTimeOut);
-
ConnectFuture connectFuture = connector.connect(address);
-
connectFuture.awaitUninterruptibly();
-
if
(connectFuture.isDone()) {
-
if
(!connectFuture.isConnected()) {
-
logger.info("fail to connect "
+ logInfo);
-
connector.dispose();
-
-
throw
new
Exception();
-
}
-
}
分享到:
相关推荐
Apache MINA是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。 当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版...
基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发...
hive 开发UDF 使用maven工程 引发jar包缺失 hive 开发UDF 使用maven工程 引发jar包缺失
mina-filter-compression-2.0.7.jar,mina 过滤器jar包,核心包之一
org.apache.mina.core.buffer.IoBuffer mina core 包
远古: java.net + io java.net + iojava.net + java.iojava.net + java.iojava.net + java.iojava.net + java.iojava.net + java.io java.net + io java.net + io java.net + iojava.net + java.iojava.net + java....
MINA入门实例,实现长连接,短连接通讯。
Mina长连接短连接实例包含Minaclient工程和MinaHost工程,另外还有几个文档,相信对理解这两个工程有很大的帮助
mina-andrawis.github.io:个人网站
mina-core-2.0.0-M1.jar/mina-example-1.0.5.jar/slf4j-jdk14-1.6.1.jar/slf4j-log4j12-1.6.1.jar mina 所用jar
db.jdbc:jdbc连接池 game:开始游戏 game.message:消息管理者,将客户端的消息传到具体的处理器处理 game.message.handler:消息处理者(功能实现的地方,上接service,下连DAO) net.mina.protocol:自定义通信...
mina-core-2.0.0-M6.jar
mina-transport-apr-2.0.2.jar
apache-mina-2.0.16.zip
mina-core-2.0.0-M6.jar mina-example-2.0.0-M6.jar mina-filter-codec-netty-2.0.0-M6.jar mina-filter-compression-2.0.0-M6.jar mina-integration-beans-2.0.0-M6.jar mina-integration-jmx-2.0.0-M6.jar mina-...
高性能Java网络框架 MINA.7z
mina-core-2.0.0-M1.jar包和slf4j相关jar包
基于Java的mina高性能Java网络框架.zip
mina高性能Java网络框架.zip
基于Apache Mina实现的TCP长连接和短连接实例 详细说明,可参见blog http://blog.csdn.net/peterwanghao/article/details/6900523