У меня есть HTTP-сервер Netty, который я тестирую, отправляя запросы через Apache JMeter.Я использую библиотеку метрик Dropwizard для измерения задержки на сервере.У меня проблема с метриками Dropwizard, которые показывают значения, отличные от JMeter, для задержки (Среднее и 99-й процентиль), но только время от времени.
Обработка происходит в отдельном пуле потоков, созданном с помощью класса ThreadPoolExecutor.Однако я заменил фактическую обработку, выполняемую в Test.java, на оператор сна, чтобы я знал, сколько времени занимает обработка.
Мой код выглядит следующим образом
LatencyTester.java
public class LatencyTester {
public static void main(String[] args) throws Exception {
Executors.newScheduledThreadPool(1);
displayMetrics.scheduleAtFixedRate(new Metrics(), 10, 10, TimeUnit.SECONDS);
new NettyServer().run();
}
}
NettyServer.java
public class NettyServer {
ThreadPoolExecutor executor;
public NettyServer() {
}
public void run() throws Exception {
executor = new ThreadPoolExecutor(7,7,100, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy());
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
Timer.Context context = Metrics.TIMER.time(); //Start Dropwizard metrics timer
ChannelPipeline p = ch.pipeline();
p.addLast(new HttpServerCodec());
p.addLast("aggregator", new HttpObjectAggregator(1048576));
p.addLast(new NettyServerHandler(executor, context));
}
}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(15000).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
NettyServerHandler.java
public class NettyServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
private Future<ByteBuf> result;
private Timer.Context cntx;
private ThreadPoolExecutor threadPool;
public NettyServerHandler(ThreadPoolExecutor pool, Timer.Context cntx) {
this.cntx = cntx;
this.threadPool = pool;
}
@Override
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
Test tst = new Test();
result = threadPool.submit(tst);
boolean keepAlive = HttpUtil.isKeepAlive(msg);
FullHttpResponse response = null;
response = new DefaultFullHttpResponse(HTTP_1_1, OK, result.get());
String contentType = msg.headers().get(HttpHeaderNames.CONTENT_TYPE);
if (contentType != null) {
response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType);
}
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
if (!keepAlive) {
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
} else {
response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
ctx.write(response);
}
ctx.flush();
cntx.stop(); //Stop Dropwizard metrics timer
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
Test.java
public class Test implements Callable<ByteBuf> {
public Test() {
}
@Override
public ByteBuf call() throws Exception {
TimeUnit.SECONDS.sleep(5);
return (Unpooled.copiedBuffer("Done".getBytes()));
}
}
Вот некоторые результаты, которые я получил после запусканесколько тестов на JMeter, каждый продолжительностью 5 минут.И сервер, и JMeter работают на моем ноутбуке.Потоки сервера, приведенные ниже, ссылаются на значение, установленное для экземпляра ThreadPoolExecutor в NettyServer.java (значения задержки ниже в мс).1020 * 1, 7, 33407, 35165, 33380, 35003
5, 17, 15695, 19998, 16667, 19970 - Среднее различие на 1 секунду
50, 50, 8963, 15032, 15356, 29959 - Большая разница
7, 23, 11295, 14965, 16121, 20002 - большая разница
Почему некоторые из этих тестов показывают несоответствия с результатами JMeter и Metrics?Я что-то не так делаю в том, где я запускаю и останавливаю таймер Dropwizard Metrics?
Что я могу сделать, чтобы точно измерить задержки запросов на стороне сервера, чтобы они отображали время, затраченное с момента получения запросов доответы отправлены?