Play Framework:如何处理内存密集型动作



我有一个Play Framework应用程序(Play 2.8、Scala 2.13和Java 8(,它使用Apache PDFBox 2从上传的PDF文件中创建JPG缩略图。缩略图是根据请求创建的,然后缓存在文件系统中。然而,当一个用户试图显示带有许多PDF的库,而这些PDF没有缓存缩略图时,会同时创建一堆缩略图,服务器会因OutMemoryError而崩溃(同时执行5或6个任务似乎就足够了(。服务器会自动重新启动,几十秒钟后就可以使用了,但创建的缩略图已经损坏,我不得不面对许多不可用的问题。

PDFBox配置为使用临时文件,但在渲染缩略图时会出现内存不足的情况。

服务器只有2 GB的RAM可用。上传的PDFS每个约为1MB,生成的缩略图约为100KB(72DPI;大小约为500×1000px(。我可以在不增加堆大小的情况下解决这个问题吗?理想情况下,Play应该能够自动对这些内存密集型请求进行排队,但我可以通过手动限制同时进行的内存密集型任务的数量来生存,不知何故…

最简单的方法可能是使用一个专用的ExecutionContext和一个底层固定大小的线程池来生成缩略图。

import java.nio.file.Path
import java.util.concurrent.Executors
import scala.concurrent.{ ExecutionContext, Future }
object RenderPDF {
implicit val ec : ExecutionContext = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(3 /* adjust */))
def thumbnail(pdf: Path) : Future[Path] = Future {
... // call PDFbox
}
}

您可以在操作处理程序中使用它来加载缩略图的生成。

如果你正在处理上传的PDF,预渲染缩略图可能会更好,因为这样可以避免用户打开图库时突然需要渲染几十个PDF的问题。

最新更新