性能调优-Java SDK 调优-阿里云开发者社区

开发者社区> 阿里云支持与服务> 正文

性能调优-Java SDK 调优

简介: OSS 公网下的传输性能调优

环境准备

  • 使用 Java 1.8 及以上版本。
  • 查看版本
    执行命令java -version查看Java版本

下载SDK

  • 直接通过 GitHub 下载
  • 安装SDK,在Maven项目中加入依赖项(推荐方式)
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>

初始化的参数设置

日志调优参数

一般情况下不会开启日志功能,很多用户都是开启日志 log4j 后写变慢了;网上有很多关闭的方法可以找下开源的处理文档关闭掉,如果用户配置了log4j的属性文件, 需要在那个属性文件里 配置 oss的 日志级别 ;

image.png

超时参数设置

弱网的环境下最好将超时时间设置长一些,增加重试次数,避免上传失败。

// 创建ClientConfiguration。ClientConfiguration是OSSClient的配置类,可配置代理、连接超时、最大连接数等参数。
ClientConfiguration conf = new ClientConfiguration();

// 设置OSSClient允许打开的最大HTTP连接数,默认为1024个。
conf.setMaxConnections(2048);
// 设置Socket层传输数据的超时时间,默认为50000毫秒。
conf.setSocketTimeout(10000);
// 设置建立连接的超时时间,默认为50000毫秒。
conf.setConnectionTimeout(10000);
// 设置从连接池中获取连接的超时时间(单位:毫秒),默认不超时。
conf.setConnectionRequestTimeout(1000);
// 设置连接空闲超时时间。超时则关闭连接,默认为60000毫秒。
conf.setIdleConnectionTime(10000);
// 设置失败请求重试次数,默认为3次。
conf.setMaxErrorRetry(5);

网络流传输

用户采用网络流传输,SDK 会通过公网先拉源文件,如果源拉文件很慢,直接影响到写 OSS 速度,尽量不要通过网络流上传文件,尽量使用本地上传。如果要用网路流的方式传输,先保证源文件网络的通畅和带宽充足;

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 上传网络流。
InputStream inputStream = new URL("https://www.aliyun.com/").openStream();
ossClient.putObject("<yourBucketName>", "<yourObjectName>", inputStream);

// 关闭OSSClient。
ossClient.shutdown();

主机文件描述符

用户使用 SDK 配置的 connection 代表应用层处理的最大能力,要和主机的文件描述符相对成,如果主机设置的 FD 是 1000 ,SDK 应用层即便设置到 2000,最后效果也达不到 2000 ,最多只能处理 1000 个连接;

代码优化

java SDK 在 分片的基础上增加了断点传输,既可以在分片基础上增加并发,也支持断点记录的功能,在遇到网络问题断开时不需要每次从文件开始重传,从记录断点的位置继续传输;

分片大小建议
100M,1M 分片
1000M , 10M 分片
10G , 100M 分片
100G, 1G 分片

setPartSize 设置分片大小,默认 1M

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

ObjectMetadata meta = new ObjectMetadata();
// 指定上传的内容类型。
meta.setContentType("text/plain");

// 通过UploadFileRequest设置多个参数。
UploadFileRequest uploadFileRequest = new UploadFileRequest("<yourBucketName>","<yourObjectName>");

// 通过UploadFileRequest设置单个参数。
// 设置存储空间名称。
//uploadFileRequest.setBucketName("<yourBucketName>");
// 设置文件名称。
//uploadFileRequest.setKey("<yourObjectName>");
// 指定上传的本地文件。
uploadFileRequest.setUploadFile("<yourLocalFile>");
// 指定上传并发线程数,默认为1。
uploadFileRequest.setTaskNum(5);
// 指定上传的分片大小,范围为100KB~5GB,默认为文件大小/10000。
uploadFileRequest.setPartSize(1 * 1024 * 1024);
// 开启断点续传,默认关闭。
uploadFileRequest.setEnableCheckpoint(true);
// 记录本地分片上传结果的文件。开启断点续传功能时需要设置此参数,上传过程中的进度信息会保存在该文件中,如果某一分片上传失败,再次上传时会根据文件中记录的点继续上传。上传完成后,该文件会被删除。默认与待上传的本地文件同目录,为uploadFile.ucp。
uploadFileRequest.setCheckpointFile("<yourCheckpointFile>");
// 文件的元数据。
uploadFileRequest.setObjectMetadata(meta);
// 设置上传成功回调,参数为Callback类型。
uploadFileRequest.setCallback("<yourCallbackEvent>");

// 断点续传上传。
ossClient.uploadFile(uploadFileRequest);

// 关闭OSSClient。
ossClient.shutdown();

常见问题

下文结合一些常见的使用案例说下注意问题,案例不定期补充,所有用户数据信息已经处理过。

SDK.ServerUnreachable : Speicified endpoint or uri is not valid

image.png

出现这种问题意思是用户没有连接到阿里云网关,一般和一下几个原因有关系:

  • 用户端的代码中并发请求 STS 过高,而用户端的 ECS 或者本地 PC 不足以承载当时的并发导致,降低 OSS 并发。
  • 用户的网络到 server 端有超时现象可以进行抓包验证。
  • 用户的 STS SDK 版本以及 SDK core 版本不是最新导致。更换到新版 SDK 测试一下

访问 NoSuchKey

case:java.lang.Exception: com.aliyun.oss.OSSException: 
Not Foundn[ErrorCode]: NoSuchKeyn

java SDK 出现这种问题,就是源文件不存在,可以参考排查系列中的 [404](
https://yq.aliyun.com/articles/657166?spm=ata.13261165.0.0.181e32fbXDYxLN)

socketException

image.png

可以明显看到错误是 socket 异常了,这可能是 socket 在 init 阶段就失败了,请求都没有到 OSS ,建议客户端检查下:

  • 当时的网络是否出现抖动。可以用 ping -c 100 -s 1024 -i 0.01 或者 mtr 命令看下网络即时探测的数据
  • 主机的 socket 连接数是否占满。可以用 netstat 命令看下当前的连接数;
  • SDK 中设置的 maxconnection 是多大,如果当时链接数超过 maxconnection 设置,也会出现 socket 异常。
  • 如果以上没有没有问题,只能让用户部署 tcpdump 或者 wireshark 抓包,然后复现问题后,分下数据包。

Java 结合 web 实现通过 STS 上传 OSS

如果出现如下报错,可能和跨域或者代码中配置的 OSS 信息有关,可以按照如下思路处理。

image.png

image.png

image.png

如果是使用 java 的代码,可以看下

  • 服务端生成上传信息时 host 和 bucket 是否填写正确。
  • 是否对 OSS 配置了跨域文件。

版权声明:本文中所有内容均属于阿里云开发者社区所有,任何媒体、网站或个人未经阿里云开发者社区协议授权不得转载、链接、转贴或以其他方式复制发布/发表。申请授权请邮件developerteam@list.alibaba-inc.com,已获得阿里云开发者社区协议授权的媒体、网站,在转载使用时必须注明"稿件来源:阿里云开发者社区,原文作者姓名",违者本社区将依法追究责任。 如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

分享阿里云支持与服务团队最佳实践、经典案例与故障排查。

官方博客
文档