ai-chatbot/docs/AI生图平台桶缓存落地对接答复-基于项目现状.md
Your Name fe8a8564e7
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
Update agent visibility fixes and local docs
2026-03-21 02:01:56 +08:00

14 KiB
Raw Blame History

AI生图平台桶缓存落地对接答复(基于本项目现状)

1. 文档目的

本文档用于回应本地清单 AI生图平台桶缓存落地对接清单.md,并结合当前项目的真实实现,给出一份可以直接用于和基础设施、资源域名、桶存储负责人对齐的项目侧答复。

本文只描述“当前项目已实现的事实”和“基于这些事实的建议”,不把尚未上线的理想方案写成现状。


2. 一句话结论

对本项目来说,只要 https://s3.jiansun.vip 继续作为统一对外资源主域名,并且入口服务器上的 180G 磁盘缓存只做“读缓存”而不改上传链路,那么项目应用层基本不需要改代码,就可以直接受益。

原因很简单:

  • 项目当前所有图片类资源最终都走统一存储服务上传
  • 对外 URL 由存储配置里的 publicUrl 决定,而不是写死在业务代码里
  • 项目默认就是“新内容新 key”,天然适合读缓存
  • 当前没有依赖“对象覆盖后立刻强制失效”的核心链路

3. 当前项目真实存储链路

3.1 上传入口

项目中的图片上传与多数生图结果回存,都会走统一存储服务:

  • 核心实现:lib/storage/service.ts
  • 聊天上传接口:app/(chat)/api/files/upload/route.ts

统一存储服务的优先级如下:

  1. 数据库中配置的默认 S3 兼容存储
  2. 备用桶故障切换配置
  3. 环境变量 S3
  4. Vercel Blob 兜底

也就是说,项目本身已经是“多存储后端兼容”的。

3.2 对外 URL 生成方式

当前项目上传成功后,对外图片 URL 的生成规则是:

  • 如果存储配置里设置了 publicUrl
    • 返回:publicUrl + /uploads/...
  • 如果没有设置 publicUrl
    • 返回:endpoint + /bucket + /uploads/...

因此,对项目来说真正关键的不是“桶后面用不用缓存”,而是:

  • 当前默认存储配置中的 publicUrl 是否统一指向 https://s3.jiansun.vip

如果是,那么项目对外发给前端、消息、相册、画布、详情页的资源 URL,就会自然统一使用这个域名。

3.3 当前资源 key 规则

项目统一上传时,文件 key 采用:

uploads/{timestamp}-{random}.{ext}

特点:

  • 路径前缀稳定:/uploads/
  • 文件名默认唯一
  • 默认不会覆盖旧对象

这对读缓存非常友好,因为:

  • 同一张新图天然是新 URL
  • 缓存不会因为“同 URL 内容被覆盖”而频繁失真

4. 本项目实际会被缓存命中的资源范围

基于当前代码,最适合接入入口机磁盘读缓存的资源,主要是这些:

4.1 用户上传图片

来源:

  • 聊天区上传
  • 画布素材上传
  • 局部编辑、修图、扩图等中间结果回存

特点:

  • 统一进 uploads/...
  • 后续可能被多轮编辑、对话历史、画布再次引用

4.2 AI 生成结果图

来源:

  • 聊天生图
  • 编辑生成
  • 扩图、增强、去水印、角度编辑等图像工作流

落库位置:

  • generatedImage.originalUrl
  • generatedImage.thumbnailUrl

这些 URL 会被以下场景重复读取:

  • 聊天消息回放
  • 相册页 /gallery
  • 精选页
  • 管理后台图片记录
  • 无限画布节点

4.3 详情页生成相关图片

来源:

  • AI详情主图
  • AI详情追加评价晒图
  • 详情历史归档封面图

特点:

  • 一轮生成后可能被画布、存档、后续再次编辑反复读取
  • 对重复访问更敏感,适合缓存

4.4 工作流中的中间结果图

如:

  • 去背景结果
  • 增强图
  • 扩图结果
  • 角度编辑结果
  • 场景融合图

特点:

  • 虽然是中间态,但在会话里会被持续回读
  • 如果用户反复对比和继续编辑,也会产生热点访问

5. 对清单中关键问题的项目侧答复

5.1 关于“需要确认的资源范围”

基于项目实际情况,可以先明确:

当前最值得纳入缓存命中的路径前缀

首选:

  • /uploads/

原因:

  • 当前统一上传服务默认就写入这个前缀
  • 这是用户上传图、生成图、处理结果图最稳定的公共前缀

当前最可能成为热点的资源类型

  • 会话中反复引用的参考图
  • 相册中的生成结果图
  • AI详情主图与评价晒图
  • 画布中的历史结果图
  • 编辑工作流中多轮引用的中间结果图

项目侧当前无法直接从代码给出的内容

项目代码里目前没有现成的“近 3 天 Top20 资源 URL 统计”接口。

所以如果基础设施侧需要:

  • 近 3 天最常访问的 20 个资源 URL
  • 主要热点路径前缀

建议直接从:

  • Nginx access log
  • 对象存储访问日志
  • 资源域名层日志

做统计,而不是从业务数据库里推。

5.2 关于“是否统一只使用一个主资源域名”

项目建议结论

建议统一:

  • 主用:https://s3.jiansun.vip
  • 备用:https://s3.yydd.ai

并且在项目的默认存储配置里:

  • publicUrl 只配置成 https://s3.jiansun.vip

为什么对本项目很重要

因为当前项目会把图片 URL 持久化到很多地方:

  • generatedImage
  • 消息内容 markdown
  • media asset
  • 画布数据
  • AI详情归档

如果两个公网域名都长期作为默认资源入口使用,就会出现:

  • 同一份资源在数据库中可能留下两套公网 URL
  • 前端、相册、对话、画布里都可能混用不同域名

这会带来:

  • 缓存命中分散
  • 数据治理复杂
  • 后续域名切换和清理成本变高

项目侧结论

对当前项目来说:

  • 可以保留 https://s3.yydd.ai 作为基础设施备用
  • 但不建议把它配置成业务默认返回的资源 URL

5.3 关于“是否同 key 覆盖”

当前项目默认行为

默认不是同 key 覆盖,而是新内容新 key。

这是当前项目的真实实现。

统一上传时生成的路径形式为:

uploads/{timestamp}-{random}.{ext}

这意味着什么

对于缓存层来说,这其实是最理想的模式:

  • 新图 = 新 URL
  • 不需要依赖强制 purge
  • 缓存旧对象不会污染新对象

需要注意的例外

如果未来有人在对象存储层手工做:

  • 同路径覆盖
  • 同 key 重写

那么缓存仍可能返回旧内容。

但就当前项目默认代码路径而言,这不是主流行为。

5.4 关于“时效要求”

当前项目的大多数图片链路

当前项目大多数图片资源都适合“读缓存优先”:

  • 新图默认新 URL
  • 会话、相册、画布大多是读取已经生成好的资源
  • 不依赖“同 URL 秒级替换内容”

当前少数需要特别注意的情况

  1. 如果基础设施层后续做了“同 URL 覆盖”
  • 会有缓存短时返回旧图的风险
  1. 如果资源域名切换
  • 旧 URL 已经持久化在数据库和消息里,不能只改 DNS 口径,还要考虑历史数据

项目侧建议

只要遵守:

  • 新内容新 key
  • 主资源域名单一化

那么当前项目对缓存一致性的压力并不高。

5.5 关于“流量规模”

项目代码层能确定的事实

当前项目存在大量图片重复读取场景:

  • 聊天消息回放
  • 相册分页
  • 画布节点回显
  • AI详情历史存档
  • 后续编辑再次读取旧图

项目代码层目前不能直接给出的事实

项目中没有现成的资源访问量级面板来回答:

  • 峰值并发
  • 每分钟请求数
  • 热点 URL 排行
  • 资源命中曲线

这类数据仍建议由入口网关、Nginx、对象存储日志侧统计。

项目侧判断

从业务形态上看,本项目非常适合读缓存,因为它是明显的“生成后被多次回看、回显、继续编辑”的产品,不是“一次下载后永不再读”的冷资源型系统。

5.6 关于“联调样本”

项目侧建议联调用下面 3 类真实资源:

  1. 用户上传原图
  • 路径特征:/uploads/...
  • 用于验证首次回源、二次命中
  1. AI 生成结果图
  • 包括 originalUrl 和 thumbnailUrl
  • 用于验证相册、会话回放、画布回显的缓存效果
  1. AI详情主图或晒单图
  • 文件通常更大、读取更频繁
  • 用于验证长图场景的稳定性

项目本身可以提供测试资源 URL,但如果要验证“真实热点价值”,仍建议从线上真实访问日志中抽样。

5.7 关于“这次不需要改的内容”

结合项目现状,这次确实不需要先改这些内容:

  • 不需要改业务接口域名
  • 不需要先迁桶
  • 不需要改聊天上传接口
  • 不需要改 AI 生图主流程
  • 不需要改画布或相册读取逻辑

前提条件只有一个:

  • 当前默认存储配置中的 publicUrl 继续统一返回主资源域名

6. 项目侧对“会不会有两个 URL”的明确答复

6.1 缓存本身不会制造第二个 URL

对本项目来说,只要缓存层放在:

  • https://s3.jiansun.vip

前面,且仍返回同一个公网地址,那么:

  • 会话里看到的 URL 不变
  • 相册里拿到的 URL 不变
  • 数据库里保存的 URL 不变
  • 只是入口服务器内部多了一份磁盘缓存

所以:

缓存本身不会让本项目出现第二个用户可见 URL。

6.2 真正会导致“双 URL”的是双域名并用

如果业务层长期同时把下面两个域名都写进数据库或消息:

  • https://s3.jiansun.vip/...
  • https://s3.yydd.ai/...

那对本项目来说就真的是两套 URL 了。

这不仅影响缓存,也会影响:

  • 相册聚合
  • 画布历史复用
  • 消息解析
  • 存储迁移时的 URL 替换

因此项目侧建议非常明确:

  • s3.jiansun.vip 作为唯一默认 publicUrl
  • s3.yydd.ai 只做备用访问入口,不写入业务默认配置

7. 项目里已有的相关能力,基础设施侧可以放心利用

7.1 多存储后端兼容 已具备

当前项目支持:

  • S3 / MinIO / 阿里云 OSS 风格配置
  • 默认存储
  • 备用桶故障迁移

7.2 阿里云 OSS 入口桶 + 延迟转存 已具备

当前项目已有:

  • 上传优先进入阿里云 OSS 的配置
  • 到期后转存到目标默认桶
  • 转存后自动替换数据库中的 URL
  • 到期后清理源对象

这说明项目本身已经有“入口桶”和“最终落地桶”的概念。

但要注意

这套 OSS 转存能力和你们现在要做的 入口机读缓存 不是一回事:

  • OSS 转存:属于存储生命周期管理
  • 入口机缓存:属于读路径加速

两者可以并存,而且不会冲突。

7.3 对外资源路径稳定 已具备

当前绝大多数图片都落在:

/uploads/...

这很适合基础设施侧做:

  • 路径维度的缓存策略
  • 热点资源命中统计
  • 单独限流和回源观测

7.4 Provider 读图适配 已具备部分能力

例如 Volcano Vision provider 中,已有把 publicUrl 形式的上传图 URL 重写成底层 endpoint/bucket 形式的逻辑,用于避免部分供应商抓取公开资源时失败。

这说明:

  • 项目不是完全假设“所有供应商都直接从公网域名读图”
  • 即便公网资源域名前面加了缓存,只要 publicUrl 配置一致,当前系统仍然能工作

8. 当前项目对缓存落地的建议

8.1 项目侧推荐落地方式

建议基础设施侧这样落:

  1. 保持业务默认资源域名为 https://s3.jiansun.vip
  2. 让 s3.jiansun.vip 前挂入口服务器读缓存
  3. 缓存主要覆盖 /uploads/ 路径
  4. 不改上传链路,不改桶位置
  5. 不在业务配置中默认使用 https://s3.yydd.ai

8.2 项目侧推荐前置检查项

在正式切量前,建议先确认:

  1. 项目当前默认存储配置里的 publicUrl 是否为 https://s3.jiansun.vip
  2. 历史数据库中是否已经混入了 s3.yydd.ai 资源 URL
  3. Nginx 缓存是否正确返回命中头,如 X-Cache-Status
  4. 是否只缓存 GET 读流量,不介入写入逻辑
  5. 是否对超大文件和极低频资源设置合理淘汰策略

8.3 项目侧不建议的做法

  1. 不建议把两个公网资源域名同时作为业务默认入口
  2. 不建议让业务层开始复用同一个对象 key 覆盖新图
  3. 不建议把“入口读缓存”和“迁桶/改上传链路”绑定在同一个窗口一起做

9. 项目侧当前仍缺少的支持

虽然项目整体适配缓存没有问题,但如果后面要长期运营缓存层,当前项目还缺这些观测能力:

  1. 没有按资源 URL 维度的访问统计
  2. 没有热点资源排行榜
  3. 没有区分“上传成功量”和“资源读取量”的统一面板
  4. 没有面向缓存层的 purge / 失效控制接口

这些都不是这次缓存落地的阻塞项,但属于后续优化方向。


10. 最终答复口径

如果要给 AI 生图平台负责人一个简短的项目侧结论,可以直接用下面这段:

基于我们当前项目实现,入口服务器上的 180G 磁盘缓存可以直接作为 https://s3.jiansun.vip 的读缓存使用,项目业务层基本不需要改造。因为我们当前图片资源统一经存储服务上传,对外 URL 由存储配置中的 publicUrl 决定,且默认采用 uploads/{timestamp}-{random}.{ext} 这种新内容新 key 的方式,天然适合缓存命中。

对项目最关键的前提只有两个:

  1. 业务默认资源域名统一使用 https://s3.jiansun.vip;
  2. 不要把 https://s3.yydd.ai 同时作为默认业务资源域名写入数据库或消息。

只要保持“主域名单一化 + 新内容新 key”,当前这套读缓存方案对我们的聊天生图、画布、相册、AI详情等链路都是正向收益,而且不会改变现有上传链路和真实桶位置。


11. 相关代码位置

如需进一步联调,可重点查看:

  • 统一上传服务:lib/storage/service.ts
  • 上传接口:app/(chat)/api/files/upload/route.ts
  • OSS 转存任务:lib/jobs/oss-image-migration-job.ts
  • OSS 转存 API:app/api/jobs/migrate-oss-images/route.ts
  • 相册读取:app/api/gallery/route.ts
  • 聊天图片落库:app/(chat)/api/chat/route.ts
  • Volcano 读图 URL 改写:lib/ai/providers/volcano-vision.ts