1

我构建了一个图像交付应用程序,它可以提供图像并按需调整大小/更改图像扩展名。

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

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

我构建的一切工作正常,但在生产中 CPU 使用率很高。我怀疑这是因为我在将图像res.sendFile()保存到文件系统后返回了图像。

目前这是我的工作流程:

  • 如果图像已使用所需参数(fs.access())保存,我会检查文件系统
  • 如果存在,我res.sendFile本地图像路径
  • 如果它不存在,我使用 Sharp 生成它,我将它保存在文件系统中,然后我res.sendFile生成的图像路径

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

我该如何更换它?

这是我在谷歌搜索时发现的:

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

1 回答 1

1

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

有几种方法可以做到这一点。最简单的可能是从您的 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;
}
于 2017-09-26T11:10:33.907 回答