next/image组件导致服务器504超时

谁能想到,一个前端组件也能把服务搞崩溃。这个组件正是next/image,原本是想利用next/image来优化图片,next.js官方也一直推荐这么做。

突然有一天用户反馈网站出现504超时报错,当时优先重启恢复服务。然后把日志打开观察,果不其然,几分钟后就又出现504超时,伴随出现的日志则是:

upstream image response failed for https://example.com/280d59d8-f3b0-11ed-a295-00163e253f9a_00002_VvBbv3zj.jpg?OSSAccessKeyId=LTAI5nodLHeacT1J5SmWh&Expires=317044217325&Signature=Wf5jYWf7vnXOyRoKLVtiTCrt8%3D 404

初步判断是图片404导致服务器超时,深入猜测是使用next.js服务端渲染请求了图片资源,而图片资源不存在导致服务器渲染出错。

但是很不合理,服务端只是把图片资源的地址渲染到html中,并不会在服务端请求图片资源才对,为什么服务器日志会出现上述错误信息呢?于是观察浏览器中图片的请求,发现格式是这样的: http://example.com/_next/image?url=https%3A%2F%2Fexample.com%2Ff6c912da-f0cc0000_0d7GBaLE.jpg%3FOSSAccessKeyId%3DmWh%26Expires%3D317043899846%26Signature%3DYUMro%253D&w=384&q=75

浏览器请求的图片资源并不是图片的真实地址,而是经过了next.js服务处理的,尤其是URL最后两个参数,是图片压缩参数。如果你发现图片变模糊了,也可能是这两个参数捣的鬼。直接拿着这个地址去浏览器请求发现响应很慢,这时再次得出结论:这个图片组件有问题。为了验证把所有使用了next/image组件全部使用原生img标签,发布到线上后就再没出现504超时。

总结:next/image组件包装后的图片资源需要经过node层压缩处理,会消耗CPU资源,对于大量的图片资源会有风险,酌情处理。 本次出现的时候伴随着图片资源404,可能是有bug存在,如果加载不到正确的图片就会触发bug。 另一种解决方案:根据官方文档说明,如果使用next/image,需要添加sharp包来提高性能,但是可能需要注意内存消耗问题。