2016-09-14 16 views
0

AWSマルチパートアップロードを使用してファイルをAWSバケットにアップロードしようとしています。これは、小さなファイルのための素晴らしい作品しかし、今私は(170個の部分に分割される)大きなファイルを追加しようとしている、と私は次のエラーを取得:AWSマルチパートアップロードノードjsエラー

multiErr, upload part error: { [RequestTimeTooSkewed: The difference between the request time and the current time is too large.] 

ORこのエラー:

multiErr, upload part error: { [TimeoutError: Connection timed out after 120000ms] 

これをどのように修正することができますか?ここに私のコードです:

var fs = require('fs'); 
var AWS = require('aws-sdk'); 
AWS.config.loadFromPath('./config.json') 
var s3 = new AWS.S3(); 

// File 
var fileName = 'atom.mov'; 
var filePath = './' + fileName; 
var fileKey = fileName; 
var buffer = fs.readFileSync('./' + filePath); 
// S3 Upload options 
var bucket = 'test.bucket.1234'; 

// Upload 
var startTime = new Date(); 
var partNum = 0; 
var partSize = 1024 * 1024 * 5; // Minimum 5MB per chunk (except the last part) http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html 
var numPartsLeft = Math.ceil(buffer.length/partSize); 
var maxUploadTries = 3; 
var multiPartParams = { 
    Bucket: bucket, 
    Key: fileKey, 
    ContentType: 'application/mov' 
}; 
var multipartMap = { 
    Parts: [] 
}; 

function completeMultipartUpload(s3, doneParams) { 
    s3.completeMultipartUpload(doneParams, function(err, data) { 
    if (err) { 
     console.log("An error occurred while completing the multipart upload"); 
     console.log(err); 
    } else { 
     var delta = (new Date() - startTime)/1000; 
     console.log('Completed upload in', delta, 'seconds'); 
     console.log('Final upload data:', data); 
    } 
    }); 
} 

function uploadPart(s3, multipart, partParams, tryNum) { 
    var tryNum = tryNum || 1; 
    s3.uploadPart(partParams, function(multiErr, mData) { 
    if (multiErr){ 
     console.log('multiErr, upload part error:', multiErr); 
     if (tryNum < maxUploadTries) { 
     console.log('Retrying upload of part: #', partParams.PartNumber) 
     uploadPart(s3, multipart, partParams, tryNum + 1); 
     } else { 
     console.log('Failed uploading part: #', partParams.PartNumber) 
     } 
     return; 
    } 
     .Parts[this.request.params.PartNumber - 1] = { 
     ETag: mData.ETag, 
     PartNumber: Number(this.request.params.PartNumber) 
    }; 
    console.log("Completed part", this.request.params.PartNumber); 
    console.log('mData', mData); 
    if (--numPartsLeft > 0) return; // complete only when all parts uploaded 

    var doneParams = { 
     Bucket: bucket, 
     Key: fileKey, 
     MultipartUpload: multipartMap, 
     UploadId: multipart.UploadId 
    }; 

    console.log("Completing upload..."); 
    completeMultipartUpload(s3, doneParams); 
    }); 
} 

// Multipart 
console.log("Creating multipart upload for:", fileKey); 
s3.createMultipartUpload(multiPartParams, function(mpErr, multipart){ 
    if (mpErr) { console.log('Error!', mpErr); return; } 
    console.log("Got upload ID", multipart.UploadId); 

    // Grab each partSize chunk and upload it as a part 
    for (var rangeStart = 0; rangeStart < buffer.length; rangeStart += partSize) { 
    partNum++; 
    var end = Math.min(rangeStart + partSize, buffer.length), 
     partParams = { 
      Body: buffer.slice(rangeStart, end), 
      Bucket: bucket, 
      Key: fileKey, 
      PartNumber: String(partNum), 
      UploadId: multipart.UploadId 
     }; 

    // Send a single part 
    console.log('Uploading part: #', partParams.PartNumber, ', Range start:', rangeStart); 
    uploadPart(s3, multipart, partParams); 
    } 
}); 
+0

タイムアウトが問題です。彼らは起こる。しかし、リクエストを再試行する前に、リクエストを再発行する必要があるように見えます。タイムアウトが発生した場合、リクエストの日付は古すぎます。これはRequestTimeTooSkewedの意味です。 –

+0

ええええと、リクエストを再試行する前に再署名するにはどうしたらいいですか? – deeveeABC

+0

実際、コードをより詳細に見ると、それはすでにあなたのために起こっていると思います。問題は、すべての170の部品を高速で連続して起動しているため、同時接続が170件になり、潜在的に多すぎることです。これにより、タイムアウトが発生し、ローカルリソース(CPU、ネットワーク)の飽和により要求が間接的に遅延する可能性があります。私は非同期の並列マルチパートアップローダ(jsではなく)を書きました。必要なすべての部品番号と範囲の配列を格納し、最初の "n"部分(設定可能な値)をループで開始し、コールバックが発生しました... –

答えて

0

設定でタイムアウトプロパティを設定してみてください。 これは、私の500メガバイト+ファイルのために働いて30分はやり過ぎかもしれないが、それは働いていた;)

var aws = require('aws-sdk'); 

aws.config.update({ 
    region: "your region", 
    accessKeyId: "your access key", 
    secretAccessKey: "your secret", 
    httpOptions: {"timeout: 1800000"} 
}); 
0

s3.uploadのデフォルトのタイムアウトは120000ミリ秒(2分)です。大きなファイルをアップロードするときや、接続が不十分なときは、ファイルを大きくすることができます。

S3コンストラクタを使用して、デフォルトのタイムアウトを設定します。

const s3 = new AWS.S3({ 
    httpOptions : { 
     timeout: 300000 
    } 
    //... other config 
}); 

S3 documentationをご覧ください。