在多线程中将文件上传到 S3

Uploading files to S3 in Multithreading

我在 spring 应用程序中使用 s3 AWS 客户端将文件上传到 s3,但有时会出现错误,

com.amazonaws.SdkClientException: Unable to execute HTTP request: Timeout waiting for connection from pool
com.amazonaws.SdkClientException: Unable to execute HTTP request: Timeout waiting for connection from pool
Caused by: org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool

因此,作为解决此问题的方法,我使用了以下方法并且目前有效。

@Bean
public AmazonS3 s3Client() {
    return AmazonS3ClientBuilder
            .standard()
            .withClientConfiguration(new ClientConfiguration()
                    .withMaxConnections(100)
                    .withConnectionTimeout(100)
                    .withMaxErrorRetry(5))
            .build();
}

public String uploadFile() {
    // upload code
}

我将其创建为 Spring Bean。但是我在多线程环境中使用它。所以同时会有很多并发请求。我看到 AmazonS3ClientBuilder 被注释为 @NotThreadSafe。所以我需要知道在多线程中将它用作 bean 是否可以,或者我是否应该在相同的 uploadFile 方法中使用上面的代码块?任何人都可以向我解释最好的方法吗?谢谢

您没有分享上传过程的实际代码,但我认为您的问题出在那个代码上。所以,回答你的问题:

  1. 关于@NotThreadSafe,你不应该担心这个。您使用构建器的目的是创建 AmazonS3 客户端的实例。此过程在 Spring 初始化期间完成,这反过来意味着整个过程由 single thread and thus is not affected by potential synchronization problems. Note that what this mentioned before is in regards to the AmazonS3ClientBuilder. The created AmazonS3Client object (created by invoking AmazonS3ClientBuilder#build) is marked as thread safe as you can see in the related source.

    处理
  2. 关于您遇到的问题。不幸的是,如果不共享上传对象逻辑,就没有具体的方法来理解它的确切原因。但是,我认为您的问题源于您创建的多个并发上传请求高于配置的最大连接数。这反过来会导致这些请求阻塞,等待从 HTTP 池中检索连接。如果不能及时检索到一个,那么请求就会超时(你正在经历的)。有关更多信息,您可以查看相关问题 here,其中概述了您所获得的相同行为,尽管是下载操作。