Aws s3 — SdkInterruptedException

Получение исключения com.amazonaws.http.timers.client.SdkInterruptedException при выполнении приведенной ниже строки кода при развертывании как задания Spark в AWS EMR.

S3Object response = s3client.getObject(new GetObjectRequest(s3URI.getBucket(), s3URI.getKey()));

Версия SDK, код и трассировка стека указаны ниже. В чем может быть проблема и как ее решить?

Информация о версии

  • Версия Java: 1.8
  • Версия AWS SDK: 1.11.1026

Зависимость

  • com.amazonaws:aws-java-sdk-bundle:jar:1.11.1026

Код

public static ByteArrayOutputStream getS3Object(String path) {
  AmazonS3 s3client = null;
  try {
    AmazonS3URI s3URI = new AmazonS3URI(path);
    s3client = AmazonS3ClientBuilder.defaultClient();
    S3Object response = s3client.getObject(new GetObjectRequest(s3URI.getBucket(), s3URI.getKey()));
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = response.getObjectContent().read(buffer)) != -1) {
      byteArrayOutputStream.write(buffer, 0, bytesRead);
    }
    response.close();
    return byteArrayOutputStream;
  } catch (AbortedException | IOException e) {
    e.printStackTrace();
    System.err.println("AWS call interrupted retrying " + e);
  } finally {
    if (s3client != null) {
      s3client.shutdown();
    }
  }
  throw new RuntimeException("s3 object is null");
}

Трассировки стека

com.amazonaws.AbortedException: 
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleInterruptedException(AmazonHttpClient.java:880)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:757)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:715)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:697)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:561)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:541)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5456)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5403)
at com.amazonaws.services.s3.AmazonS3Client.getObject(AmazonS3Client.java:1524)
com.example.S3Utils.getS3Object(S3Utils.java:78)
Caused by: com.amazonaws.http.timers.client.SdkInterruptedException
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.checkInterrupted(AmazonHttpClient.java:935)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.checkInterrupted(AmazonHttpClient.java:921)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1115)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:814)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:781)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:755)
... 53 more

Вы используете AWS SDK для Java V1. Эта версия SDK скоро устареет. aws.amazon.com/blogs/developer/…. Вам следует обновиться до V2 как можно скорее. Ниже я опубликую код, который вы должны использовать.

smac2020 22.02.2024 16:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
362
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы используете версию SDK, которая устарела, как указано в моем комментарии. Теперь, чтобы получить объект S3 с помощью AWS SDK для Java V2, вы можете использовать этот код. Если вы не знаете, как начать работу с V2, см. Руководство для разработчиков:

Руководство разработчика — AWS SDK для Java 2.x

package com.example.s3;

// snippet-start:[s3.java2.getobjectdata.main]
// snippet-start:[s3.java2.getobjectdata.import]
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
// snippet-end:[s3.java2.getobjectdata.import]

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class GetObjectData {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <bucketName> <keyName> <path>

                Where:
                    bucketName - The Amazon S3 bucket name.\s
                    keyName - The key name.\s
                    path - The path where the file is written to.\s
                """;

        if (args.length != 3) {
            System.out.println(usage);
            System.exit(1);
        }

        String bucketName = args[0];
        String keyName = args[1];
        String path = args[2];
        Region region = Region.US_EAST_1;
        S3Client s3 = S3Client.builder()
                .region(region)
                .build();

        getObjectBytes(s3, bucketName, keyName, path);
    }

    public static void getObjectBytes(S3Client s3, String bucketName, String keyName, String path) {
        try {
            GetObjectRequest objectRequest = GetObjectRequest
                    .builder()
                    .key(keyName)
                    .bucket(bucketName)
                    .build();

            ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest);
            byte[] data = objectBytes.asByteArray();

            // Write the data to a local file.
            File myFile = new File(path);
            OutputStream os = new FileOutputStream(myFile);
            os.write(data);
            System.out.println("Successfully obtained bytes from an S3 object");
            os.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
// snippet-end:[s3.java2.getobjectdata.main]

Вы можете найти POM в примере кода AWS на Github здесь:

https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/s3

Спасибо @smac2020. У нас есть другой код, использующий AWS SDK для Java v1.x. Будут ли внесены какие-либо изменения в этот код для перехода с AWS SDK для версии 1.x на версию 2.x?

Vasanth Subramanian 22.02.2024 16:50

Да, существует руководство по миграции. docs.aws.amazon.com/sdk-for-java/latest/developer-guide/…. Вам следует как можно скорее заменить все версии V1 на V2.

smac2020 22.02.2024 17:06

мы попробовали обновить версию aws sdk (software.amazon.awssdk:s3:2.24.5) и использовали ваш код. Теперь мы видим это исключение software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from any of the providers in the chain....Interrupted waiting to refresh a cached value., InstanceProfileCredentialsProvider(): Interrupted waiting to refresh a cached value.. Вариант использования: мы вызываем API с этим объектом S3. Мы получаем это исключение после того, как сервер возвращает 500 — внутренняя ошибка сервера, и мы пытаемся получить объект S3. В чем может быть проблема?

Vasanth Subramanian 23.02.2024 18:13

Это означает, что ваши учетные данные не могут быть найдены «software.amazon.awssdk.core.Exception.SdkClientException: невозможно загрузить учетные данные от любого из поставщиков в цепочке». Чтобы настроить свои учетные данные, см. docs.aws.amazon.com/sdk-for-java/latest/developer-guide/…

smac2020 23.02.2024 19:14

Мы перебираем список путей S3, затем получаем текущий объект S3, а затем загружаем этот объект S3 в виде файла, состоящего из нескольких частей, вызывающего API. Учитывая пять путей к объектам S3, если API завершается с ошибкой сервера 500 при попытке использовать третий объект S3, мы сталкиваемся с этим исключением при попытке возобновить работу с четвертым объектом S3. (Примечание. Экземпляр настраивается с помощью роли IAM, и мы не настраиваем учетные данные явным образом). Также пробовал использовать политику повтора (СТАНДАРТ) на клиенте S3, но проблема осталась та же. В чем может быть проблема?

Vasanth Subramanian 26.02.2024 11:23

Другие вопросы по теме