1.
目标:支持大量 iOS 客户端并发上传几十 MB 到数 GB 文件,保证可恢复、低资源占用、可扩展与可观测。
要点:客户端直传到对象存储(减少服务器带宽)、使用断点续传协议(tus 或 multipart)、预签名 URL、上传会话管理、限流与队列、校验与回调。
2.
1) 使用 URLSession 背景会话(URLSessionConfiguration.background),保证应用在后台也能上传。
2) 将文件切片(chunk)为 5MB-50MB 区间,避免单片过大导致重传成本高。
3) 每个分片获取服务器预签名 PUT/POST URL(短有效期),并用 PUT 直接上传到对象存储;上传成功后通知后台完成该片。
4) 使用 Content-Range 或 tus 协议记录偏移量,保存本地断点信息(offset、uploadId、已完成分片列表),启动时优先从本地恢复。
5) 并发控制:单设备并发上传并发数 2-4,避免占满移动网络与移动端 CPU。并发任务失败按指数退避重试(如 500、502、503 情况)。
3.
1) /upload/init:客户端请求,后端生成 uploadId、分片大小、总片数、并返回每片的预签名 URL(或返回模板让客户端逐片申请)。保存会话状态到 Redis(轻量)或数据库。
2) /upload/commit:客户端最后一片上传完成后调用,后端校验所有分片完整并触发合并任务(若采用对象存储的 Multipart Complete API,则发起 Complete)。
3) /upload/status:返回已完成分片列表,供客户端断点续传使用。接口需支持分页与快速查询(用 Redis bitset 或 Bloom filter 优化)。
4.
1) 使用 S3/GCS/Azure Blob 的 Multipart Upload 或 S3-compatible 存储,利用服务端 Complete API 进行合并。
2) 直传采用预签名 URL,服务器只做鉴权与签名,显著降低带宽和服务器负载。
3) 对于需加密/防篡改的场景,要求客户端上传前计算分片 checksum(例如 SHA256),并在 Complete 时校验每片 digest。
5.
1) 前端负载均衡(Nginx/ALB):配置长连接复用、增加 client_max_body_size、合理的 timeout(避免过短中断大文件上传)。
2) 使用 API Gateway 进行鉴权并限流(按用户/IP/应用 Key)。
3) 后端采用无状态微服务 + Redis 做会话缓存,结合自动伸缩(Kubernetes HPA 或云自动扩缩容),并在入口处引入令牌桶或漏桶限速。
6.
1) 所有 upload 操作需设计为幂等:每个分片带 uploadId + partNumber,重复请求覆盖相同 part。
2) 客户端与服务端都应实现重试与指数退避,服务器端对短时错误返回明确状态码(429、503)并在响应头提供 Retry-After。
3) 对于合并失败,保存失败记录并异步重试(使用消息队列如 SQS/Kafka);超过阈值将告警并将 uploadId 标记为需人工介入。
7.
1) 打点:上传成功率、分片失败率、平均上传时延、带宽使用、后端错误率。使用 Prometheus + Grafana。
2) 告警策略:分片失败率持续上升、Complete 失败、对象存储 5xx 增多触发 PagerDuty。
3) 运维工具:提供手工合并/回滚接口、列出未完成会话并能触发补偿任务。
8.
1) 鉴权采用短期签名、OAuth2 或自定义 token,避免长期凭证泄露。
2) 校验:上传后校验整体 checksum,防止传输损坏。对于敏感数据启用服务器端加密或客户端加密。
3) 成本优化:启用对象存储生命周期规则(冷归档)、尽量使用直传降低出站带宽成本。
9.
问:如何为 iOS 客户端设定分片大小与并发数?
答:一般分片 5MB-50MB,过小增加请求次数,过大重试成本高。并发数建议单设备 2-4;服务端可按用户/租户限制并发总量,结合网络状况动态调整(测速后选择分片/并发)。
10.
问:Complete Multipart 失败或部分分片损坏如何处理?
答:设计异步补偿流程:失败写入队列,后台重试(限次)并通知运维。保持原始分片至少若干小时至几天(根据 SLA),便于重试或人工检查。同时记录每片 checksum 以便发现损坏。
11.
问:在突发并发(例如活动期间)如何防止系统崩溃?
答:实施多层限流(网关/负载均衡/服务端令牌桶)、优先级队列、熔断器(Circuit Breaker)与降级策略(例如临时只允许小文件或延迟处理大文件),并提前做容量预热与负载测试。