首页 > 解决方案 > 是否可以将大文件上传到 Ktor & Netty 服务器?

问题描述

我正在制作一个简单的文件上传和下载服务,并发现据我了解,Netty 在请求处理结束之前不会释放直接缓冲区。结果,我无法上传更大的文件。

我试图确保问题不在我的代码中,所以我创建了最简单的微型 Ktor 应用程序:

routing {
    post("upload") {
        call.receiveMultipart().forEachPart {}
        call.respond(HttpStatusCode.OK)
    }
}

默认直接内存大小约为 3Gb,为了使测试更简单,我将其限制为:

System.setProperty("io.netty.maxDirectMemory", (10 * 1024 * 1024).toString())

在启动 NettyApplicationEngine 之前。

现在,如果我上传一个大文件,例如使用 httpie,我得到“连接重置”:

http -v --form POST http://localhost:42195/upload file@/tmp/FileStorageLoadTest-test-data1.tmp

http: error: ConnectionError: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer')) while doing POST request to URL: http://localhost:42195/upload

在服务器端,除了“java.io.IOException: Broken delimiter occurred”异常之外,没有关于该问题的信息。但是如果我把断点放在 NettyResponsePipeline#processCallFailed 中,真正的例外是:

io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 65536 byte(s) of direct memory (used: 10420231, max: 10485760)

可惜没有记录这个异常。

此外,我发现如果我使用 Jetty 引擎,相同的代码可以正常工作。

环境:

Ubuntu Linux
Java 8
Ktor=1.2.5
netty-transport-native-epoll=4.1.43.Final 

(但如果 Netty 在没有 native-epoll 支持的情况下启动,问题是一样的)

标签: kotlinnettyktor

解决方案


推荐阅读