多線程上傳的好處android
在本地持久保存斷點記錄的調用方式:ios
android:api
String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 要保證目錄存在,若是不存在則主動建立
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// 建立斷點上傳請求,參數中給出斷點記錄文件的保存位置,需是一個文件夾的絕對路徑
ResumableUploadRequest request
= new ResumableUploadRequest("<bucketName>", "<objectKey>", "<uploadFilePath>", recordDirectory);
// 設置上傳過程回調
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
@Override
public void onProgress(ResumableUploadRequest request
, long currentSize, long totalSize) {
Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
}
});
OSSAsyncTask resumableTask = oss.asyncResumableUpload(request
, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
@Override
public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
Log.d("resumableUpload", "success!");
}
@Override
public void onFailure(ResumableUploadRequest request, ClientException clientExcepion
, ServiceException serviceException) {
// 異常處理
}
});複製代碼
ios:緩存
// 得到UploadId進行上傳,若是任務失敗而且能夠續傳,利用同一個UploadId能夠上傳同一文件到同一個OSS上的存儲對象
OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
resumableUpload.bucketName = <bucketName>;
resumableUpload.objectKey = <objectKey>;
resumableUpload.partSize = 1024 * 1024;
resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};
resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
resumableUpload.recordDirectoryPath = cachesDir;//記錄斷點的文件路徑
OSSTask * resumeTask = [client resumableUpload:resumableUpload];
[resumeTask continueWithBlock:^id(OSSTask *task) {
if (task.error) {
NSLog(@"error: %@", task.error);
if ([task.error.domain isEqualToString:OSSClientErrorDomain]
&& task.error.code == OSSClientErrorCodeCannotResumeUpload) {
// 該任務沒法續傳,須要獲取新的uploadId從新上傳
}
} else {
NSLog(@"Upload file success");
}
return nil;
}];複製代碼
數據分析
android/ios 端的分片上傳改成併發後的測試與以前對比,上傳分片的網絡請求速度 多線程 和 單線程是同樣的使用時間,這個主要是取決於帶寬速度, 多線程相較於單線程主要是提升了讀取文件的io時間。數據以下:bash
iOS 模擬器測試
100mb大小文件
1000 part num 單線程 104.530217s 多線程 54.528591s
100 part num 單線程 59.306880s 多線程 54.336914s
1.31g 大小文件
100 part num 單線程 746.775666s 多線程 731.940330s
1000 part num 單線程 822.866331s 多線程 733.306236s
2000 part num 單線程 965.428122s 多線程 731.940330s
5000 part num 單線程 1205.379382s 多線程 732.982330s
android motoXT1085 雙核cpu
100mb文件
100 part num 單線程 70.484s 多線程 53.656s
1000 part num 單線程 104.530217s 多線程54.528591s
1.31g視頻文件
135 part num 單線程 869s 多線程 738s
1342 part num 單線程 1079.081s 多線程 732.079s複製代碼
整體來看比以前有提高,單線程隨着片的個數的增長時間耗時愈來愈高,而多線程下,時間基本是同樣的,按照目前默認配置的part size 256kb ,單線程下網絡資源與I/O資源都吃滿,併發下性能提升平均有30%左右(上傳時間減小)服務器
移動端下,網絡資源與I/O資源通常都比較緊缺,多線程不會提升網絡的總帶寬:好比,在跑滿某個資源下載策略分配一個鏈接供給帶寬2000Kb/s的時候,本地單線程 可以同時吃滿 2000Kb/s,這裏就到達了一個峯值;可是若是某個資源鏈接帶寬是2000Kb/s,可是單線程請求帶寬 已經達到 2000Kb/s,那麼就是本地網絡帶寬 Block了上傳速度,也就是說開再多線程,再多鏈接也都無濟於事;但,若是本地網絡帶寬 吃完2000Kb/s 的同時還有不少的網絡資源剩餘,假如還有2000Kb/s的提高空間,那麼這時再創建一個鏈接 將這 2000Kb/s 也吃滿,那麼此時的速度就能夠達到 4000Kb/s,這時提速很明顯,I/O資源同理。網絡