Реализован http-сервер netty 4.
public void start() {
System.out.println("In Start method");
try {
ServerBootstrap b = new ServerBootstrap();
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new HttpServerPipelineFactory())
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, WriteBufferWaterMark.DEFAULT)
.childOption(ChannelOption.AUTO_READ, false)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(listenerPort).sync();
System.out.println("server started listening on port " + listenerPort);
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}
}
Класс фабрики конвейера HTTP -
public class HttpServerPipelineFactory extends ChannelInitializer<Channel> {
@Override
protected void initChannel(Channel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("codec", new HttpServerCodec());
pipeline.addLast("compress", new HttpContentCompressor());
pipeline.addLast("decompress", new HttpContentDecompressor());
pipeline.addLast("aggregator", new HttpObjectAggregator( 512 * 1024));
pipeline.addLast("chunked", new ChunkedWriteHandler());
pipeline.addLast("flow", new FlowControlHandler());
pipeline.addLast("keep-alive", new HttpServerKeepAliveHandler());
pipeline.addLast("request", new AdvancedHTTPHandler());
}
}
AdvancedHTTPHandler - -
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import static io.netty.util.CharsetUtil.UTF_8;
public class AdvancedHTTPHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
private static Logger logger = LoggerFactory.getLogger(HTTPRequestHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.copiedBuffer("My Netty".getBytes()), false);
response.headers().add(request.headers());
response.headers().set(CONTENT_LENGTH, response.content().readableBytes());
ctx.channel().writeAndFlush(response);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
ctx.read();
}
}
Я хочу для отладки -Dio.netty.leakDetection.level=PARANOID
и я установил его как аргумент JVM здесь . Это не работает, если у меня нет зависимости implementation("org.springframework.boot:spring-boot-starter:2.2.6.RELEASE")
.
Если у меня есть эта зависимость implementation("org.springframework.boot:spring-boot-starter:2.2.6.RELEASE")
и я запускаю сервер, я могу видеть журналы, связанные с утечкой ресурсов -
![Netty resource leak logs](https://i.stack.imgur.com/ehrgJ.jpg)
Если я прокомментирую эту зависимость и запустим проект gradle with-spring:runMain
, то журналы утечки ресурсов netty не будут выведены в консольный журнал.
Мой проект находится на github здесь .
Зачем мне добавлять зависимость, которая не нужна для работы arg JVM. Есть идеи?