【问题标题】:worker thread being blocked in Netty工作线程在 Netty 中被阻塞
【发布时间】:2016-01-03 04:16:36
【问题描述】:

我知道 netty 使用 Reactor 模式避免为每个连接创建一个线程, 这种模式的核心概念是 Linux 中的“选择器”或epoll 系统调用。

但我也听说如果处理程序从不关闭它的通道,它将占用一个工作线程并阻塞它:这是否意味着每个连接都将使用(阻塞)一个线程,所以 对于每个接受的套接字我们还需要创建一个线程吗?

例如,如果我写一个有 10,000 个持久连接的服务器,这个服务器是否需要 10,000 个工作线程??

上面这两件事之间的矛盾让我很困惑,如果我理解错了,谁能解释我?谢谢~

=========================================

一个例子(只有 1 个工作线程),它总是可以同时处理一个客户端的事件。

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
public class Netty_test {
    public static void main(String[] args) {
        ChannelFactory factory =new     NioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newFixedThreadPool(1));
    ServerBootstrap bootstrap = new ServerBootstrap(factory);
        ChannelPipelineFactory cpf=new ChannelPipelineFactory(){
            public ChannelPipeline getPipeline() {
                return Channels.pipeline(new testHandler());
            }
        };
        bootstrap.setPipelineFactory(cpf);
        bootstrap.setOption("child.tcpNoDelay", true);      
        bootstrap.bind(new InetSocketAddress(100));
    }
}
class testHandler extends SimpleChannelHandler {
@Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {    
        System.out.println("messageReceived, handler work.");
        e.getChannel().write(e.getMessage());
        ctx.sendUpstream(e);
    }
}

【问题讨论】:

    标签: java netty


    【解决方案1】:

    不,您的 10,000 个连接将共享工作线程。一个工作线程将处理多个连接/通道。这就是为什么不阻塞工作线程非常重要的原因。

    【讨论】:

    • 但是在我上面的例子中,服务器只能处理一个持久连接。
    • 我已经在 Win7 和 Linux(CentOS 5) 中使用 netty-3.2.4.Final.jar 尝试过这个例子。
    • 你的工人比线程多。将您的工厂更改为只有 1 个工人,您将看到它可以处理多个连接。
    • 像这样:NioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newFixedThreadPool(1), 1);
    【解决方案2】:

    1) 在反应器模式中,调度程序通过侦听一系列事件队列并将事件传递给具体的事件处理程序来获取一个事件。事件处理程序可以仅由一个线程、线程池或每个线程的每个事件执行。取决于您的实施。

    2) 您可以为每个通道添加超时计时器,并在传入数据时重置此计时器。如果定时器超时,则关闭该通道,防止空闲通道过多。

    我的 0.2 美分?

    【讨论】:

    • 那么我的服务器如何通过一个线程同时服务两个连接?除非我关闭其中一个频道,否则它似乎不起作用。
    • Netty 框架应该支持非阻塞 IO 模式,通过线程池同时服务多个连接。这是描述此功能的链接slideshare.net/zaubersoftware/non-blocking-io-with-netty
    猜你喜欢
    • 2012-01-25
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2018-12-20
    • 2015-09-25
    相关资源
    最近更新 更多