Инструмент для расчета напряжений и соединений

Я создаю простой и быстрый инструмент стресс-тестирования для веб-приложения. Требования: наибольшее количество исходящих http-запросов (скажем, простых запросов) от одного узла.

Ранее мы использовали netty, и я выбрал его для написания этого простого теста. Это действительно просто, и я закончил только с 4 маленькими классами, расширяющими netty api ( код здесь), и он дает около 30K rps на машине localhost dev (linux).

Основным ограничением является лимит исходящих соединений (лимит открытого файла / сокета в linux), он составляет около 30-40 КБ на моей машине. Ты получаешь 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();
    }

Он начал работать. Единственная проблема - это немного несправедливо, потому что вы можете увеличить счетчик, но не можете подключиться или уменьшить и не смогли отключиться после него.

Итак, почему счетчик не работает в правильной версии?

ОБНОВЛЕНИЕ: попробовал как предложено, вкл / дек в 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

SADF

2 ответа

Вам не нужно увеличивать количество отправленных сообщений в ChannelFutureListener, который добавляется в ChannelFuture, который был возвращен из операции write(...). В противном случае вы увеличите его, даже если запись ожидает.

Теория.

В исходной версии вы уменьшаете счетчик подключений для всех попыток подключения, в случае неудачных. Если вы увеличите счетчик в channelConnected() и добавите понижающий прослушиватель в ChannelCloseFuture и этот момент, я думаю, вы получите лучший результат.

Это потому что

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

всегда будет вызывать operationComplete, даже если канал никогда не был подключен.

ОБНОВИТЬ:

Чтобы убедиться, что учитываются только подключенные каналы. В обратном вызове channelConnected() в STressClientHandler:

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

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
             connected.decrementAndGet();
        }
    });
Другие вопросы по тегам