Netty параллелизм и «Сброс соединения по пиру» - PullRequest
3 голосов
/ 25 октября 2011

Я построил следующий простой сервер и тестирую его с использованием ab. Если я запускаю ab, делая 3000 запросов (300 одновременно), это работает. Если я запускаю его снова, он показывает мне:

apr_socket_connect(): Connection reset by peer (54) 

И если после этой ошибки я пытаюсь сделать один запрос с помощью curl без перезапуска сервера, он работает. Если я запускаю снова ab, это показывает ту же ошибку. Кажется, что он не может обрабатывать слишком много одновременных соединений. Ниже код:

public static void main(String[] args) throws Exception {

        ServerBootstrap bootstrap = new ServerBootstrap(
                new NioServerSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(new StringEncoder(), new MyServerHandler());
            }
        });

        bootstrap.bind(new InetSocketAddress(9090));
        System.out.println("Running");
}

Вот обработчик:

public class MyServerHandler extends SimpleChannelUpstreamHandler {

    private static AtomicLong request = new AtomicLong();

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
            throws Exception {  
        ChannelFuture channelFuture = e.getChannel().write("This is request #" + request.incrementAndGet() + "\n");
        channelFuture.addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
            throws Exception {
        System.out.println(e.getCause());
        e.getChannel().close();
    }

}

Как вы видите, это очень просто, просто показывает общее количество обработанных запросов. Любые советы?

Спасибо

Ответы [ 2 ]

1 голос
/ 05 ноября 2011

Я не вижу сразу ничего плохого, но вы можете попробовать следующее, чтобы получить больше информации:

  1. Переопределите channelClosed и выведите что-нибудь, чтобы вы были на 100% уверены, что Netty хотя бы пытается закрыть канал.
  2. Используйте jvisualvm, чтобы взглянуть на JVM, на которой работает ваш сервер; вы должны видеть потоки и узнать, активны они или нет.
  3. Напишите что-нибудь на System.out на стороне сервера на channelConnected, чтобы вы знали, что ваши соединения сделали это далеко (особенно для 2-го запуска).
  4. Когда вы запускаете ab во второй раз, возникает ли ошибка при каждой попытке подключения или только для некоторых?

Что я нахожу странным, так это то, что это работает с первого раза, но не после. Имейте в виду, что это может быть не проблема Netty или даже JVM, а скорее ОС, ограничивающая попытки подключения.

Я провел несколько тестов на своем собственном тестовом сервере Netty и обнаружил, что запуск одновременных соединений с большими партиями приведет к непредсказуемому результату (большинство подключится, некоторые потерпит неудачу, но всегда с другим соотношением). Пока что я не понимаю, почему это так (пока), но я подозреваю, что моя ОС отказывает в соединениях, а не в Netty.

1 голос
/ 25 октября 2011

«Сброс соединения по пиру» обычно означает, что вы записали соединение, которое уже было закрыто другим концом.Другими словами, ошибка протокола приложения.Сама ошибка появляется при последующем чтении или записи.

...