首页 > 解决方案 > 将对象上传到 Amazon S3 时多次超时

问题描述

我在 Spring Boot 项目中通过 AWS Java SDK V2 与 AWS 通信。

我有一个每天运行 4 次(间隔 6 小时)的计划任务,它将从数据库中提取一些信息并将它们放入 Amazon S3 存储桶中的 CSV 文件中。

我遇到的问题是这个任务有时会成功放置文件,有时它根本不起作用,我收到以下错误:Unable to load credentials from service endpoint.

抛出异常表明SockettimeoutException: connect timeout

这是我在 Amazon S3 中编写的代码:

        try {
            PutObjectRequest objectRequest = PutObjectRequest.builder()
                    .bucket(awsProperties.getS3BucketName())
                    .contentLength((long) filetoUploadBytes.length)
                    .key(FileUtils.getFileFullPath(awsProperties.getPath()))
                    .build();

            log.info("Request that will be sent to upload file to AWS S3 is : {}", objectRequest);

            PutObjectResponse uploadedObjectResponse = s3Client.putObject(
                    objectRequest,
                    RequestBody.fromBytes(filetoUploadBytes)
            );
            log.info("Response sent by S3 (file uploaded successfully) : {}", uploadedObjectResponse);
        } catch (Exception e) {
            log.error("Cannot upload file to S3 due to : {} {}", e.getMessage(), e.getCause());
        }

这也是我用于配置的代码:

ClientOverrideConfiguration.builder()
                .retryPolicy(
                        RetryPolicy.builder()
                                .numRetries(awsProperties.getRetries())
                                .build()
                )
                .apiCallTimeout(Duration.ofMinutes(2))
                .apiCallAttemptTimeout(Duration.ofMinutes(2))
                .build();

更新:添加 S3Client 的代码

@Configuration
@RequiredArgsConstructor
@Slf4j
public class S3Config {
    private final AwsProperties awsProperties;
    private final AwsClientHelper awsClientHelper;

    @Bean
    public S3Client s3Client() {
        return S3Client.builder()
                .overrideConfiguration(awsClientHelper.getConfiguration())
                .region(Region.of(awsProperties.getRegion()))
                .credentialsProvider(InstanceProfileCredentialsProvider.create())
                .build();
    }
}

更新 2:异常的堆栈跟踪

java.net.SocketTimeoutException: connect timed out
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
    at java.base/java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    at java.base/java.net.Socket.connect(Unknown Source)
    at java.base/sun.net.NetworkClient.doConnect(Unknown Source)
    at java.base/sun.net.www.http.HttpClient.openServer(Unknown Source)
    at java.base/sun.net.www.http.HttpClient.openServer(Unknown Source)
    at java.base/sun.net.www.http.HttpClient.<init>(Unknown Source)
    at java.base/sun.net.www.http.HttpClient.New(Unknown Source)
    at java.base/sun.net.www.http.HttpClient.New(Unknown Source)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
    at software.amazon.awssdk.regions.internal.util.ConnectionUtils.connectToEndpoint(ConnectionUtils.java:45)
    at software.amazon.awssdk.regions.util.HttpResourcesUtils.readResource(HttpResourcesUtils.java:112)
    at software.amazon.awssdk.regions.util.HttpResourcesUtils.readResource(HttpResourcesUtils.java:91)
    at software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider$InstanceProviderCredentialsEndpointProvider.endpoint(InstanceProfileCredentialsProvider.java:150)
    at software.amazon.awssdk.regions.util.HttpResourcesUtils.readResource(HttpResourcesUtils.java:112)
    at software.amazon.awssdk.regions.util.HttpResourcesUtils.readResource(HttpResourcesUtils.java:91)
    at software.amazon.awssdk.auth.credentials.HttpCredentialsProvider.refreshCredentials(HttpCredentialsProvider.java:79)
    at software.amazon.awssdk.utils.cache.CachedSupplier.refreshCache(CachedSupplier.java:132)
    at software.amazon.awssdk.utils.cache.OneCallerBlocks.prefetch(OneCallerBlocks.java:38)
    at software.amazon.awssdk.utils.cache.CachedSupplier.prefetchCache(CachedSupplier.java:116)
    at software.amazon.awssdk.utils.cache.CachedSupplier.get(CachedSupplier.java:91)
    at java.base/java.util.Optional.map(Unknown Source)
    at software.amazon.awssdk.auth.credentials.HttpCredentialsProvider.resolveCredentials(HttpCredentialsProvider.java:146)
    at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.resolveCredentials(AwsExecutionContextBuilder.java:165)
    at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(AwsExecutionContextBuilder.java:102)
    at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.invokeInterceptorsAndCreateExecutionContext(AwsSyncClientHandler.java:69)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.lambda$execute$1(BaseSyncClientHandler.java:78)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.measureApiCallSuccess(BaseSyncClientHandler.java:175)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:76)
    at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:45)
    at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:56)
    at software.amazon.awssdk.services.s3.DefaultS3Client.putObject(DefaultS3Client.java:8832)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
    at org.springframework.cloud.sleuth.instrument.scheduling.TraceSchedulingAspect.traceBackgroundThread(TraceSchedulingAspect.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor128.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
    at jdk.internal.reflect.GeneratedMethodAccessor127.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
    at org.springframework.cloud.sleuth.instrument.async.TraceRunnable.run(TraceRunnable.java:68)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)

标签: javaamazon-web-servicesspring-bootamazon-s3aws-sdk-java-2.0

解决方案


推荐阅读