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

时间:2011-10-25 21:12:59

标签: java asynchronous network-programming nio netty

我打算在即将开展的项目中使用Netty。该项目将充当客户端和服务器。特别是它将建立和维护与各种服务器的许多连接,同时为其自己的客户提供服务。

现在,NioServerSocketChannelFactory的文档公平地指定了服务器端的线程模型 - 每个绑定的监听端口在整个过程中都需要一个专用的 boss 线程,同时连接客户端将在 worker 线程上以非阻塞方式处理。具体来说,一个工作线程将能够处理多个连接的客户端。

但是,NioClientSocketChannelFactory的文档不太具体。这似乎也同时利用 boss worker 线程。但是,文档说明:

  

一个NioClientSocketChannelFactory有一个boss线程。它根据请求进行连接尝试。一旦连接尝试成功,boss线程就会将连接的Channel传递给NioClientSocketChannelFactory管理的其中一个工作线程。

工作线程似乎也以与服务器案例相同的方式运行。

我的问题是,这是否意味着从我的程序到外部服务器的每个连接都会有一个专用的 boss 线程?如果我建立数百或数千个此类连接,这将如何扩展?

作为旁注。重复使用单个Executor(缓存线程池)作为ChannelFactory的 bossExecutor workerExecutor 是否有任何不良副作用?那么在不同的客户端和/或服务器ChannelFactory实例之间重新使用呢? This is somewhat discussed here,但我没有找到足够具体的答案。任何人都可以详细说明这个吗?

3 个答案:

答案 0 :(得分:13)

这不是关于Netty客户端线程模型如何工作的问题的真实答案。但是,您可以使用相同的NioClientSocketChannelFactory来创建包含多个ClientBootstrap的单个ChannelPipelineFactory,从而创建大量连接。看一下下面的例子。

public static void main(String[] args)
{
    String host = "localhost";
    int port = 8090;
    ChannelFactory factory = new NioClientSocketChannelFactory(Executors
            .newCachedThreadPool(), Executors.newCachedThreadPool());
    MyHandler handler1 = new MyHandler();
    PipelineFactory factory1 = new PipelineFactory(handler1);
    AnotherHandler handler2 = new AnotherHandler();
    PipelineFactory factory2 = new PipelineFactory(handler2);
    ClientBootstrap bootstrap = new ClientBootstrap(factory);
    // At client side option is tcpNoDelay and at server child.tcpNoDelay
    bootstrap.setOption("tcpNoDelay", true);
    bootstrap.setOption("keepAlive", true);
    for (int i = 1; i<=50;i++){
        if(i%2==0){
            bootstrap.setPipelineFactory(factory1);
        }else{
            bootstrap.setPipelineFactory(factory2);
        }

        ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,
                port));

        future.addListener(new ChannelFutureListener()
        {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception
            {
                future.getChannel().write("SUCCESS");
            }
        });
    }
}

它还显示了如何为不同的连接设置不同的管道工厂,因此根据您建立的连接,您可以在通道管道中调整编码器/解码器。

答案 1 :(得分:1)

我不确定你的问题是否得到了解答。这是我的答案:有一个Boss线程同时管理您应用中的所有待处理的CONNECT。它使用nio处理单个(Boss)线程中的所有当前连接,然后将每个成功连接的通道交给其中一个工作人员。

答案 2 :(得分:0)

您的问题主要与性能有关。单线程在客户端上可以很好地扩展。

哦,唠叨已经关闭了。您仍然可以在那里浏览存档。