Netty客户端连接问题

Posted Netty之家

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty客户端连接问题相关的知识,希望对你有一定的参考价值。

问题

Netty客户端想同时连接多个服务端,使用如下方式,是否可行,我简单测试了下,暂时没有发现问题。代码如下


EventLoopGroup group = new NioEventLoopGroup();

try {

Bootstrap b = new Bootstrap();

b.group(group)

......代码省略

// Start the client.

ChannelFuture f1 = b.connect(HOST, PORT);

ChannelFuture f2 = b.connect(HOST2, PORT2);


// Wait until the connection is closed.

f1.channel().closeFuture().sync();

f2.channel().closeFuture().sync();

......代码省略

}


解答

上述代码没有问题,原因是尽管Bootstrap自身不是线程安全的,但是执行Bootstrap的连接操作是串行执行的,而且connect(String inetHost, int inetPort)方法本身是线程安全的,它会创建一个新的NiosocketChannel,并从初始构造的EventLoopGroup中选择一个NioEventLoop线程执行真正的Channel连接操作,与执行Bootstrap的线程无关,所以通过一个Bootstrap连续发起多个连接操作是安全的,它的原理如下:



注意事项-资源释放问题

在同一个Bootstrap中连续创建多个客户端连接,需要注意的是EventLoopGroup是共享的,也就是说这些连接共用一个NIO线程组EventLoopGroup,当某个链路发生异常或者关闭时,只需要关闭并释放Channel本身即可,不能同时销毁Channel所使用的NioEventLoop和所在的线程组EventLoopGroup,例如下面的代码片段就是错误的


ChannelFuture f1 = b.connect(HOST, PORT);

ChannelFuture f2 = b.connect(HOST2, PORT2);

f1.channel().closeFuture().sync();

} finally {

group.shutdownGracefully();

}


注意事项-线程安全问题

需要指出的是Bootstrap不是线程安全的,因此在多个线程中并发操作同一个Bootstrap实例是一件非常危险的事情,Bootstrap是I/O操作工具类,它自身的逻辑处理非常简单,真正的I/O操作都是由EventLoop线程负责的,所以通常多线程操作同一个Bootstrap实例也是没有意义的,而且容易出错,错误代码如下:


Bootstrap b = new Bootstrap();

{

//多线程执行初始化、连接等操作

}



以上是关于Netty客户端连接问题的主要内容,如果未能解决你的问题,请参考以下文章

Netty 客户端无法连接

阻止客户端关闭与 netty 服务器的连接(我需要设置啥)?

Netty 线程模型在客户端连接多的情况下如何工作?

netty中一个客户端可以连接(监听)多个服务端并且可以正常发送给不同服务端数据以及接受服务端的数据?

长连接开发踩坑之netty OOM问题排查实践

Netty源码分析-Bootstrap客户端连接过程