客户端的循环冗余校验和服务端不一致,可以上传成功
排查
出现类似问题,需要先收集信息,经常发生在 Java sdk 上传的过程中。
- requestID 出现 checksum 不一致的情况一定会伴随有 requestID 信息。
- 上传方式是通过 SDK 还是自己调 API 上传,需要明确 SDK 的版本信息。
- 问题能否稳定复现,能复现最好提供网络抓包便于问题分析。
- tcpdump -i <出口网卡> -s0 host -w checksum.pcap
分析:
- 收集到 requestID 后,先升级到阿里云确认是否已经上传成功,一般 checksum 不一致并不会导致上传失败, checksum 是对文件进行循环冗余计算的方法,和 MD5 不一样,如果 MD5 不一致,文件上传一定失败。如果日志记录上传成功,可以校验文件的 MD5 是否一致,如果一致的话请忽略 checksum 不一致的情况。
- 出现 checksum 不一致的情况和网络以及系统主机都有关系,先通过网络抓包分析下,客户端发起 request header 中的 crc64 是否和 requestID 查到的 crc64,如果一致的话说明用户上传网络传输中被篡改了,如果不一致的话说明客户本地写入到内存后就出现问题。
- 如果用户本地计算写入到内存和服务端的不一致,需要用户在本地代码中进行 debug ,在上传请求发起前,先打印出 crc64 记录到本地,看看与 SDK 计算的是否一致,确保文件在上传前不要有其他进行在占用,或者读写。如果本地计算的 crc64 和 SDK 一致 说明不是计算问题,而是写入到内存后出现了问题,说明是客户端的系统导致的异常。
建议:
- 如果出现 checksum 不一致,但是文件 MD5 一致的话客户可以将 crc64 关掉,替换成 MD5 的校验方式,在 header 增加 Content-MD5 头,MD5 值要全部大写,然后在 base64 编码。
- Java SDK 关闭 crc64 的方法
关闭 crc 的方法如下:
https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.702.5bb84b4eKVgJfk
String endpoint = "<yourEndpoint>";
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
ClientConfiguration conf = new ClientConfiguration();
conf.setCrcCheckEnabled(false);
// 创建OSSClient实例。
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
- 使用 https 协议上传,将 endpoint 协议头改为 https 即可,看下更换为 https 协议后问题是否还能复现。