LINUX.ORG.RU

Netty и ab не грузят CPU на 100%

 , ,


0

1

Что-то не пойму в чем проблема: есть HTTP-сервер на Netty 3.2.6:

public class HttpServer
{
    private final String name;
	private final int port;
    private Channel channel;
    private InetSocketAddress socketAddress;

    public HttpServer(String name, int port)
    {
        this.name = name;
		this.port = port;
	}

    public void run(int selectorThreadCount, ThreadPoolConfig threadPoolConfig)
        throws BackEndException
	{
        ServerBootstrap bootstrap =
            new ServerBootstrap(new NioServerSocketChannelFactory(
                Executors.newFixedThreadPool(selectorThreadCount),
                new ThreadPoolExecutor(threadPoolConfig.getCorePoolSize(),
                    threadPoolConfig.getMaximumPoolSize(),
                    threadPoolConfig.getKeepAliveTime().to(TimeUnit.SECONDS),
                    TimeUnit.SECONDS, new SynchronousQueue<Runnable>())));
		bootstrap.setOption("child.tcpNoDelay", true);
        bootstrap.setOption("child.keepAlive", true);
        bootstrap.setOption("tcpNoDelay", true);
        bootstrap.setOption("keepAlive", true);
        bootstrap.setOption("receiveBufferSize", 1048576);
        bootstrap.setOption("backlog", 1000);
        bootstrap.setPipelineFactory(new HttpServerPipelineFactory());
        socketAddress = new InetSocketAddress(port);
        channel = bootstrap.bind(socketAddress);        
    }
}

public class HttpServerPipelineFactory implements ChannelPipelineFactory
{
	
    protected final HttpServerHandler handler = new HttpServerHandler();

	@Override
	public ChannelPipeline getPipeline() throws Exception {
		ChannelPipeline pipeline = Channels.pipeline();
		
        pipeline.addLast("decoder", new HttpRequestDecoder());
        pipeline.addLast("endcoder", new HttpResponseEncoder());		
        pipeline.addLast("handler", handler);
		
		return pipeline;
	}

}

public class HttpServerHandler extends SimpleChannelUpstreamHandler
{   
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
    {
        HttpRequest request = (HttpRequest)e.getMessage();
        boolean keepAlive = HttpHeaders.isKeepAlive(request);
        // Build the response object.
        HttpResponse response =
            new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.setContent(ChannelBuffers.copiedBuffer(
            "Hello from ServerHandler!", CharsetUtil.UTF_8));
        response.setHeader(HttpHeaders.Names.CONTENT_TYPE,
            "text/plain; charset=UTF-8");
//        HttpRequest request = (HttpRequest)message;        

        if (keepAlive)
        {
            // Add 'Content-Length' header only for a keep-alive connection.
            response.setHeader(HttpHeaders.Names.CONTENT_LENGTH,
                response.getContent().readableBytes());
            // Add keep alive header as per:
            // - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection
            response.setHeader(HttpHeaders.Names.CONNECTION,
                HttpHeaders.Values.KEEP_ALIVE);
        }

        ChannelFuture future = e.getChannel().write(response);

        if (!keepAlive)
        {
            future.addListener(ChannelFutureListener.CLOSE);
        }
	}	
}

в общем проще некуда. Есть Apache ab, который запускаю с параметрами: ab -n 10000 -c 10 http://localhost:8087/

Есть машина: под офтопиком 7 x64, Core i7-3770 4 ядра + HT(?), 16ГБ ОЗУ, Java(TM) SE Runtime Environment (build 1.6.0_45-b06).

Проблема: при нагрузке не грузит CPU на 100% независимо от параметров ab и Executors pool для Netty. Максимально удалось получить около 1000 запросов/сек, при этом CPU был загружен процентов на 25%, причем половина ядер явно совсем простаивала. При увеличении уровня конкурентности в ab растет время ответа и немного падает количество запросов/сек, CPU все так же отдыхает. Если запустить несколько копий ab, то увеличивается нагрузка на CPU (максимум до 80%), растет время ответа, но общая производительность серверной части остается той же судя по всему.

Что я упустил и как такое может быть?



Последнее исправление: maxcom (всего исправлений: 2)

запустить N инстансов netty (по количеству ядер у проца * гипертрейдинг) и каждый из них вручную запустить с affinity на соответствующее ядро - так проканает?

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

Дык они разве сокет между собой смогут поделить? Я Netty плохо знаю, но вроде как там есть boss thread, который на сокете сидит и соединения принимает и под них потоки ищет для обработки.

metadeu5
() автор топика

С включенным -k для ab удалось добиться 75000 запросов/сек и загрузку CPU на 70%, кроме того теперь все ядра задействованы, но дальше дело не идет.

metadeu5
() автор топика
Ответ на: комментарий от metadeu5

Сетевой стек локалхоста очень магический. Потом бенчмарк мешает работе сервера, сбрасывает ему кеши постоянно

vertexua ★★★★★
()
Ответ на: комментарий от metadeu5

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

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

Да я чето уже кучу параметров в регистре понаменял по советам из энторнетов, но как-то не помогло.

На самом деле проблема так и не решена, и нагрузить машину удается только запуском нескольких нагружалок. Яйцеголовые мне подсказывают, что возможно нагружалка говно, но я не верю.

metadeu5
() автор топика
Ответ на: комментарий от vtVitus

В реестре конечно же, да, совсем забыл уже винду.

metadeu5
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.