在promise.all()中下载s3客户端时丢失网络连接

问题描述 投票:0回答:1

我正在开发一个基于nodejs的服务器,该服务器从s3下载1000个pdf文件,每个文件9MB,将它们压缩成zip文件,并返回URL。

但是,从 S3 下载时出现问题。 当我开始在 S3 上下载时,大约下载了 100 个下载内容,然后无法连接互联网。 看起来与大小无关,因为尝试使用 1GB 文件的 5 个文件时成功了。

这会导致mysql连接丢失>事务失败

[ERROR] Error: BEGIN; - Can't add new command when connection is in closed state
lost connection

我怀疑繁重的网络操作不应该放在promise.all()内部,但我不知道确切的原因。救命!

await Promise.all(
  Ids.map((id) => {
    const readablePayloads: Array<{ filename: string; bugffer: Readable; }> = [];
    // get key, bucket by id
    
    const buffer = await S3Helper.getReadable({bucket, key} {accessKeyId, secretAccessKey});
    readablePayloads.push({ filename, buffer });
  })
)
static async getReadable(opts: { bucket: string; key: string }, awsOpts: AwsOptions): Promise<Readable> {
    return (await createS3Client(awsOpts).send(new AWS.GetObjectCommand({ Bucket: opts.bucket, Key: opts.key }))).Body as Readable;
  }

可以肯定的是,这段代码的工作连接数不到 100 个

node.js amazon-web-services amazon-s3 promise
1个回答
0
投票

我发现这个问题的可能原因有几个:

  • 文件描述符限制。
    任何打开的连接都使用文件描述符。 Linux 每个进程的 文件描述符的默认限制是 1024 。因此,除了分叉 Node.js 进程或增加限制之外,您无能为力。除非你有充分的理由,否则不真正推荐后者。另一种方法是限制连接数量,我将在下面介绍。

  • 内存堆限制。
    这种可能性较小,但仍然是:每个打开的连接都会使用一定量的内存。此外,根据您编写代码和处理可读流的方式,您可能会在可读流中出现过多的缓冲,甚至内存泄漏。

限制连接数

以较小的组下载文件,而不是一次全部下载。它可能看起来像这样:

// _.chunk comes from the `lodash` library.
// Now `chunksOfIds` is an array of arrays, each of which contains up to 100 ids.
// i.e [[1,2,...,100],[101,102,...,200],...,[1001,1002,...,1100]]
const chunksOfIds = _.chunk(Ids, 100)

for (const chunk of chunksOfIds) {
  const readablePayloadsOfThisChunk: Array<{ filename: string; bugffer: Readable; }> = [];

  chunk.map((id) => {
    // get key, bucket by id

    const buffer = await S3Helper.getReadable({bucket, key} {accessKeyId, secretAccessKey});
    readablePayloadsOfThisChunk.push({ filename, buffer });
  })


  // Note: you have to process your `readablePayloads` here, in the loop,
  // so that you will finish your computations before the processing of the next chunk will start
  await processReadablePayloads(readablePayloadsOfThisChunk)
}

© www.soinside.com 2019 - 2024. All rights reserved.