在AWS EC2部署Next.js时,是否需缓存S3图片或迁移缓存至CloudFront?
解答
1. 要不要在EC2的Next.js里缓存S3图片?
完全没必要,纯浪费成本。理由很简单:
- AWS内部S3到EC2的网络延迟极低,同区域内的流量还免费,靠本地缓存提速的收益几乎为0。
- 你已经搭了CloudFront CDN,所有图片请求最终都会被CloudFront缓存,EC2本地存的优化图只会额外占EC2磁盘空间,还可能出现缓存过期不及时的问题——比如S3里的原图更新了,EC2缓存的旧图还在给用户返回。
2. 怎么把Next.js的图片优化缓存移到CloudFront?
考虑到你不太懂Lambda,给你两个上手简单的方案:
方案一:让CloudFront直接缓存Next.js输出的优化图
这是最省心的方案,不需要额外加服务,只调配置就行:
- Next.js侧配置:在
next.config.js里放开S3域名的图片加载权限,同时关掉Next.js的本地缓存(避免占EC2资源):
部署时不要给EC2的module.exports = { images: { remotePatterns: [ { protocol: 'https', hostname: '你的S3桶域名(比如xxx.s3.amazonaws.com)', pathname: '/**', }, ], cacheMemoryCount: 0, // 关闭内存缓存,省EC2内存 // 若用Next.js 13+ App Router,可加unoptimized: false确保优化功能开启 }, };.next/cache/images目录做持久化存储(比如不挂载EBS卷到这个目录),这样EC2重启后缓存会自动清掉,不会长期占空间。 - CloudFront侧配置:
- 把你的EC2服务器设为CloudFront的源(多EC2场景可先配置ELB)。
- 针对
/_next/image*开头的请求,设置长TTL(比如30天),因为优化后的图片基本不会变更。 - 缓存键要包含请求里的
w(宽度)、q(质量)参数,这样不同尺寸、质量的优化图能被分别缓存。
这样用户第一次请求某张优化图时,会走到EC2的Nextjs处理,处理完CloudFront就把结果缓存下来,后续请求直接从CloudFront返回,EC2不会存储任何优化图,完全避免重复存储的成本。
方案二:用S3托管优化后的图片(适合图片量很大的场景)
如果想彻底让AWS托管优化图,不让EC2沾手图片处理,可以这么搞:
- 建两个S3桶:一个存原始图片,另一个存优化后的图片(开启静态网站托管)。
- 给Next.js写个自定义图片loader,让它生成指向CloudFront的优化图URL。当用户请求优化图时,CloudFront如果没缓存,就触发EC2上的Next.js处理优化,然后把优化后的图片上传到存优化图的S3桶里,后续请求直接从这个S3桶+CloudFront返回。
- 这个方案要写点简单的上传代码,比方案一麻烦,但适合长期有大量图片优化需求的场景,能进一步减轻EC2的压力。
3. 额外的成本优化小技巧
- 给存原始图片的S3桶加生命周期规则,把3个月以上没访问的图片转到Glacier低成本存储,能省不少钱。
- 当S3里的原始图片更新时,手动或者用S3事件通知触发CloudFront的缓存失效,避免用户看到旧图。
内容的提问来源于stack exchange,提问作者spyhere
相关产品推荐
相关产品推荐

