标签:start nbsp err 解决 tcp连接 ddl 业务 min tmp
1、NIO超级陷阱
之所以说NIO超级陷阱,就是因为我在本系列开头的那句话,因为使用缺陷导致客户业务系统瘫痪。当然,我对这个问题进行了很深的追踪,包括对MINA源码的深入了解,但其实之所以会出现这个问题,它的根不是MINA的原因,而是JDK底层的问题。
JDK底层在实现nio时,为了能够唤醒等待在io上的线程,在windows平台使用了两个端口建立连接发消息实现。看如下代码:
- public class NIOTest {
-
- @Test
- public void test1(){
-
- final int MAXSIZE=1000;
- Selector [] sels = new Selector[ MAXSIZE];
- try{
- for( int i = 0 ;i< MAXSIZE ;++i ) {
- sels[i] = Selector.open();
- Thread.sleep(1000*10);
- }
- }catch( Exception ex ){
- ex.printStackTrace();
- }
- }
- }
也就是说每调用一次Selector.open(),就会占用两个随机可用端口,相互通信--这就是问题的根源。
当然对于我们的项目来说,这个问题的解决需要分两步,首先限制端口数到用户可接受范围内,这个比较容易,我们可用只调用一次Selector.open()方法即可,使用单利模式;第二步,因为Selector.open()方法每次都是使用的系统当前可用的随机端口,所以就有可能导致占用客户业务端口的情况,因此我们必须把Selector.open()所开的端口限制在一定范围内,最好可以通过代码指定使用哪几个端口,但是直到现在我们都没有找到,如果亲们有方法的话,很感谢能够告诉我....,。
Selector总结如下:
Windows下,Selector.open()会自己和自己建立两条TCP链接。不但消耗了两个TCP连接和端口,同时也消耗了文件描述符。
Linux下,Selector.open()会自己和自己建两条管道。同样消耗了两个系统的文件描述符。
来源于:http://blog.csdn.net/haoel/article/details/2224055
所以,现在我们现在就干脆用传统IO与MINA server通信吧。
2、使用同步IO与MINA通信
其实非常简单,唯一的难点就在于使用同步IO与MINA通信时,怎么编码和解码,还是看下面代码吧。
server 端(用的MINA)
- public void startServer() {
- logger.debug("mina server start");
- int port = SysEvnVar.managerPort;
- logger.debug("manager端口号:" + port);
- IoAcceptor acceptor = new NioSocketAcceptor();
-
- acceptor.getFilterChain().addLast("logger", new LoggingFilter());
-
- ObjectSerializationCodecFactory objsCodec=new ObjectSerializationCodecFactory();
- objsCodec.setDecoderMaxObjectSize(DEFAULTDECODER);
- objsCodec.setEncoderMaxObjectSize(DEFAULTDECODER);
-
- acceptor.getFilterChain().addLast(
- "codec",
- new ProtocolCodecFilter(objsCodec));
-
- acceptor.setHandler(serverHandler);
-
- acceptor.getSessionConfig().setReadBufferSize(DEFAULTBUFFERSIZE);
-
- acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, DEFAULTIDLETIME);
-
- try {
-
- acceptor.bind(new InetSocketAddress(port));
- logger.info("mina server bind port ("+port+") sucess");
- } catch (IOException e) {
- logger.error("mina server bind port ("+port+") fail:" + e.getMessage(),e);
- }
- }
client端(使用同步IO)
看代码里面的注释,怎么编码和解码,其实我是直接看MINA源码,把MINA的编码和解码方法工具类直接拷到了我们的client端,这样就轻松的实现使用同步IO和MINA进行通信。
NIO框架之MINA源码解析(五):NIO超级陷阱和使用同步IO与MINA通信
标签:start nbsp err 解决 tcp连接 ddl 业务 min tmp
原文地址:http://www.cnblogs.com/duanxz/p/6754612.html