1

Web アプリケーション用のシンプルで最速のストレス テスト ツールを構築しています。要件: 単一ノードからの最大数の HTTP 要求 (たとえば、単純な取得)。

以前は netty を使用していましたが、この単純なテストを作成するためにそれを選択しました。これは非常にシンプルで、netty api (コードはこちら) を拡張する 4 つの小さなクラスのみで終了し、ローカルホストの開発マシン (Linux) で約 30K rps を提供します。

主な制限は発信接続の制限 (Linux でのオープン ファイル/ソケット制限) で、私のマシンでは約 30 ~ 40K です。java.net.BindExceptionこの場合は取得します。したがって、制限に達したときのパフォーマンスの低下を防ぐために、手動で発信 netty 接続の数を制限する必要があります

この制限をカウンターで実装し、最初のバージョンでインクリメントSimpleChannelUpstreamHandler.channelConnectedおよびデクリメントしましたfuture.getChannel().getCloseFuture().addListener(コード、その場所のコメントを参照)。

そして、インクリメントを近くに置いた後でのみbootstrap.connect

connected.incrementAndGet();
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));

およびデクリメントSimpleChannelUpstreamHandler.messageReceived:

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        // the same here - decrementing connections here is not fully fair but works!
        connected.decrementAndGet();
        e.getChannel().close();
    }

-それは働き始めました。唯一の問題-カウンターをインクリメントできますが、接続に失敗するか、デクリメントし、その後切断に失敗するため、少し不公平です。

では、正しいバージョンでカウンターが機能しないのはなぜですか?

更新: 提案されたように、inc/dec で試してみましたSimpleChannelUpstreamHandler.channelConnected:

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        // by logic you should count connection here, but in practice - it doesn't work
        connected.incrementAndGet();
        ctx.getChannel().getCloseFuture().addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                connected.decrementAndGet();
            }
        });

        e.getChannel().write(GET);
        sent.incrementAndGet();
    }

機能しませんでした。ここでも、送信された > 接続された場所で予測できない数字が表示されました。例:

client1 stat: connected=    0, sent=    0, ERRORS: timeouts=    0, binds=    0, connects=0
client1 stat: connected=   11, sent= 4990, ERRORS: timeouts=    0, binds=    0, connects=0
client1 stat: connected=    1, sent= 8591, ERRORS: timeouts=    0, binds=    0, connects=0
client1 stat: connected=  459, sent=13064, ERRORS: timeouts=    0, binds=    5, connects=0
client1 stat: connected= 1545, sent= 7234, ERRORS: timeouts=    0, binds=  115, connects=0
client1 stat: connected=    0, sent=10037, ERRORS: timeouts=    0, binds=   80, connects=0

悲しい

4

2 に答える 2

0

write(...) 操作から返された ChannelFuture に追加される ChannelFutureListener で、送信カウントをインクリメントする必要はありません。それ以外の場合は、書き込みが保留中であってもインクリメントします。

于 2013-04-27T17:41:54.273 に答える
0

理論。

元のバージョンでは、失敗したものを含め、すべての接続試行の接続カウンターを減らします。channelConnected ()でカウンターをインクリメントし、ChannelCloseFuture とそのポイントにデクリメント リスナーを追加すると、より良い結果が得られると思います。

それの訳は

boostrap.connect().getChannel().getCloseFuture(...)

チャネルが接続されていない場合でも、常に operationComplete を呼び出します。

アップデート:

接続されたチャネルのみがカウントされるようにします。STressClientHandler の channelConnected() カルバック:

    connected.incrementAndGet();
    ctx.getChannel().getCloseFuture().addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
             connected.decrementAndGet();
        }
    });
于 2013-04-24T08:50:48.150 に答える