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