我在我的应用程序中添加了一个限制功能,需要在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
方法中设置握手失败。所以我想知道是否有更好的方法来关闭通道而不触发握手失败事件,因为当我的限制关闭通道时,握手过程还没有开始。
答案 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
是您最近可以拒绝/关闭连接的地方。