繁体   English   中英

将Netty直接IO缓冲区累积到CompositeByteBuf

[英]Accumulating Netty direct IO buffer to CompositeByteBuf

我们正在从应用程序中的Servlet API 2.5(每个请求的线程)迁移到Netty。 一种情况是使用我们拥有多年的阻塞式ini文件解析器。 当前的方法是将传入的ByteBuf累积到CompositeByteBuf并在用ByteBufInputStream包装之后将其提供给解析器。

在实际的应用程序中,我们使用HTTP,并且ini作为HTTP请求正文发送到服务器。 但在下面的代码段中,假定所有入站内容都是传输文件。

class AccumulatingChannelHandler extends ChannelInboundHandlerAdapter {
  final BlockingIniFileParser parser = new BlockingIniFileParser();
  CompositeByteBuf accumulator;

  @Override
  public void channelActive(ChannelHandlerContext ctx) {
    accumulator = ctx.alloc().compositeBuffer(Integer.MAX_VALUE);
  }

  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) {
    ByteBuf ioBuffer = (ByteBuf) msg;
    accumulator.addComponent(true, ioBuffer);
  }

  @Override
  public void channelInactive(ChannelHandlerContext ctx) {
    IniFile iniFile = parser.parse(new ByteBufInputStream(accumulator));
    accumulator.release();
    ByteBuf result = process(iniFile);
    ctx.writeAndFlush(result);
    ctx.close();
  }

  private ByteBuf process(IniFile iniFile) {...}
}

class BlockingIniFileParser {
  IniFile parse(InputStream in) {...}
}

interface IniFile {
  String getSetting(String section, String entry);
}

默认情况下,池直接缓冲区进入channelRead方法。 使用这种策略,我们可能会面临无法控制的直接内存消耗。 因此,我想了解:

  1. 以这种方式累积IO缓冲区是否合理?
  2. 是否有将Netty IO与阻塞解析器集成的最佳实践?
  3. 使用Netty解析输入(以某种结构化格式)的最佳实践是什么?

您没有提到典型的上载ini文件的大小,但是假设它们足够大以至于引起一些关注,我将考虑放弃CompositeByteBuf。 分配一个非池化的(可选直接)缓冲区,并在池中的缓冲区进入门中时,将其写入非池化缓冲区中,然后释放它们。 阅读完毕后,继续在未池缓冲的缓冲区周围使用ByteBufInputStream。 完成后,未缓冲的缓冲区将被GC化。

您仍将分配内存,但是不会从缓冲池中提取内存,如果您使用直接的非池缓冲,则不会对堆造成太大影响。

最终,如果未缓冲的缓冲区的大小仍然值得关注,我会咬牙切齿,将传入的缓冲池写到磁盘上,并在完成后使用FileInputStream读回它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM