这几天在解决一个用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(); //不关闭的话会运行一段时间后抛出,too many open files异常,导致无法连接
throw new Exception();
}
}
分享到:
相关推荐
Apache Mina是一个流行的Java框架,专门用于简化和优化网络应用开发,它支持多种协议如TCP/IP、UDP/IP等,并提供了长连接和短连接的支持。在这个实例中,我们将探讨如何使用Mina实现长连接和短连接。 首先,理解长...
Apache MINA是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。 当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版...
它基于Java NIO(非阻塞I/O)构建,允许在高并发场景下高效地处理连接和数据传输。Mina支持多种网络协议,如TCP/IP、UDP/IP以及HTTP、FTP等,因此常被用于构建网络服务,如代理服务器、聊天应用、数据库中间件等。 ...
基于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包缺失
它利用Java NIO库,实现了异步、非阻塞的通信模式,可以在单一线程中处理多个并发连接,大大提升了服务器的并发能力。Minaclient和MinaHost工程正是展示了如何在实际项目中应用这些概念。 在Minaclient工程中,我们...
mina-filter-compression-2.0.7.jar,mina 过滤器jar包,核心包之一
总的来说,Mina与Socket结合使用,可以构建出高效、灵活的网络通信解决方案。Mina的高级抽象简化了网络编程的复杂性,而Socket则提供了基础的网络通信能力。理解这两者的原理和用法,对于提升Java网络编程技能至关...
Apache MINA(Multipurpose Infrastructure for Network Applications)是一个高性能、异步事件驱动的网络应用程序框架,主要用于简化开发服务器端和客户端的网络应用。标题"apache-mina-2.0.16"表明我们讨论的是...
Mina(Java Multithreaded Network Application Framework)是一个用Java编写的网络应用框架,它提供了高度可扩展性和性能,适用于多种网络协议,包括TCP和UDP。Mina为开发者提供了一种抽象层,简化了网络编程的复杂...
远古: 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(Multipurpose Infrastructure for Network Applications)是一个Java框架,专门设计用于构建高性能、高可用性的网络应用程序,尤其适合TCP和UDP协议的长连接应用。它提供了异步I/O模型,可以处理大量的并发...
org.apache.mina.core.buffer.IoBuffer mina core 包
mina-core-2.0.0-M1.jar是Apache Mina项目的核心库,它是一个高度可扩展的网络通信框架,主要用于构建高性能、高效率的服务端和客户端应用程序。Mina提供了一种统一的API,可以处理多种传输协议,如TCP/IP、UDP/IP...
Apache MINA是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。这个“apache-mina-2.1.3-bin.tar.zip”文件包含了Apache MINA的最新版本2.1.3,适用于Java开发者,便于...
3. 高性能、高扩展性:MINA框架可以帮助开发者快速开发高性能、高扩展性的网络通信应用。 MINA框架的组成部分: 1. IoAcceptor:负责接受来自客户的请求。 2. IoProcessor:负责处理客户请求,定时检查客户是否有...
它提供了JAVA对象的序列化和虚拟机内部通信的功能,使得开发者能够迅速构建高性能、高可扩展性的网络应用。Mina的核心特性是其事件驱动、异步(基于Java NIO)的编程模型,使得处理网络通信变得更加高效。 Mina分为...
然而,频繁的短连接可能会增加握手和释放连接的开销,特别是在高并发场景下。 2. **TCP长连接**:在长连接中,一旦建立连接,就可以进行多次数据传输,直到连接的任意一方主动断开连接。这种模式适用于需要保持连续...
MINA(Multipurpose Infrastructure for Network Applications)是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。MINA由Apache软件基金会开发,并且是其顶级项目之一...
Apache Mina是一个开源的网络通信框架,常用于构建高性能、高效率的服务端应用程序,尤其在Java平台上。在本文中,我们将深入探讨Mina的核心概念,包括连接管理、心跳机制以及断线重连策略。 首先,让我们理解"Mina...