使用Express提供动态生成的图像或保存的图像

时间:2017-09-20 14:14:59

标签: javascript express sharp

我构建了一个图像传送应用程序,可以按需提供图像和调整图像扩展名。

我使用Express进行路由,使用Sharp来处理图像。

当使用新的大小/扩展名请求图像时,我想将生成的图像保存在文件系统上,并在下次使用相同参数(缓存的种类)请求相同图像时检索保存的图像。 / p>

我构建的所有内容都运行正常,但在生产中CPU使用率很高。我怀疑这是因为我将文件保存在文件系统后返回res.sendFile()的图像。

目前这是我的工作流程:

  • 我检查文件系统是否已使用所需参数保存图像(fs.access()
  • 如果存在,我res.sendFile本地图像路径
  • 如果它不存在,我使用夏普生成它,我将它保存在文件系统上,并res.sendFile生成的图像路径

我读res.sendFile不使用系统sendfile调用,并且CPU很重。

我该如何更换?

以下是我在Google上搜索时发现的内容:

  • 当我生成新图片时,我可以res.send()夏普生成的缓冲区而不是res.sendFile已保存的图片
  • 当图像已经保存时,也许我应该使用静态快速中间件(http://expressjs.com/en/starter/static-files.html),但我不知道如何动态调用它并告诉它图像路径(基于提供的参数)请求网址。)。

1 个答案:

答案 0 :(得分:1)

不幸的是,使用static中间件会产生相同的性能特征,因为它使用与res.sendFile相同的方法。您想要做的就是在应用程序前面运行来自Nginx或smilar反向代理的图像。

有几种方法可以实现这一目标。最简单的可能是从Node.js应用程序发送重定向,指向反向代理服务的位置。

基本上,当/imageID/toto.jpg?quality=80的请求进入时,您希望将其重定向到/static-images/imageID_80.jpg

// ...

const imageName = ${req.params.imageId}_${req.query.quality}.jpg

if (!(await pathExists(imageName)) {
  await generateFileUsingSharp(req.params.imageId, req.query.quality)
}

res.redirect(`/static-images/${imageName}`)

然后你会让Nginx在/static-images位置提供文件:

location /static-images {
  alias /var/www/generated-images;
}