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