本文介绍如何处理在使用OSS SDK时可能出现的网络超时问题。

问题现象

OSS SDK在使用过程中出现的较典型的问题是使用SDK联网过程中出现超时,且在上传过程中提示ConnectionTimeOut的错误,比较影响用户使用体验。

问题排查

由于该问题无法复现,现列举以下可能的原因进行逐一排查,以解决OSS SDK的网络超时问题。

  1. 网络环境

    分析网络路径:

    手机/PC --- 运营商网络 --- OSS Server

    用户所在的网络环境可能处在运营商网络边缘节点,向运营商网络请求成功率比较低。可以利用CDN的边缘加速节点,减少手机/PC网络对运营商网络的依赖。具体链路如下:

    手机/PC -- CDN就近节点 -- 运营商网络 -- OSS Server

    如果问题没有完全解决,仍有ConnectionTimeOut的错误提示,请查看网络配置的分析。

  2. 网络配置

    以下代码为具体的超时错误信息:

    "ConnectionTimeoutError&errormsg=Failed to upload some parts with error: ConnectionTimeoutError: Connect timeout for 60000ms, PUT https://***.oss-cn-hangzhou.aliyuncs.com/***/***/***.mp4?partNumber=2&uploadId=*** -2 (connected: false, keepalive socket: false)headers: {} part_num: 2

    从错误信息中可以得出如下结论 :

    • 超过60s没有收到服务器的返回信息而断开连接。
    • 分析CDN提供的日志,超时的主要原因是分片还没上传成功,连接就已经断开。
    • 如果上传的文件较大,在弱网络环境下,客户端/PC端发送的请求迟迟得不到OSS服务器的响应。

    综合以上分析过程,现推荐以下几种解决方案:

    • 上传方式采用分片断点上传,每个分片的大小不超过1MB。
    • 添加重传机制,保证某一个分片上传失败后还可以继续上传。
    • 增大超时时间。
    //js sdk 分片断点上传示例代码
    
    let retryCount = 0;
    let retryCountMax = 3;
    ...
    const uploadFile = function uploadFile(client) {
      if (!uploadFileClient || Object.keys(uploadFileClient).length === 0) {
        uploadFileClient = client;
      }
      ...
    
      console.log(`${file.name} => ${key}`);
      const options = {
        progress,
        partSize: 1000 * 1024,//设置分片大小
        timeout: 120000,//设置超时时间
      };
      if (currentCheckpoint) {
        options.checkpoint = currentCheckpoint;
      }
      return uploadFileClient.multipartUpload(key, file, options).then((res) => {
        console.log('upload success: %j', res);
        currentCheckpoint = null;
        uploadFileClient = null;
      }).catch((err) => {
        if (uploadFileClient && uploadFileClient.isCancel()) {
          console.log('stop-upload!');
        } else {
          console.error(err);
          //retry
          if (retryCount < retryCountMax){
              retryCount++;
              console.error("retryCount : " + retryCount);
              uploadFile('');
          }
        }
      });
    };

总结

如果通过标准OSS访问域名(例如oss-cn-hangzhou.aliyuncs.com)访问OSS的数据,且这是通过运营商网络对OSS进行访问,由于网络环境的复杂性,例如在一些弱网络环境下或网络不稳定的情况,就会在上传过程中遇到ConnectionTimeOut的网络错误。可以尝试通过以下方式来解决:

  • 采用分片断点上传,每个分片的大小不要超过1MB,也不要小于100KB。
    说明 OSS服务器不接受小于100KB大小的分片。
  • 添加重传机制,保证某一个分片上传失败后还可以继续上传。
    说明 Android/iOS SDK中已经默认开启, 不需要额外配置。
  • 增大超时时间。
  • 通过CDN全站加速服务来提升OSS传输。