基础排查
一、
上传 OSS 出现慢的场景,OSS 会返回一个 requestID 属性,请保留这个 requestID 这是 OSS 所有信息的查询入口,升级阿里云时可以快速定位问题,如果上传超时的话时没有这个属性的。 requestID 可以通过抓包获取到,也可以在代码中解析 OSS 的返回 http result 结果获得。
二、
客户端在上传 OSS 时用的内网的地址还是公网的 OSS 地址,如果使用了阿里云主机服务,并且和 OSS 是同一个 region ,强烈推荐使用 internal 内网地址操作 OSS 这能大大提升你的请求速度。OSS 提供的域名可以参考
https://help.aliyun.com/document_detail/31837.html?spm=a2c4g.11186623.6.571.4dcd2841C29fHi
三、
如果走公网上传 OSS ,速度无法保证,排查需要结合多个网络测试命令,比如常用ping -c 50 -i 0.01 -s 1024 <OSS 公网域名>
mar <OSS 公网域名>
traceroute <OSS 公网域名>
,如下测试客户端的网络出口也不是很稳定,需要多次的测试。
四、
排除客户端出口带宽是否被打满,可以通过 iftop
看下客户端的出口流量。
五、
etstat 查看下主机的 TCP 链接是否被打高
六、
客户端的上传代码读取的是本地文件还是网络流,如果是读取的网络流然后上传到 OSS ,那读文件的时间也会影响到上传时间。建议用本地文件先测试。
七、
客户端的代码是否开启过 crc64 ,开启这个功能对上传的性能影响比较大,开启 crc 后,要在本地先对文件循环冗余校验完后,在开始上传,很消耗性能。
"看病" 对号入座,按照上面描述的分成多个问题进行描述,基本都是上传延迟的问题。
案例:开启 crc64 上传速度下降
该病例,使用 ossutil 工具对比 OSS 的 SDK 上传速度比 osstuil 慢几十倍。
- 通过截图也能看出来确实慢,但是 SDK 即使代码写的再差也不能如此地步。
- 翻阅代码中发现 OSS SDK 在初始化 ossclient 时开启了 crc64 ,关闭后性能直线上升,回复到正常状态,秒传。
auth = oss2.Auth('AK', 'SK')
bucket = oss2.Bucket(auth, 'endpoint', 'bucket',enable_crc=False)
结论:
如果使用 OSS SDK 时建议关闭掉 crc64 ,可以在请求头中增加 Content-MD5 的方式用 MD5 替换 crc64 ,性能更快。
案例:调用 JAVA SDK 上传打印出的时间判断处理很慢
分析:
通过 JAVA 2.8.3 版本的上传接口 PutObjectResult putObject(String bucketName, String key, InputStream input) 上传文件到 OSS ,通过打印前后的系统时间发现每次上传都要几十秒,但是通过 requestID 和抓包的结果都很快。
通过完成的抓包,可以看到网络传输开始到结束的时间非常短,物理的传输时间都很短,证明确实很快就完成上传的操作,但为什么打印的时间差和抓包有这么大差距,需要看下客户端的代码。发现客户端的代码再调用 putobject 时传入的文件是一个网络流,通过公网去读源文件,代码 debug 发现时间整体卡在了读的延迟上,于是更换了本地文件测试后发现秒传。
结论:
建议出现这类问题先抓包看下实际的物理传输是不是真的慢,还仅是自己打印的时间慢而已。
案例:教学作业大量上传超时
分析:
第一个问题:客户端时再内蒙古,OSS 再杭州,通过公网上传 OSS,在学校内部上传作业失败率很高,但是在校外上传失败率明显下降。日志报链接失败。
ossupload by all localcatch, filepath:/storage/emued/0/Homrk/com.identhomework/temp0/1539238757673.JPEG,ex:Failed to connect to /124.160.145.44:80
[ErrorMessage]: Failed to connect to /124.160.145.44:80,time:2018-10-11 14:56
第二个问题:客户端网络内无法解析公网域名。
第二个问题比较好解决,客户端的 DNS 服务出现问题导致解析失败,或者 DNS 请求超时无法解析出域名。第一个问题我们就要用上述的基础排查一步步看
- 排查到 ping 时就发现客户端的网络比较差,丢包率达到了 6% ,这种问题肯定需要在客户端进行抓包分析。
- 通过抓包发现客户端的网络丢包很高,同时出现了很多乱序,只截图了部分的抓包信息。通常都知道少量的乱序没有关系,但是大量的乱序报文会造成重传,而且频繁的丢包,也会导致不停的重传。
结论:
综合现象来看当客户端由学校转移到家里后失败率就下降,学校的网络避免不了嫌疑,但是由于一致没有抓包链接失败的包,只能从网络的角度分析,客户端的弱网导致了链接失败超时。此类问题只能通过抓现象包来进行分析,遇到这类问题第一时间抓包保留现场。
案例: PutObject 写入超时
分析:
- 客户端时用的 webDav 工具上传到 OSS ,上传时会直接出现机器负载高的情况。这种情况可以先使用阿里云的 ossutil 工具,这个性能非常好,支持并发、断点、分片上传。https://help.aliyun.com/document_detail/44075.html?spm=a2c4g.11174283.6.1256.18687da2tNqG1T
- 如果替换 ossutil 还出现上传 502 的话,就必须要在客户端抓包分析,在此之前先将文章开始的基础排查做一遍。`
案例:跨国传输链接超时
出现这种跨国传输超时,要先在本地抓包,判断是否被国际链路出口封堵导致,一般跨国的 OSS 传输建议购买全球加速 CDN 的方式来做,或者使用阿里云的高速通道和专线。
案例:客户端突发大量上传时间过长
分析:
客户端先尝试开始的基础排查,先确定客户端的网络是稳定的,如果无法解决后,第一时间获取到上传时间过长的 requestID 或者抓包升级到阿里云。
案例:SDK 上传打印时间很长
通过 SDK 上传小文件到 OSS ,自己代码中调用时间打印发现超过 20s
分析:
出现这种问题,先在本地部署个抓包看下是否真的上传有延迟,该案例是程序问题, SDK 再读取文件是通过网络流读取,这部分时间也算到 SDK 的上传时间内。导致打印的时间过长,切换到本地文件测试后时间恢复正常。
案例:Node.js 上传超时 socketTimeout
2018-10-26 10:06:05.962 nodejs.ResponseErrorException: ResponseError: socket hang up, GET http://prod33.vpc100-oss-cn-beijing.aliyuncs.com/webpack-hot-middleware/-/webpack-hot-middleware-2.24.3.tgz -1 (connected: true, keepalive socket: true, agent status: {"createSocketCount":3436,"createSocketErrorCount":0,"closeSocketCount":3433,"errorSocketCount":0,"timeoutSocketCount":58,"requestCount":3520,"freeSockets":{},"sockets":{"prod33.vpc100-oss-cn-beijing.aliyuncs.com:80:":3},"requests":{}}, socketHandledRequests: 2, socketHandledResponses: 1)
headers: {}
2018-10-26 10:46:15.042 nodejs.ResponseErrorException: ResponseError: socket hang up, GET http://pro-rd-cnpm.vpc100-oss-cn-beijing.aliyuncs.com/is-binary-path/-/is-binary-path-1.0.1.tgz -1 (connected: true, keepalive socket: true, agent status: {"createSocketCount":633,"createSocketErrorCount":0,"closeSocketCount":632,"errorSocketCount":0,"timeoutSocketCount":1,"requestCount":632,"freeSockets":{},"sockets":{"pro-rd-cnpm.vpc100-oss-cn-beijing.aliyuncs.com:80:":1},"requests":{}}, socketHandledRequests: 2, socketHandledResponses: 1)
2018-10-26 10:46:15.042 nodejs.ResponseErrorException: ResponseError: socket hang up, GET http://pro-rd-cnpm.vpc100-oss-cn-beijing.aliyuncs.com/is-binary-path/-/is-binary-path-1.0.1.tgz -1 (connected: true, keepalive socket: true, agent status: {"createSocketCount":633,"createSocketErrorCount":0,"closeSocketCount":632,"errorSocketCount":0,"timeoutSocketCount":1,"requestCount":632,"freeSockets":{},"sockets":{"pro-rd-cnpm.vpc100-oss-cn-beijing.aliyuncs.com:80:":1},"requests":{}}, socketHandledRequests: 2, socketHandledResponses: 1)
headers: {}
分析:
- 通过初始的报错信息可以知道客户端是 socket 建联失败导超时断开,请求没有到 OSS ,提供的日志表象可以看出请求并发越高,本地的 socket 超时越多,由此判断是客户的并发高导致出现了瓶颈引起的 socket 超时。
- 通过辅助的抓包发现,客户端是 keepalive + 高并发的场景,如果客户端长期不释放掉 TCP 链接书,很容易将客户端的协议栈打满,造成 socket 建联超时。
结论:
- 自己的程序代码中,将 keepalive 请求缩短,并且客户端的程序中要在请求完成后主动示范掉长链接回收资源。
- ss -la | grep -i wait 看下并发高的时候主机的 wait 数量是不是很高,如果大量的 wait 无法释放也回占用主机的资源。
- ss 看下主机的链接数有没有超时 ulimit 的限制。
- 并发高的时间,主机出口带宽是否被占满。
- 程序上建议增加一个 sockettimeout 的容错,设置合理的间隔时间然后重试下。
案例:解析失败导致超时
2018/10/24 14:03:47 hlg_matting_PreF (pid=15693)(error): parseUrl2Image.hpp(186), read_element: image_url_service connect fail: Could not resolve host: disanzhe.oss-cn-hangzhou-internal.aliyuncs.com, url: https://disanzhe.oss-cn-hangzhou-internal.aliyuncs.com/mattings/0/images/20181024-135354-f5ee.jpg
通过报错可以看出客户端发出的 DNS 请求都失败,导致的请求 OSS 超时,这种问题,直接看下 DNS 服务是否异常,或者 DNS 出现异常、限流等问题,并不是 OSS 故障。
案例:驻云客户端上传 OSS 错误
问题:
客户端通过驻云工具上传 OSS 同一个 bucket 不通 prefix,经常出现 curl error 的情况,由于驻云客户端不是阿里云开发的,所以错误定义并不是很清晰,逐一排查。
分析:
- 看下客户端工具的并发线程设置。
- 客户端的出口带宽是否有限制。
- 替换下 OSS 可靠的工具 ossutil,或者 ossbrower 再测试一下。
结果替换为 ossbrower 文件可以正常上传。