Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 是否可以将大型文件上载到Ktor&;网络服务器?_Kotlin_Netty_Ktor - Fatal编程技术网

Kotlin 是否可以将大型文件上载到Ktor&;网络服务器?

Kotlin 是否可以将大型文件上载到Ktor&;网络服务器?,kotlin,netty,ktor,Kotlin,Netty,Ktor,我做了一个简单的文件上传和下载服务,发现据我所知,Netty在请求处理结束之前不会释放直接缓冲区。因此,我无法上传更大的文件 我试图确保问题不在我的代码中,因此我创建了最简单的微型Ktor应用程序: 路由{ 发布(“上传”){ call.receiveMultipart().forEachPart{} call.respond(HttpStatusCode.OK) } } 默认的直接内存大小约为3Gb,为了简化测试,我将其限制为: System.setProperty(“io.netty.ma

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

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

路由{
发布(“上传”){
call.receiveMultipart().forEachPart{}
call.respond(HttpStatusCode.OK)
}
}
默认的直接内存大小约为3Gb,为了简化测试,我将其限制为:

System.setProperty(“io.netty.maxDirectMemory”,(10*1024*1024.toString())
在启动NettyApplicationEngine之前

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

在服务器端,除了“java.io.IOException:breaked delimiter accurrented”异常之外,没有关于该问题的任何信息。但如果我将断点放在NettyResponsePiline#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在启动时没有本机e波尔支持,问题也是一样的)

你找到解决方案了吗?@SaurabhPadwekar,在这种情况下,从Netty切换到Jetty就足够了。谢谢你的回复。所以,在将Netty更改为Jetty之后,这个代码
调用.receiveMultipart().forEachPart{}
是否能够释放缓冲区?我知道我要求的太多了,但您是否可以分享代码片段,以展示如何在不导致内存泄漏的情况下接收较大文件的多部分块。谢谢。@SaurabhPadwekar,Jetty中的实现完全不同,直接内存没有问题。不过速度要慢25%。此外,我还必须使用ApacheFileUpload而不是ktor默认的CIOMultipartDataBase,因为CIOMultipartDataBase在上传过程中将临时文件保存到磁盘,这不适合我的服务。上载代码以FileUpload().getItemIterator(KtorUploadRequestContext(call.request))开始,其中FileUpload来自Apache,KtorUploadRequestContext是org.Apache.commons.FileUpload.UploadContext的非常简单的实现。
Ubuntu Linux
Java 8
Ktor=1.2.5
netty-transport-native-epoll=4.1.43.Final