開發與維運

性能調優-Java SDK 調優

環境準備

  • 使用 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 配置了跨域文件。

Leave a Reply

Your email address will not be published. Required fields are marked *