简体   繁体   English

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

[英]Accumulating Netty direct IO buffer to CompositeByteBuf

We are migrating from Servlet API 2.5 (thread per request) in our application to Netty. 我们正在从应用程序中的Servlet API 2.5(每个请求的线程)迁移到Netty。 One of cases is using blocking-style ini file parser which we had for many years. 一种情况是使用我们拥有多年的阻塞式ini文件解析器。 Current approach is accumulating incoming ByteBuf into CompositeByteBuf and feeding it to a parser after wrapping with ByteBufInputStream . 当前的方法是将传入的ByteBuf累积到CompositeByteBuf并在用ByteBufInputStream包装之后将其提供给解析器。

In real application we are using HTTP and ini is sent to a server as HTTP request body. 在实际的应用程序中,我们使用HTTP,并且ini作为HTTP请求正文发送到服务器。 But in snippet below it is assumed that all inbound content is transferred file. 但在下面的代码段中,假定所有入站内容都是传输文件。

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);
}

By default pooled direct buffers are coming to channelRead method. 默认情况下,池直接缓冲区进入channelRead方法。 And with such strategy we risk to get uncontrollable consumption of direct memory. 使用这种策略,我们可能会面临无法控制的直接内存消耗。 So, I would like to understand: 因此,我想了解:

  1. Is it rational to accumulate IO buffers in such fashion? 以这种方式累积IO缓冲区是否合理?
  2. Is there any best practice for integrating Netty IO with blocking parsers? 是否有将Netty IO与阻塞解析器集成的最佳实践?
  3. What is the best practice for parsing input (in some structured format) with Netty? 使用Netty解析输入(以某种结构化格式)的最佳实践是什么?

You have not mentioned the size of a typical uploaded ini file, but assuming they're large enough to cause some concern, I would consider ditching the CompositeByteBuf. 您没有提到典型的上载ini文件的大小,但是假设它们足够大以至于引起一些关注,我将考虑放弃CompositeByteBuf。 Allocate an un-pooled [optionally direct] buffer and as pooled buffers come in the door, write them to the un-pooled buffer, then release them. 分配一个非池化的(可选直接)缓冲区,并在池中的缓冲区进入门中时,将其写入非池化缓冲区中,然后释放它们。 When you're done reading, continue with your use of a ByteBufInputStream around the un-pooled buffer. 阅读完毕后,继续在未池缓冲的缓冲区周围使用ByteBufInputStream。 Once complete, the un-pooled buffer will be GCed. 完成后,未缓冲的缓冲区将被GC化。

You will still be allocating chunks of memory, but it won't be drawn from your buffer pools, and if you use a direct un-pooled buffer, it will not impact your heap as much. 您仍将分配内存,但是不会从缓冲池中提取内存,如果您使用直接的非池缓冲,则不会对堆造成太大影响。

Ultimately, if the size of the un-pooled buffer remains a concern, I would bite the bullet and write the incoming pooled buffers out to disk and on completion, read them back in using a FileInputStream. 最终,如果未缓冲的缓冲区的大小仍然值得关注,我会咬牙切齿,将传入的缓冲池写到磁盘上,并在完成后使用FileInputStream读回它们。

暂无
暂无

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

相关问题 Netty CompositeByteBuf是直接还是间接 - Is netty CompositeByteBuf direct or indirect Netty io.netty.buffer.ByteBuf.array()引发异常-直接缓冲区 - Netty io.netty.buffer.ByteBuf.array() throws exception - direct buffer Micronaut HttpResponse 主体 CompositeByteBuf 类型抛出 io.netty.util.IllegalReferenceCountException: refCnt: 0 - Micronaut HttpResponse body CompositeByteBuf type throws io.netty.util.IllegalReferenceCountException: refCnt: 0 io.netty.buffer.PooledByteBufAllocator的NoClassDefFoundError - NoClassDefFoundError for io.netty.buffer.PooledByteBufAllocator java.lang.NoSuchMethodError:io.netty.buffer.PooledByteBufAllocator.metric()Lio / netty / buffer / PooledByteBufAllocatorMetric; - java.lang.NoSuchMethodError: io.netty.buffer.PooledByteBufAllocator.metric()Lio/netty/buffer/PooledByteBufAllocatorMetric; 网络缓冲区,内核空间或用户空间在哪里分配直接缓冲区的内存? - Where is the memory of direct buffer allocated by netty, kernel space or user space? Memory 泄漏/发布 object io.netty.buffer.PooledByteBufAllocator 来自 JAR netty-configuration-buffer 过渡使用 - Memory leak/issue of the object io.netty.buffer.PooledByteBufAllocator from JAR netty-buffer transitively used by azure-data-appconfiguration 在Netty 4中直接使用内存 - Direct memory usage in Netty 4 将io.netty.buffer.ByteBuf转换为java.nio.ByteBuffer的有效方法 - Efficient way to convert io.netty.buffer.ByteBuf to java.nio.ByteBuffer grpc服务器启动时,大量的io.netty.buffer.PoolThreadCache $ MemoryRegionCache $ Entry实例 - Huge number of io.netty.buffer.PoolThreadCache$MemoryRegionCache$Entry instances when grpc server started
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM