杠精派
派聪明
0/512

热门评论

Yuxy 2026年02月07日 17:55
引用原文:才会调用 commitSync() 提交 offset
这个是应该在@KafkaListener注解的方法中实现吗?举个例子
点赞
回复2 取消回复
Yuxy 2026年02月07日 17:56
这个是应该在@KafkaListener注解的方法中实现吗?举个例子@派聪明
点赞
回复 取消回复
Yuxy 2026年02月07日 18:10
是的,绝大多数情况下就写在 @KafkaListener 方法中,而且要放在“业务全部成功之后”。 手动提交 offset 的正确姿势是: ****************** = false 在 @KafkaListener 方法中 业务逻辑全部成功后 显式调用 ack.acknowledge()(Spring Kafka 推荐) 或 consumer.commitSync()(低层方式)
这个是应该在@KafkaListener注解的方法中实现吗?举个例子@派聪明
点赞
回复 取消回复

10 条评论

落雨 2026年02月10日 02:28
引用原文:拦截器
****************************,用的是过滤器吧
点赞
回复 取消回复
Yuxy 2026年02月07日 22:05
引用原文:在写入链路中,如何保证MySQL、Redis、MinIO和Elasticsearch之间的数据最终同步?
@派聪明
点赞
回复1 取消回复
派聪明 2026年02月07日 22:06
在文件上传处理链路中,MySQL、Redis、MinIO 和 Elasticsearch 的数据最终同步通过 **事件驱动架构 + 重试机制 + 死信队列(DLQ)** 实现,具体策略如下: --- ### **1. 核心架构:Kafka 异步解耦** - **生产端**:文件合并完成后,向 Kafka 的 `file-processing` 主题发送消息(含文件 MD5、路径等元数据)。 - **消费端**:多个消费者并行处理任务: - **MinIO 下载** → **文本解析** → **分块存 MySQL** → **向量化存 ES**。 --- ### **2. 关键一致性保障机制** #### **(1) 消息投递可*性** - **生产端事务**: - 使用 `@Transactional` 保证 MySQL 状态更新与 Kafka 消息发送在同一事务中(原子性)。 - 配置 `acks=all` + `retries=3` + 幂等生产者,确保消息至少成功一次。 - **消费端幂等**: - 消费者通过文件 MD5 唯一标识任务,避免重复处理。 #### **(2) 失败重试与补偿** - **自动重试**: - 消费者配置 `DefaultErrorHandler`,失败后等待 3 秒重试,最多 4 次(共 5 次机会)。 - 使用 `Spring Retry` 处理外部服务(如豆包 API)超时。 - **死信队列(DLQ)**: - 重试失败的消息自动转发至 `file-processing-dlt` 主题,隔离故障任务。 - 通过监控告*或定时任务补偿 DLQ 中的数据。 #### **(3) 数据状态追踪** - **MySQL 任务表**: - 记录每个文件的处理状态(`PENDING → PARSING → VECTORIZING → COMPLETED/FAILED`)。 - 支持后台任务扫描失败状态,手动或自动重跑。 --- ### **3. 各系统职责分工** | **系统** | **作用** | |----------------|--------------------------------------------------------------------------| | **MySQL** | 存储文件元数据、分块文本、处理状态(核心数据源)。 | | **Redis** | 缓存分片上传状态(Bitmap),加速断点续传查询。 | | **MinIO** | 存储原始文件、分片数据;合并后提供文件访问。 | | **Elasticsearch** | 存储文本块的向量索引,支持混合搜索(向量 + 关键词)。 | | **Kafka** | 解耦异步任务,保证消息可*投递与重试。 | --- ### **4. 边界情况处理** - **网络抖动**:生产者/消费者自动重试,确保消息不丢失。 - **服务故障**: - MinIO/ES 不可用时,任务进入 DLQ,恢复后重试。 - MySQL 回滚时,Kafka 消息未发送(事务性保障)。 - **数据不一致**: - 通过任务状态表 + 定时对账任务,检测并修复不一致(如 ES 索引缺失)。 --- ### **总结** 系统通过 **Kafka 事件驱动** 实现跨系统解耦,结合 **事务消息 + 自动重试 + 死信队列** 确保最终一致性。即使部分服务短暂故障,也能通过重试和补偿机制恢复数据同步,同时避免阻塞用户上传流程。
点赞
回复 取消回复
Yuxy 2026年02月07日 17:55
引用原文:才会调用 commitSync() 提交 offset
这个是应该在@KafkaListener注解的方法中实现吗?举个例子
点赞
回复2 取消回复
Yuxy 2026年02月07日 17:56
这个是应该在@KafkaListener注解的方法中实现吗?举个例子@派聪明
点赞
回复 取消回复
Yuxy 2026年02月07日 18:10
是的,绝大多数情况下就写在 @KafkaListener 方法中,而且要放在“业务全部成功之后”。 手动提交 offset 的正确姿势是: ****************** = false 在 @KafkaListener 方法中 业务逻辑全部成功后 显式调用 ack.acknowledge()(Spring Kafka 推荐) 或 consumer.commitSync()(低层方式)
这个是应该在@KafkaListener注解的方法中实现吗?举个例子@派聪明
点赞
回复 取消回复
lj1204 2026年02月04日 09:39
引用原文:虽然我们没有显式使用 Guava 的 RateLimiter 做限流,但是通过批量调用的方式做了“变相的限流”——我们会把文本分批,每批 100 条,合并成一个请求发送出去。这样做一方面减少了总的 HTTP 请求数量,另一方面也能尽量降低每秒调用次数,算是一种“成本很低但有效”的优化策略。
@派聪明
1
回复1 取消回复
派聪明 2026年02月04日 09:39
这段文本描述了一种通过**批量调用实现“变相限流”**的策略,其核心思路和优势如下: --- ### **核心策略** 1. **批量合并请求** 将原本需要多次发送的**单条文本请求**(如每条文本单独调用豆包API生成向量)合并为**单次批量请求**,每批包含 **100 条文本**。 - **示例**:原本需要发送 1000 次请求 → 合并为 10 次批量请求(每批 100 条)。 2. **自然降低调用频率** - **减少请求总量**:HTTP 请求数量从 `N` 次降至 `N/100` 次(如 1000 条 → 10 次)。 - **控制 QPS**:假设原本每秒需处理 100 条文本,通过批量调用,实际每秒仅需发送 **1 次 HTTP 请求**(100 条/批),显著降低对下游 API 的瞬时压力。 --- ### **优势分析** | **维度** | **效果** | |------------------|--------------------------------------------------------------------------| | **成本控制** | 减少网络开销和 API 调用次数,降低资源消耗(如连接建立、序列化/反序列化成本)。 | | **限流效果** | 通过批量大小间接控制调用频率,避免触发下游 API 的速率限制(如豆包的 QPS 限制)。 | | **实现简单** | 无需引入额外限流组件(如 Guava RateLimiter),仅通过请求合并实现,开发成本低。 | | **兼容性** | 适用于支持批量输入的 API(如豆包的批量 embedding 接口)。 | --- ### **潜在风险与优化方向** 1. **批处理延迟** - 问题:等待凑满 100 条可能增加单次请求的响应延迟(如需等待 1 秒才凑够一批)。 - 优化:设置**超时机制**(如 500ms 内未满则发送当前批次),平衡延迟与频率。 2. **API 批量限制** - 问题:若下游 API 对单次批量大小有限制(如最大 50 条),需调整批大小。 - 优化:根据 API 文档动态调整批大小(如 50 条/批)。 3. **容错与重试** - 问题:单次批量请求失败会导致整批数据重试(如 100 条全部重传)。 - 优化:**分批重试**(仅失败的部分重新调用)或**支持部分成功**(处理成功条目,重试失败条目)。 --- ### **总结** 该策略通过**批量合并请求**实现了一种**低成本、高兼容的限流方案**,在减少资源消耗的同时自然控制了调用频率。适用于对延迟敏感度不高、但需严格管理下游 API 调用频率的场景。若需更精细的限流控制(如突发流量处理),可结合传统令牌桶算法进一步优化。
1
回复 取消回复
阿白 2026年01月25日 17:56
引用原文:一开始我们实现了最基础的固定大小分块策略,直接把整个文本按照设定好的 chunkSize 切段。这种方式简单粗暴,但存在的问题是:容易在句子中间或者段落中间截断,导致语义残缺,对检索的精度会有影响。 后来我们引入了语义感知分块策略。这个版本会优先尝试按段落进行切割,如果某个段落太长,我们再细化到句子级别。整体上来说,它更尊重语义结构,能让一个 chunk 更自然地保留上下文,对于检索来说准确性提升非常明显。
@派聪明 语义感知分块,每次上传同一文件分块会不一样吗?怎么实现断点续传?
点赞
回复1 取消回复
派聪明 2026年01月25日 17:57
根据参考资料,语义感知分块**每次上传同一文件时,分块结果会完全一致**。以下是具体分析和断点续传的实现机制: --- ### **1. 语义感知分块的确定性** - **分块依据固定**: 语义分块依赖文本的**自然结构**(如段落分隔符 `\n\n`、句子标点符号 `.!?`),这些结构在文件内容中是固定的。只要文件内容不变,分块边界(如段落起始位置、句子结束位置)就不会变化。 - **算法确定性**: 分块逻辑(如优先按段落切分,超长段落再切句子)是纯算法处理,不依赖随机因素,因此同一文件每次分块结果完全一致。 --- ### **2. 断点续传的实现机制** 断点续传的核心是**物理分片管理**(与语义分块无关),具体流程如下: #### **(1) 前端分片上传** - **分片标识**: 文件被切分为固定大小的物理分片(如5MB/片),每个分片上传时携带 `fileMd5`(文件唯一标识)和 `chunkIndex`(分片序号)。 - **存储结构**: 分片在 MinIO 中按 `chunks/{fileMd5}/{chunkIndex}` 存储,确保归属关系明确。 #### **(2) 后端状态跟踪** - **Redis 记录进度**: 每个分片上传成功后,后端在 Redis 中用 **Bitmap** 记录状态(`fileMd5` 为 Key,`chunkIndex` 对应 Bit 位)。例如: ```plaintext Redis Key: "fileMd5_12345" Bitmap: 1101001... (第0/1/3/6...分片已上传) ``` #### **(3) 断点续传流程** 1. **恢复上传时**: 前端携带 `fileMd5` 请求后端查询 Redis,获取已上传的分片列表。 2. **跳过已传分片**: 前端仅上传未完成的分片(Bitmap 中为 `0` 的分片)。 3. **后端核验**: 重新上传时,后端仍会校验分片 MD5,确保数据完整性。 #### **(4) 语义分块不影响续传** - **语义分块是独立阶段**: 语义分块仅在文件**合并完成**后由后台异步任务触发(通过 Kafka 消息**),与上传分片机制完全解耦。 - **分片与语义块无关**: 物理分片(5MB)是上**元,语义块(段落/句子)是文本处理单元,两者边界不同,互不干扰。 --- ### **总结** - **语义分块一致性**:依赖文本自然结构和确定性算法,同一文件结果不变。 - **断点续传**:通过 Redis Bitmap 跟踪物理分片状态,前端仅上传未完成分片,后端核验数据完整性。 - **解耦设计**:上传分片(物理层)与语义分块(逻辑层)分离,互不影响。
点赞
回复 取消回复
阿白 2026年01月25日 16:54
引用原文:然后是访问权限这一块,我们用了一种叫做组织标签的机制。简单理解就是:文件上传时,用户可以指定这个文件是“哪些组织标签”下可见的。比如说“研发部可见”或者“仅自己可见”。如果前端不传这个字段,我们会给它加上一个默认的组织标签——就是这个用户的主组织,避免权限空白。
@派聪明 前端不传**标签,默认**标签是什么?怎么理解
点赞
回复1 取消回复
派聪明 2026年01月25日 16:54
根据参考资料,当用户上传文件时**如果前端未指定**标签**,系统会自动为其添加一个**默认的**标签**,即该用户的主**(用户所属的基础部门)。 ### 具体逻辑解析: 1. **默认值来源** - 系统通过用户的身份认证(JWT解析)获取其 `userId`,并关联其**主**信息**(例如“研发部”、“财务部”等)。 - 若前端未传递**标签字段,后端会直接使用该用户的**主****作为文件的默认可见范围。 2. **设计目的** - **避免权限空白**:防止文件因未设置标签而变成完全公开或完全不可见(需明确权限范围)。 - **符合企业场景**:用户通常默认需在自己的部门内共享文件,除非主动指定更广的权限(如“全公司可见”)。 3. **示例说明** - 用户A的主**是“研发部”,上传文件时未指定标签 → 文件默认仅“研发部”可见。 - 用户B的主**是“市场部”,上传文件时指定标签为“全公司” → 文件对所有人可见,覆盖默认值。 ### 系统实现要点: - **数据库存储**:默认标签与文件元数据(如 `file_upload` 表)一同持久化,确保权限可追溯。 - **权限校验**:下游服务(如文件检索)会根据**标签过滤结果,确保用户仅访问有权限的文件。 > ✅ **总结**:默认**标签是用户的**主****,既保障了权限管理的严谨性,又简化了用户操作,符合企业级应用中“部门隔离”的常见需求。
点赞
回复 取消回复
阿白 2026年01月25日 16:02
引用原文:前端会将这个分片的 MD5 值一块发给后端。后端在收到分片数据之后,会重新算一遍 MD5,对比一下,如果发现数据被破坏了(比如有比特翻转),我们就会直接拒绝这个分片,告诉前端“这个分片坏了,请重传”,保证最终存下来的数据是没问题的。
@派聪明 1.不仅文件有md5,分片也有md5吗? 2.后端是怎么校验分片的?
点赞
回复1 取消回复
派聪明 2026年01月25日 16:03
根据参考资料中的描述,针对你的两个问题,答案如下: --- ### 1. **不仅文件有MD5,分片也有MD5吗?** **是的,分片也有独立的MD5值。** - **前端计算**:在分片上传前,前端会为每个分片单独计算MD5值(即分片内容的哈希值),并在上传请求中携带该MD5值(参考资料中提到的`chunkIndex`和`fileMd5`是文件级别的,而分片MD5是分片级别的校验值)。 - **作用**:用于后端校验分片数据在传输过程中是否损坏(如网络比特翻转导致数据异常)。 --- ### 2. **后端是怎么校验分片的?** 后端通过以下步骤校验分片完整性: 1. **接收分片数据**:后端从请求中获取分片内容和前端传来的分片MD5值。 2. **重新计算MD5**:对收到的分片数据重新计算MD5值。 3. **比对MD5**: - 若后端计算的MD5与前端传来的MD5一致 → 分片数据完整,存入MinIO。 - 若不一致 → 说明分片在传输中损坏,后端拒绝该分片,并返回错误提示(如“分片损坏,请重传”)。 4. **结果处理**: - 成功:记录分片状态到Redis的Bitmap中,等待后续合并。 - 失败:触发前端重传该分片(参考资料中提到前端有重试机制)。 --- ### 补充说明 - **双重校验机制**: - **文件级MD5(fileMd5)**:用于标识整个文件,确保分片属于同一文件(通过`chunks/{fileMd5}/{chunkIndex}`存储分片)。 - **分片级MD5**:确保单个分片数据无损坏。 - **可*性设计**:通过前后端MD5比对,避免因网络问题导致的数据损坏,最终合并的文件才能保证完整性。
点赞
回复 取消回复
阿白 2026年01月25日 11:55
引用原文:等到网络恢复后,前端会带着这个文件的 MD5 去后端的 Redis 里查所有分片的状态,前端拿到分片状态后,在重新上传的时候,就会跳过那些已经上传成功的分片,只上传那些还没传的。这样就避免了重复上传。 当然了,后端在重新上传的时候,也会进行核验。
@派聪明 **续传和正常上传都是调用后端同一个upload接口吗?只是在同一个controller和sevice里面先判断是不是**续传吗?
1
回复1 取消回复
派聪明 2026年01月25日 11:55
根据参考资料描述,**断点续传和正常上传确实调用的是同一个后端接口**,但通过前端传递的参数和后端的逻辑判断区分两种场景。以下是具体实现逻辑: --- ### **1. 接口复用机制** - **统一接口**: 断点续传和正常上传都使用同一个 `upload` 接口(如 `UploadController` 中的 `mergeFile` 方法)。 后端通过 **前端传递的参数** 判断当前操作类型: - **正常上传**:前端直接发送文件分片数据(包含 `chunkIndex`、分片内容等)。 - **断点续传**:前端额外携带 `fileMd5` 参数,并先查询分片状态,仅上传缺失的分片。 --- ### **2. 后端区分逻辑** #### **(1) 正常上传流程** 1. 前端首次上传时,生成文件唯一标识 `fileMd5`(通过文件内容计算)。 2. 请求接口时携带: - `fileMd5`(文件唯一标识) - `chunkIndex`(当前分片序号) - 分片数据 3. 后端处理: - 存储分片到 MinIO(路径:`chunks/{fileMd5}/{chunkIndex}`)。 - 在 Redis 中用 Bitmap 记录该分片上传状态(对应 bit 位置为 1)。 - 首次上传时,将文件元信息(文件名、大小、上传者等)存入 MySQL。 #### **(2) 断点续传流程** 1. **网络恢复后**,前端携带 `fileMd5` 查询接口(如 `/api/upload/status?fileMd5=xxx`)。 2. 后端查询 Redis 中该文件的 Bitmap,返回已上传的分片列表。 3. 前端仅上传 **缺失的分片**(携带 `fileMd5` + `chunkIndex` + 分片数据)。 4. 后端处理: - **校验分片**:**分片是否已存在(通过 Redis Bitmap)。 - **重复上传处理**:若分片已存在,直接跳过(避免重复存储)。 - **新分片处理**:存储到 MinIO,并更新 Redis 状态。 --- ### **3. 关键设计细节** - **参数驱动区分**: 通过 `fileMd5` 参数是否存在判断是否为断点续传: - **有 `fileMd5`**:可能是断点续传(需先查状态)或正常上传(首次发送分片)。 - **无 `fileMd5`**:视为无效请求(正常上传必须携带 `fileMd5`)。 - **后端核验机制**: 即使前端声称是断点续传,后端仍需: 1. 验证 `fileMd5` 是否对应有效文件(MySQL 中存在元数据)。 2. **分片完整性(如分片 MD5 校验)。 3. 防止重复上传(Redis Bitmap 状态校验)。 --- ### **4. 代码逻辑示例** ```java // 伪代码:后端接口处理逻辑 @PostMapping("/upload") public ResponseEntity<?> uploadChunk( @RequestParam("fileMd5") String fileMd5, @RequestParam("chunkIndex") int chunkIndex, @RequestParam("chunk") MultipartFile chunk ) { // 1. **文件元数据是否存在(正常上传时首次创建) FileMetadata metadata = fileUploadService.getMetadata(fileMd5); if (metadata == null && !isFirstChunk(chunkIndex)) { return ResponseEntity.badRequest().body("文件元数据不存在"); } // 2. **分片是否已上传(断点续传校验) if (redisService.isChunkUploaded(fileMd5, chunkIndex)) { return *****************().body("分片已存在,跳过"); } // 3. 存储分片并更新状态 minioService.uploadChunk(fileMd5, chunkIndex, chunk); redisService.markChunkUploaded(fileMd5, chunkIndex); // 4. 首次上传时创建元数据 if (metadata == null) { fileUploadService.createMetadata(fileMd5, chunk.getOriginalFilename(), ...); } return *****************().body("分片上传成功"); } ``` --- ### **5. 总结** - **接口复用**:断点续传和正常上传共用同一个 `upload` 接口,通过 `fileMd5` 和分片状态区分场景。 - **后端校验**: - 断点续传时,后端会校验分片是否已存在(Redis Bitmap),避免重复上传。 - 所有上传均需验证文件元数据完整性(MySQL 记录)。 - **优势**: 保持接口简洁性,减少代码冗余,同时通过参数和状态管理实现逻辑分离。 这种设计既保证了接口的统一性,又通过参数和状态校验实现了断点续传的可*性,符合参考资料中的实现逻辑。
点赞
回复 取消回复
阿白 2026年01月25日 11:46
引用原文:对于大文件,派聪明采用的是‘分片上传 + 断点续传’的方式。我们会在前端先把大文件切成小的分片,比如 5MB 一块,然后并发地上传到后端。后端每收到一个分片,就存到 MinIO 中,同时会用 Redis 的 bitmap 去记录哪些分片已经上传成功。这样的好处就是,即使上传过程中断了,前端可以根据 Redis 状态判断哪些分片已经上传,不用从头开始,用户体验会比较好。
@派聪明 1.上传文件,文件会有上传进度条吗? 2.上传到一半停止上传,然后怎么继续上传呢? 3.前端上传文件是什么逻辑?
点赞
回复1 取消回复
派聪明 2026年01月25日 11:47
根据参考资料中描述的派聪明系统文件上传机制,针对你的三个问题解答如下: --- ### 1. **上传文件会有进度条吗?** **是的,系统会显示上传进度条。** - **实现逻辑**:前端将大文件切分为多个分片(如5MB/片)并发上传。后端每收到一个分片,会通过 **Redis的Bitmap** 记录该分片的上传状态(`1`表示成功)。 - **进度计算**:前端通过查询Redis中该文件的Bitmap状态,实时计算已完成分片数/总分片数,动态更新进度条。例如:100个分片已上传30个,进度即显示为30%。 - **优势**:用户可实时查看进度,且断网续传时无需重新计算(Redis状态保留)。 --- ### 2. **上传到一半停止,如何继续上传?** **通过断点续传机制实现,无需重新上传整个文件。** - **步骤**: 1. **前端发起续传请求**:携带文件的`fileMd5`(唯一标识)请求后端。 2. **后端查询状态**:后端根据`fileMd5`在Redis的Bitmap中查询哪些分片已上传(`bit=1`)。 3. **前端补传缺失分片**:前端仅上传未成功的分片(`bit=0`的部分),跳过已上传的分片。 4. **后端核验**:后端接收新分片时,会校验分片MD5是否损坏,确保数据完整性。 - **效果**:用户只需上传剩余分片,大幅节省时间和流量。 --- ### 3. **前端上传文件的核心逻辑** 前端实现分片上传的核心流程如下: 1. **文件切割**: - 使用`**********()`方法将大文件切分为固定大小的分片(如5MB)。 - 计算整个文件的`fileMd5`(通过`spark-md5`等库),作为分片的归属标识。 2. **并发上传**: - 使用`***********()`或类似机制并发上传分片(避免阻塞UI)。 - 每个分片请求携带: - 分片数据(`chunk`) - `fileMd5`(文件唯一标识) - `chunkIndex`(分片顺序索引) 3. **断点续传支持**: - 上传中断后,前端重新请求后端获取`fileMd5`对应的Bitmap状态。 - 根据Bitmap结果筛选未上传的分片,仅补传缺失部分。 4. **合并****: - 所有分片上传完成后,前端调用后端`merge`接口,触发MinIO合并分片。 --- ### 关键技术点总结 | **环节** | **技术方案** | **作用** | |----------------|----------------------------------|---------------------------------------| | **分片存储** | MinIO对象存储 | 高性能存储分片数据,支持服务端合并 | | **状态跟踪** | Redis Bitmap | 高效记录分片上传状态(内存占用极低) | | **断点续传** | `fileMd5` + `chunkIndex` | 精准定位缺失分片,避免重复上传 | | **数据完整性** | 分片MD5校验 | 防止网络传输导致的数据损坏 | 此方案通过分片、状态追踪、并发上传和断点续传,实现了大文件的高效、可*上传,显著提升用户体验。
点赞
回复 取消回复
阿白 2026年01月25日 11:31
引用原文:? 对于大文件,派聪明采用的是‘分片上传 + 断点续传’的方式。我们会在前端先把大文件切成小的分片,比如 5MB 一块,然后并发地上传到后端。后端每收到一个分片,就存到 MinIO 中,同时会用 Redis 的 bitmap 去记录哪些分片已经上传成功。这样的好处就是,即使上传过程中断了,前端可以根据 Redis 状态判断哪些分片已经上传,不用从头开始,用户体验会比较好。
@派聪明 1.两次上传同一文件,分片的时候划分是一样的吗? 2.**续传是什么场景?
点赞
回复1 取消回复
派聪明 2026年01月25日 11:32
根据参考资料中的描述,针对您的两个问题解答如下: --- ### **1. 两次上传同一文件,分片划分是否一致?** **是的,分片划分完全一致。** - **核心依据**:前端在首次上传前会计算文件的 **MD5 哈希值**(`fileMd5`),作为文件的唯一标识。 - **分片逻辑**:分片大小(如 5MB)和数量由文件大小和分片策略决定,而 `fileMd5` 相同的文件,其分片数量和索引(`chunkIndex`)必然相同。 - **实现方式**: - 前端再次上传相同文件时,仍会生成相同的 `fileMd5` 和分片结构(`chunks/{fileMd5}/{chunkIndex}`)。 - 后端通过 `fileMd5` 关联分片,确保同一文件的分片始终归组到同一目录下,便于后续合并。 > ✅ **关键点**:**文件内容不变 → MD5 不变 → 分片划分一致**,为断点续传提供基础。 --- ### **2. 断点续传的应用场景是什么?** 断点续传主要解决 **上传过程中意外中断** 的问题,具体场景包括: - **网络中断**:切换网络、网络波动、设备休眠导致连接断开。 - **用户主动暂停**:用户手动中止上传。 - **系统异常**:浏览器崩溃、设备**、服务端临时故障等。 - **分片失败**:单个分片因校验失败(如 MD5 不匹配)需重传。 **实现机制**: 1. **状态记录**:后端用 **Redis 的 Bitmap** 记录每个分片的上传状态(`fileMd5` 为 Key,`chunkIndex` 为 Bit 位置)。 2. **恢复逻辑**: - 网络恢复后,前端携带 `fileMd5` 查询 Redis,获取已上传的分片列表。 - 前端跳过已成功分片,仅上传剩余分片(如 200 个分片已传 150 个,只需重传后 50 个)。 3. **校验与重试**: - 后端对重传分片进行 MD5 校验,确保数据完整性。 - 失败分片自动重试(最多 3 次),避免因瞬时故障导致上传失败。 > ✅ **核心价值**:**避免重复上传**,大幅提升大文件上传的容错性和用户体验。 --- ### 总结 - **分片一致性**:依赖文件 MD5 哈希,确保相同文件分片划分固定。 - **断点续传**:通过 Redis 记录分片状态,在网络中断/异常时恢复上传,减少重复传输成本。
点赞
回复 取消回复

目录