如何在Netty的ssl握手之前优雅地关闭一个频道?

时间:2017-09-26 21:15:09

标签: java ssl netty

我在我的应用程序中添加了一个限制功能,需要在SSL握手之前关闭一个通道,以便在传入请求速率超过阈值时减少CPU使用率。现在我使用服务器模式的Netty SslHandler来进行握手。我目前的实施是在ChannelInboundHandlerAdapter之前添加SslHandler并重写channelActive方法:

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { 
    if (!limiter.tryAcquire()) {
        ctx.close();
        return;
    }

    ctx.pipeline().remove(this);
    ctx.fireChannelActive();
}

通过这种方式,通道可以在激活时关闭。但是,我会在握手失败时收到SslHandshakeCompletionEvent。我阅读了Netty SslHandler的源代码。触发channelInactive事件时,它将在channelInactive方法中设置握手失败。所以我想知道是否有更好的方法来关闭通道而不触发握手失败事件,因为当我的限制关闭通道时,握手过程还没有开始。

2 个答案:

答案 0 :(得分:0)

你在错误的一端攻击这个问题。我们的想法不是关闭那些被过快接受的频道,而是不要太快接受它们,这将在接受处理程序而不是频道处理程序中完成。

答案 1 :(得分:0)

您的方法几乎是正确的,但是,覆盖channelRegistered方法而不是channelActive是正确的。

@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
    if (isGlobalLimitReached()) {
        ctx.close();
    } else {
        ctx.pipeline().remove(this);
        ctx.pipeline().addFirst(sslCtx.newHandler(ctx.alloc()));
        ctx.fireChannelRegistered();
    } 
}

此外,您需要动态地在管道的开头添加SslHandler,并且仅在满足您的条件时才会添加(无限制)。

在这种情况下,您将无法获得SslHandshakeCompletionEvent。在将SslHandler添加到管道时启动握手 channel.isActive()返回true(您在上面的代码中的情况)。

channelRegistered是您最近可以拒绝/关闭连接的地方。

相关问题