2.4 KiB
2.4 KiB
文件上传策略分析
🎯 业界成熟方案:先上传OSS,再存数据库
方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 先上传OSS,再存数据库 ✅ | 1. OSS上传失败不影响数据库 2. 数据库事务可快速回滚 3. 用户体验好(文件已上传) 4. 孤立文件可定时清理 |
1. 数据库失败会产生孤立文件 2. 需要清理机制 |
推荐方案(业界主流) |
| 先存数据库,再上传OSS | 1. 数据库失败不会上传OSS 2. 不会产生孤立文件 |
1. OSS上传失败需要回滚数据库 2. 数据库事务时间长 3. 用户体验差 |
不推荐 |
为什么选择"先上传OSS,再存数据库"?
-
性能优势
- OSS上传是外部服务调用,不应该阻塞数据库事务
- 数据库事务时间短,减少锁竞争
-
可靠性优势
- OSS上传失败,直接返回错误,不产生脏数据
- 数据库保存失败,OSS文件可以后续清理(定时任务)
-
用户体验优势
- 文件已上传成功,即使数据库失败,文件还在
- 可以重试数据库保存,无需重新上传
-
业界实践
- 阿里云、腾讯云、AWS 等主流云服务都推荐此方案
- 大多数开源项目采用此方案
当前实现方案
1. 校验(文件分类、配额)
↓
2. 读取文件内容
↓
3. 上传到OSS(FileService.createFile)
- 成功:返回 fileUrl 和 filePath
- 失败:直接抛出异常,不保存数据库
↓
4. 保存数据库(事务中)
- 成功:返回文件ID
- 失败:删除OSS文件,抛出异常
↓
5. 更新配额
异常处理
-
OSS上传失败
- 直接抛出异常,不保存数据库
- 用户可重试上传
-
数据库保存失败
- 删除已上传的OSS文件(清理)
- 抛出异常,用户可重试
-
孤立文件清理
- 定时任务清理未关联数据库的OSS文件
- 基于 infra_file 表的创建时间判断
优化建议
-
异步清理孤立文件
- 定时任务扫描 infra_file 表
- 删除超过7天未关联 tik_user_file 的文件
-
重试机制
- 数据库保存失败时,记录重试队列
- 后台任务重试保存
-
监控告警
- 监控OSS上传失败率
- 监控数据库保存失败率
- 监控孤立文件数量