目前,我正在尝试将文件上传到亚马逊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。您可以对所有文件使用TransferManager
到upload
,它将根据文件大小分解文件。这些选项是可配置的。如果您知道所有文件都较小,则使用putObject
可能会更容易。