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 服务器的连接(我需要设置啥)?