主备切换导致文件上传中断的本质是服务地址、连接状态或会话上下文突变,引发tcp重置、断点元数据丢失或客户端未感知新主节点,需从协议层(如分片上传、重定向网关)、服务端(共享存储断点元数据)、客户端(主动探测、状态同步)协同解决。

主备切换过程中文件上传中断,本质是服务地址、连接状态或会话上下文突然变更,导致正在传输的TCP连接被重置、断点续传元数据丢失、或客户端未及时感知新主节点。这不是单纯重试能解决的问题,需从协议层、客户端行为、服务端协同三方面入手。
确保上传协议支持无状态与连接漂移
HTTP/HTTPS 上传默认依赖长连接和会话绑定,在主备切换瞬间容易触发 Connection reset 或 502/503 错误。应优先采用以下方式:
- 使用带重定向能力的上传网关:例如 Nginx + Lua 或 API 网关统一暴露 /upload 接口,后端自动路由到当前主节点,上传过程对客户端透明
- 避免直接连具体IP或域名:客户端不应硬编码主库地址,而应通过 VIP、DNS 轮询或服务发现(如 Nacos、Consul)获取实时可用节点
- 对大文件上传启用分片上传协议(如 TUS、S3 Multipart Upload),每个分片请求独立鉴权与路由,单个失败不影响整体
服务端同步断点元数据到共享存储
断点续传依赖“已传多少字节”的状态记录。若该状态仅存在原主节点内存或本地磁盘,切换后新主无法识别进度,只能从头开始。
- 将上传上下文(file_id、offset、part_id、签名等)存入 Redis 或数据库,且主备实时同步(如 Redis Cluster 或双写MySQL)
- 上传初始化时生成唯一 upload_id,后续所有分片请求携带该 ID,服务端统一查共享存储确认进度
- 主备切换完成后的首次请求,自动触发一次 status 查询,返回当前 offset,客户端据此调整读取位置
客户端主动适配切换事件
客户端不能被动等待超时,而应具备探测能力与快速回退逻辑:
- 监听 HTTP 响应码:收到 502/503/404 时,暂停上传,调用 /upload/status?upload_id=xxx 接口刷新状态,再决定继续或重试
- 设置合理的连接与读取超时(如 connectTimeout=5s, readTimeout=30s),避免卡死在旧连接上
- 上传任务中嵌入心跳探针:每 10 秒向 /health 或 /status 发起轻量请求,若连续两次失败,主动触发重连与状态同步
规避强依赖主节点的中间状态
有些上传流程会在主节点临时写入校验文件、锁标记或预分配空间,这些操作在切换后极易不一致。
- 禁用基于本地文件系统的临时缓存(如阿里云盘的 Partitions 目录),改用对象存储(OSS/S3)作为中转,天然支持跨节点访问
- 上传校验改用客户端计算 MD5/SHA256 后上传,服务端只做摘要比对,不依赖中间文件完整性
- 合并阶段(所有分片上传完成后)才由主节点执行最终落盘,此时切换已稳定,可加分布式锁保障幂等











