环境准备
- 使用 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的 日志级别 ;
超时参数设置
弱网的环境下最好将超时时间设置长一些,增加重试次数,避免上传失败。
// 创建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
出现这种问题意思是用户没有连接到阿里云网关,一般和一下几个原因有关系:
- 用户端的代码中并发请求 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
可以明显看到错误是 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 信息有关,可以按照如下思路处理。
如果是使用 java 的代码,可以看下
- 服务端生成上传信息时 host 和 bucket 是否填写正确。
- 是否对 OSS 配置了跨域文件。