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 リスナーでチャネルを閉じる処理を試み、書き込みが完了するとチャネルが閉じられるようにします。しかし、何が起こっているのかというと、「すでに応答を送信しています。複数を送信することはできません」という例外が大量に発生し、その後にスタック オーバーフローが発生します。

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 要求を確認していないため、0 である要求数よりも 1 多い 1 つを送信しようとしていると思います。

接続時にこれを行わないようにコードを変更しますが、最初のリクエストで 503 レスポンスをトリガーします。チャネルが閉じられた場合、クライアントは adios になりますが、クライアントの最初のリクエストがしきい値を下回った場合は、バウンサーをパイプラインから削除します (クライアントがいったん入ったら、彼らは永久に入っていると仮定します)。

わかる ?

于 2012-07-03T18:49:28.970 に答える