Netty,如何实现HTTP连接限制器,它在关闭通道之前发送响应(503)

时间:2012-07-03 17:38:22

标签: java netty

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

    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监听器处理它关闭它,这样当写完成时它就关闭了。然而,发生了什么事情,我得到了很多关于&#34;已发送回复的例外情况,无法发送超过1&#34;然后堆栈溢出。

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");
    }
}

我能看到的任何想法或例子?感谢

编辑:stacktrace

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)

1 个答案:

答案 0 :(得分:3)

我认为它不会发送多个回复。我认为它是[尝试]发送一个,这比请求数量多一个,因为事件是由连接通道事件触发的,而管道还没有看到任何http请求。

我会将您的代码更改为而不是在连接时执行此操作,而是在第一个请求时触发503响应。如果该频道随后被关闭,adios客户端,但如果客户端的第一个请求低于阈值,则从管道中删除保镖(假设一旦客户端进入,他们就处于良好状态)。

有意义吗?