试图上传到S3存储桶。上传5-10后,它会挂起

时间:2016-06-19 12:06:06

标签: javascript node.js amazon-web-services amazon-s3

我创建了一个使用aws-sdk上传到我的S3存储桶的承诺。我的应用程序是一个简单的命令行脚本,用于将图像添加到S3并更新数据库。我每次运行都会有300到1000张图像上传。

我遇到的问题是上传5-10张图片,但似乎挂了。我已通过在下面的承诺中检查错误后放置console.log(data)来确认这一点。

前5张图片上传速度很快,第6张图片大约需要一分钟,第7张图片需要更长时间才会上传,此时它只会挂起。

S3-上传-promise.js

'use strict'

let AWS = require('aws-sdk')
let s3 = new AWS.S3()

module.exports = function(params) {
  return new Promise(function(resolve, reject) {
      s3.upload(params, function(err, data) {
        if(err) return reject(Error(err))
        resolve(data)
      })
  })
}

以下是调用承诺的代码:

let s3UploadPromise = require('../src/s3-upload-promise/s3-upload-promise')

// Get all PNG files from given path and upload to bucket
listpng(process.argv[2]).then(function(files) {

  let promises = []

  files.forEach(function(el, i) {
    promises.push(el, s3UploadPromise({
        Bucket: process.env.S3_BUCKET,
        Key: 'templates/' + randomstring.generate() + '.png',
        Body: fs.createReadStream(process.argv[2] + el),
        ACL: 'public-read'
    }))
  });

  Promise.all(promises).then(function(values) {
    return console.log(values)
  })
})

任何想法我做错了什么?这与我没有关闭createReadStream吗?

有什么关系

修改

我尝试在s3.upload回调中关闭流。它没有任何区别,它仍然悬挂:

s3.upload(params, function(err, data) {
    params.Body.close()
    if(err) return reject(Error(err))
    resolve(data)
})

修改2

我添加了一些错误检查,我收到以下错误:

{
  message: 'Your socket connection to the server was not read from or written to within the timeout period. Idle connections w
ill be closed.',
  code: 'RequestTimeout',
  region: null,
  time: 2016-06-19T13:14:39.223Z,
  requestId: 'F7E64E8F99E774F3',
  extendedRequestId: 'PW/mPy6t3w9U1uJc8xYKhUGi/KiSY+6yK6nq0RB21Ke1KqRmTWjjm3KXEp0qAEPDadypw+kiwCEP3upER1uecEP4Sl9Tk/lt',
  cfId: undefined,
  statusCode: 400,
  retryable: true
}

关于Github问题的comment提及:

  

使用并发时,我一直注意到这一点> 1,在几个系统上。大多数情况下,在前10个左右的请求之后,由于超时,上传的文件夹将开始获得400个。

也许在某处添加Content-Length会有所帮助。会尝试。

编辑3

我决定尝试一个名为knox的不同库。我遇到了同样的问题!这太疯狂了。如果两个不同的库面临同样的问题,那肯定是亚马逊问题吗?

S3-上传-promise.js

'use strict'

let knox = require('knox')
let process = require('process')

var client = knox.createClient({
  key: process.env.AWS_KEY,
  secret: process.env.AWS_SECRET,
  bucket: process.env.S3_BUCKET,
});

module.exports = function(params) {
  return new Promise(function(resolve, reject) {

    let headers = {
      'Content-Length': params.contentLength,
      'Content-Type': params.contentType,
      'x-amz-acl': params.permissions
    }

    client.putBuffer(params.buffer, params.key, headers, function(err, res){
      if(err) return reject(err)
      resolve(res)
    });
  })
}

致电代码......

// Get all PNG files from given path
listpng(process.argv[2]).then(function(files) {

  let promises = []

  files.forEach(function(el, i) {
    let file = process.argv[2] + el;

    fs.readFile(file, function(err, data) {
      if(err) return console.log(err)

      fs.stat(process.argv[2] + el, function(err, stats) {
        if(err) return console.log(err)

        let key = process.env.S3_TEMPLATES + '/'
        let buffer = fs.createReadStream(process.argv[2] + el)

        let params = {
          buffer: data,
          key: key + randomstring.generate() + '.png',
          contentLength: stats.size,
          contentType: 'image/png',
          permissions: 'public-read',
        }

        promises.push(s3Uploader(params))

        Promise.all(promises).then(function(values) {
          return console.log(values)
        })
      })
    })
  })
})

不确定现在还能做什么。

0 个答案:

没有答案