加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – Play Framework:文件上传 – 阻止还是非阻止?

发布时间:2020-12-16 19:17:54 所属栏目:安全 来源:网络整理
导读:给出Play文档中的示例代码: def upload = Action(parse.temporaryFile) { request = request.body.moveTo(new File("/tmp/picture/uploaded")) Ok("File uploaded")} 如何处理100个同时缓慢上传的请求(线程数)? 上传文件缓冲在内存中还是直接流式传输到磁
给出Play文档中的示例代码:

def upload = Action(parse.temporaryFile) { request =>
  request.body.moveTo(new File("/tmp/picture/uploaded"))
  Ok("File uploaded")
}

>如何处理100个同时缓慢上传的请求(线程数)?
>上传文件缓冲在内存中还是直接流式传输到磁盘?

解决方法

How 100 simultaneous slow upload requests will be handled (number of threads)?

这取决于.使用的实际线程数量并不真正相关.默认情况下,Play使用的线程数等于可用的CPU核心数.但这并不意味着如果你有4个内核,那么你一次只能限制4个并发进程. Play中的HTTP请求在Akka配置的特殊内部ExecutionContext中异步处理.在ExecutionContext中运行的进程可以共享线程,只要它们是非阻塞的 – 这是由Akka抽象出来的.所有这些都可以以不同的方式配置.见Understanding Play Thread Pools.

消耗客户端数据的Iteratee必须进行一些阻止,以便将文件块写入磁盘,但是以小(和快)足够的块完成,这不应导致其他文件上传被阻止.

我更担心的是服务器可以处理的磁盘I / O量. 100个慢速上传可能没问题,但如果没有基准测试,你就无法说出来.在某些时候,当客户端输入超过服务器可写入磁盘的速率时,您将遇到麻烦.这在分布式环境中也不起作用.我几乎总是选择完全绕过Play服务器并直接上传到Amazon S3.

Will be uploaded file buffered in memory or streamed directly to disk?

所有临时文件都流式传输到磁盘.在引擎盖下,使用iteratee库异步读取从客户端发送到服务器的所有数据.对于分段上传,也没有什么不同.客户端数据由Iteratee使用,它将文件块流式传输到磁盘上的临时文件.因此,当使用parse.temporaryFile BodyParser时,request.body只是磁盘上临时文件的句柄,而不是存储在内存中的文件.

值得注意的是,尽管Play可以以非阻塞方式处理这些请求,但一旦完成移动文件将会阻止.也就是说,request.body.moveTo(…)将阻止控制器功能,直到移动完成.这意味着如果100个上传中的几个几乎同时完成,Play的内部ExecutionContext用于处理请求会很快变得过载. moveTo的底层API在Play 2.3中也已弃用,因为它使用FileInputStream和FileOutputStream将TemporaryFile复制到永久位置.文档建议您使用Java 7 File API,因为它更有效.

这可能有点粗糙,但更像这样的事情应该这样做:

import java.io.File
import java.nio.file.Files

def upload = Action(parse.temporaryFile) { request =>
    Files.copy(request.body.file.toPath,new File("/tmp/picture/uploaded").toPath)
    Ok("File uploaded")
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读