这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
完整架构
经过前面几章,文件上传系统已经从简单接口演进为完整平台。最终架构拆成控制面和数据面:
控制面:鉴权、配额、上传任务、元数据、签名、审核状态、审计日志
数据面:客户端直传、对象存储、分片合并、CDN 分发、异步扫描
控制面由业务服务掌握,因为它需要理解用户、租户、权限和文件状态。数据面交给对象存储、CDN 和异步任务系统承载,因为它们更适合处理大文件、大带宽和耗时任务。
分层架构
┌─────────────────────────────────────────────────────────────────┐
│ 入口(客户端) │
│ 上传 / 分片 / 秒传 / 断点续传 下载 / 预览 / 签名 URL │
└──────────────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────┐
│ 控制面(业务服务) │
│ 鉴权与配额 · 上传任务管理 · 文件元数据 · 签名签发 · 状态机 │
└──────────────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────┐
│ 数据面(文件承载) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 对象存储 │ │ CDN 分发 │ │ 异步处理 │ │
│ │ 分片/冷热 │ │ 边缘缓存 │ │ 扫描/转码 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└──────────────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────┐
│ 治理与数据 │
│ file_metadata · upload_task/part · file_audit_log · 生命周期 │
└─────────────────────────────────────────────────────────────────┘
最终上传链路
一次完整上传可以这样发生:
客户端申请上传任务(文件名/大小/类型/hash)
↓
业务服务校验权限、配额和文件策略,创建 upload_task
↓
服务端返回对象存储分片上传签名
↓
客户端直传分片到对象存储
↓
客户端提交完成请求,服务端校验分片并触发合并
↓
文件状态进入 scanning,异步扫描服务处理安全与内容审核
↓
扫描通过后状态变为 available
↓
用户访问文件时,业务服务校验权限并生成 CDN 签名 URL
↓
CDN 命中直接返回,未命中则回源对象存储
这条链路把大流量从业务服务中移走,同时保留业务侧对权限和状态的控制。
核心表设计
| 数据 | 作用 |
|---|---|
| file_metadata | 文件归属、大小、类型、状态、对象 key、hash |
| upload_task / upload_part | 分片上传任务、分片状态、过期时间 |
| file_audit_log | 上传、下载、删除、审核、风险处置记录 |
不要把所有信息塞进一张文件表。上传任务是临时过程,文件元数据是长期事实,审计日志是不可随意修改的追踪记录。
文件状态机
created -> uploading -> uploaded -> scanning -> available
-> rejected
-> deleted
对象存储只知道有一个对象,数据库才是业务事实来源。通过状态机和补偿任务修复一致性:uploading 超时清理临时对象,uploaded 迟迟未扫描重新投递任务,定期比对数据库和对象存储发现孤儿文件。
高可用与治理
- 临时分片 24 小时未完成自动删除。
- 用户删除文件先软删,再延迟物理删除。
- 长期不访问的大文件转入低频或归档存储。
- 审核拒绝的文件保留短期证据后清理。
- 上传成功率、回源率、存储成本、安全命中率持续监控。
这套架构的关键在于控制面和数据面分离:业务服务掌控权限与状态,对象存储和 CDN 承载文件流量,治理能力贯穿全链路。
