Что-то не пойму в чем проблема: есть 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%), растет время ответа, но общая производительность серверной части остается той же судя по всему.
Что я упустил и как такое может быть?