目前,我正在尝试将文件上传到亚马逊S3存储桶,对此我进行了一些研究,发现TransferManager类会将文件拆分为小块,如果文件足够大,则可以使用多个线程并行上传。现在,在该应用程序中,我们正在创建一个AmazonS3 Client的单个实例(在应用程序的开头创建一个单一的bean),并使用该AmazonS3 Client为用户需要上传的每个文件创建一个TransferManager类的实例。文件,文件上传完成后(由TransferManager的waitForCompletion方法检查),我们正在调用方法transferManager.shutdownNow(false)以关闭该文件创建的所有线程,如下所示:

@AutoWired
private AmazonS3 s3Client;


   /**
 * Uploads a file using TransferManager from a MultipartFile.
 */
public String uploadFileParallelized(MultipartFile file) {
  String fileName;
  TransferManager transferManager =
      TransferManagerBuilder.standard().withS3Client(this.s3Client).build();

  try {
    String extension = getExtensionFromBytes(file.getBytes());
    fileName = getFileName(extension);

    ObjectMetadata metadata = new ObjectMetadata();
    metadata.setContentLength(file.getSize());
    metadata.setContentType(file.getContentType());

    Upload upload = transferManager.upload(getBucketName(), this.folder + fileName,
        file.getInputStream(), metadata);
    upload.waitForCompletion();
  } catch (IOException | AmazonClientException | InterruptedException e) {
    throw new FileUploadException("Couldn't upload the file to S3: " + e.getLocalizedMessage(),
        e);
  } finally {
    transferManager.shutdownNow(false);
  }


  return fileName;
}


我仍然有疑问:


我不确定您是否应该为每个上传实例化一个transferManager还是应该仅使用TransferManager的一个实例(可能是一个bean),但是在那种情况下,我将无法调用transferManager.shutdownNow(false)方法,我将无法使用它进行第二次上传。
即使我不调用shutdownNow方法,TransferManager也会关闭所有用于上传文件的线程吗?
是否可以使用相同的AmazonS3客户端创建TransferManager的多个实例,还是应该为所需的每个TransferManager创建一个S3Client?
即使文件很小(是否小于5 MB),我们也应该使用TransferManager吗?

最佳答案

https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/TransferManager.html


完成所有上传后,应在单个shutdownNow实例上调用TransferManager


  TransferManager负责管理资源,例如
  连接和线程;共享一个TransferManager实例
  只要有可能。 TransferManager,与
  适用于Java的AWS开发工具包是线程安全的。呼叫TransferManager.shutdownNow()
  传输完成后释放资源。

是。


  默认情况下,当垃圾回收传输管理器实例时,线程池将关闭。

您应该使用相同的S3客户端。这是线程安全的。
minUploadPartSize是5MB,minUploadThresholdSize是16MB。您可以对所有文件使用TransferManagerupload,它将根据文件大小分解文件。这些选项是可配置的。如果您知道所有文件都较小,则使用putObject可能会更容易。

10-05 23:28