1

目前在我的管道中,我有一个简单的处理程序来在我的服务器过载时拒绝连接:

    public class RequestFilter extends SimpleChannelHandler {

    @Override
    public void channelConnected(final ChannelHandlerContext ctx, final ChannelStateEvent e) throws Exception {
            requestLimiter(ctx, e);
            super.channelConnected(ctx, e);
    }
}

private void requestLimiter(final ChannelHandlerContext ctx, final ChannelStateEvent e) {
            if(threshold < counter) {
             ctx.getChannel().close();
            }
    }

当计数器超过阈值时,通道关闭,一切似乎都正常。

现在我想通过在关闭通道之前先发送一个 HTTP 503 响应来增强这一点。到目前为止,我尝试的是下面的这种方法,而不是立即关闭通道,我尝试编写对通道的响应,然后使用 channelfuture 侦听器处理关闭它,以便在写入完成时关闭它。然而发生的事情是我收到大量关于“已经发送响应,不能发送超过 1 个”的异常,然后是堆栈溢出。

protected void sendResponse(Channel channel, HttpResponse response) {
    if (channel.isConnected()) {
        channel.write(response).addListener(ChannelFutureListener.CLOSE);
        log.trace("response sent");
    } else if (!channel.isConnected()) {
        log.trace("attempted to send response, but the channel was closed");
    } else {
        log.trace("Not sure why this would happen");
    }
}

我可以看看任何想法或例子吗?谢谢

编辑:堆栈跟踪

java.lang.IllegalStateException: cannot send more responses than requests
    at org.jboss.netty.handler.codec.http.HttpContentEncoder.writeRequested(HttpContentEncoder.java:104)
    at org.jboss.netty.handler.timeout.WriteTimeoutHandler.writeRequested(WriteTimeoutHandler.java:152)
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:262)
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.handleDownstream(ChunkedWriteHandler.java:119)
    at org.jboss.netty.handler.execution.ExecutionHandler.handleDownstream(ExecutionHandler.java:165)
    at org.jboss.netty.channel.Channels.write(Channels.java:605)
    at org.jboss.netty.channel.Channels.write(Channels.java:572)
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245)
    at com.test.RequestFilter.sendResponse(RequestFilter.java:98)
4

1 回答 1

3

我认为它不会发送多个响应。我认为它正在 [尝试] 发送一个,这比请求数量多一,请求数量为零,因为该事件是由连接通道事件触发的,并且管道尚未看到任何 http 请求。

我会将您的代码更改为不在连接时执行此操作,而是在第一个请求时触发 503 响应。如果通道随后关闭,adios 客户端,但如果客户端的第一个请求潜入阈值以下,则从管道中删除保镖(假设一旦客户端进入,它们就永远存在)。

有道理 ?

于 2012-07-03T18:49:28.970 回答