多个工作程序事件循环组

时间:2017-06-25 22:08:50

标签: netty

我正在尝试使用netty 4.1.x编写一个TCP服务器,该服务器预计将托管数千个持久连接(TLS)。在性能测试期间,我们观察到如果有几千个连接到服务器,然后我们得到另外几千个连接的突发,这些新的SSL握手使工作线程长时间忙,这导致现有的连接开始计时。 在互联网上提供的所有Netty示例中,我看到服务器都是这样引导的:

 EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap(); // (2)
        b.group(bossGroup, workerGroup) ...

我想知道我是否可以使用两个工作组而不是一个工作组。所以,我打算做的是让workerGroup(如上所示)处理初始握手,一旦完成,我从该组注销Channel并将其注册到辅助组(参见下面的示例代码)。 p>

class SwitchToSecondaryGroupHandler extends ChannelInboundHandlerAdapter {

private final EventLoopGroup secondaryEventLoopGroup;

public SwitchToSecondaryGroupHandler(EventLoopGroup eventLoopGroup) {
    this.secondaryEventLoopGroup = eventLoopGroup;
}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    ctx.pipeline().remove(this);
    ChannelFuture future = ctx.channel().deregister();
    future.addListener((f) -> {
        if (f.isSuccess()) {
            ChannelFuture registerFuture = secondaryEventLoopGroup.register(ctx.channel());
            registerFuture.addListener((e) -> {
                ctx.fireChannelRead(msg);
            });

        }
    });
}

}

此处理程序将在SslHandler之后立即添加。它可能不必在通道读取之后,它也可以在写入之前完成。 这样,辅助组可以继续为现有连接提供服务,并且任何新连接的爆发都不会影响它们。在我使用带有StringEncoder / Decoder的独立程序的测试中,它似乎有用。

这种方法是否存在潜在问题?问题我的意思是,对于netty本身的运作。

1 个答案:

答案 0 :(得分:1)

从理论上讲,这是有效的,但重新注册频道是一种" hacky"业务也可能导致我们在某种程度上不再支持netty的情况。这里的问题在于,当通道从一个线程移动到另一个线程时,确保事物的可见性和执行的正确性。

我很想看到你在这里描述的问题的探查器快照,因为这显然不是我所期望的。你能否打开包含所有信息的网络问题,并在那里附上探查器快照。谢谢!