環境準備
- 使用 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 配置了跨域文件。