Lambda下载第三方媒体后上传S3,文件损坏问题求助
问题排查思路与解决方案
一、先从下载环节找问题
- 校验文件完整性:下载完成后,把本地文件的MD5/SHA256哈希值,和Meta WhatsApp API返回的媒体资源哈希(API响应里的
sha256字段)做对比。如果哈希对不上,说明是下载过程中数据丢包或篡改,这时候得重试下载。 - 调整httpx流式下载参数:
iter_raw()默认的块大小可能太小,试试指定chunk_size=1024*1024(1MB块),减少频繁写入磁盘的开销。另外,给请求头加Accept-Encoding: identity,强制Meta API不返回压缩后的内容——如果API自动压缩了二进制文件,你直接写入会导致文件损坏。 - 确保临时文件写入完全:Lambda的/tmp目录有缓存机制,写完chunk后,在上传前手动调用
temp_file.flush()和os.fsync(temp_file.fileno()),把内存里的缓存强制刷到磁盘,避免缓存没同步就上传,导致文件内容不全。
二、跳过临时文件,直接流式传S3
多一次磁盘读写就多一次出错的可能,直接把httpx的响应流传给S3,省去临时文件步骤:
import boto3 import httpx s3 = boto3.resource('s3') MY_BUCKET = "你的桶名" with httpx.stream("GET", get_media_url["url"], headers=META_API_HEADERS) as get_media_file: s3.Bucket(MY_BUCKET).upload_fileobj( get_media_file.raw, f"{sender}/{media_id}.ogg", ExtraArgs={"ContentType": "audio/ogg"} )
同时显式设置ContentType,避免S3自动识别文件类型出错。
三、加重试和错误处理
- 下载重试:第三方API网络波动很常见,用重试逻辑(比如自己写循环或者用
tenacity库),当哈希校验失败或下载报错时,重试2-3次。 - 上传异常捕获:给S3上传代码加try-except块,捕获
boto3.exceptions.ClientError,如果上传失败就重试,同时把错误信息打日志,方便定位问题。
四、加日志调试
- 下载时记录每个chunk的大小,下载完成后记录本地文件的实际大小,和Meta API返回的
file_size对比。如果大小一致但哈希不对,是传输中数据篡改;如果大小不一致,就是下载没完成。 - 本地模拟Lambda环境,用相同的请求参数下载文件,对比本地文件和S3上的文件,看看是不是Lambda环境的特殊问题。
内容的提问来源于stack exchange,提问作者Croves
相关产品推荐
相关产品推荐

