【问题标题】:Http Server - Are Netty FileRegions reusable?Http Server - Netty FileRegions 可重用吗?
【发布时间】:2018-06-25 17:55:24
【问题描述】:

我目前正在使用 http 服务器,有些事情的行为有点奇怪。 我想生成动态内容,也只提供静态文件。 提供动态生成的内容没有问题。 因为我想从零拷贝中获利,所以我使用 FileRegions 来提供静态文件。 我的频道管道包含以下处理程序(按此顺序):

  1. HttpRequestDecoder
  2. HttpResponseEncoder
  3. HttpObjectAggregator
  4. ApiMapper

ApiMapper 是可共享的,并且是从 SimpleInboundHandler 派生的。 创建时,ApiMapper 从静态文件创建一个 FileRegion。 现在每次请求“/” uri 时都会发生这种情况:

  1. DefaultHttpReponse 被写入 ChannelHandlerContext。 DefaultHttpReponse 未被重用,并包含用于 内容类型和内容长度
  2. FileRegion 的 ReferenceCount 使用其 retain 方法增加。 然后使用 FileRegion 作为参数在 ChannelHandlerContext 上调用 writeAndFlush。 向返回的 ChannelFuture 添加了一个 ChannelFutureListener,它会打印“DONE”。

第一个响应按预期工作,浏览器获取完整文件并正确显示它并打印“DONE”。 但是,如果再次调用“/” uri,浏览器不会显示任何内容,只会永远加载,但会打印“DONE”。 然后在我重新启动服务器后,我使用 telnet 手动拨打电话。第一个响应是正确的,但后来我注意到第二个调用只返回一个标题,但没有内容。 “DONE”仍然会被打印出来。

所以我的问题是:可以多次使用同一个 FileRegion 对象吗?我做错了什么吗?

【问题讨论】:

    标签: java http server netty


    【解决方案1】:

    不,您不能以这种方式多次写入同一个 FileRegion,因为 transferred 状态在 DefaultFileRegion 对象上更新。您需要在此处为​​每次写入创建一个新的 DefaultFileRegion 实例。

    您还需要确保在您的FileRegion 之后发送LastHttpContent,否则HttpResponseEncoder 中的状态机在您编写第二个HttpResponse 时将不会处于正确状态。

    【讨论】:

    • 因此我可以重用 LastHttpContent.EMPTY_LAST_CONTENT?我是否必须在发送之前增加参考计数?
    • 最好是直接创建一个 ByteBuf,将文件内容存储在其中并重用它,然后每次都创建一个新的 DefaultFileRegion?我目前的应用程序不是很时间批评并且负载很重,但我对未来的项目很好奇。
    猜你喜欢
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 2018-10-30
    相关资源
    最近更新 更多