Perguntas frequentes sobre solução de problemas - AWS SDK for Java 2.x

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Perguntas frequentes sobre solução de problemas

Ao usar o AWS SDK for Java 2.x em suas aplicações, você pode encontrar os erros de runtime listados neste tópico. Use as sugestões indicadas aqui para ajudar a descobrir a causa raiz e resolver o erro.

Como faço para corrigir o erro "java.net.SocketException: reinicialização da conexão” ou “falha no servidor ao concluir a resposta”?

Um erro de redefinição de conexão indica que o host, o AWS service (Serviço da AWS) ou qualquer intermediário (por exemplo, um gateway NAT, um proxy, um balanceador de carga) fechou a conexão antes que a solicitação fosse concluída. Como há muitas causas, encontrar uma solução exige que você saiba por que a conexão está sendo fechada. Os itens a seguir geralmente fazem com que uma conexão seja fechada.

  • A conexão está inativa.Isso é comum em operações de streaming, onde nenhum dado é enviado ou recebido pela rede por certo período, então uma parte intermediária detecta a conexão como inativa e a fecha. Para evitar isso, certifique-se de que a aplicação baixe ou carregue dados ativamente.

  • Você fechou o cliente HTTP ou SDK. Não feche os recursos enquanto eles estiverem em uso.

  • Um proxy configurado incorretamente. Ignore todos os proxies que você configurou para ver se isso resolve o problema. Se isso resolver o problema, o proxy está fechando sua conexão por algum motivo. Pesquise seu proxy específico para determinar por que ele está fechando a conexão.

Se você não conseguir identificar o problema, execute um TCP dump para uma conexão afetada na borda do cliente da rede (por exemplo, depois de qualquer proxy que você controla).

Se você perceber que o endpoint AWS está enviando um TCP RST (redefinição), entre em contato com o serviço afetado para ver se é possível determinar a causa da redefinição. Você deverá fornecer os IDs de solicitação e os carimbos de data e hora de quando o problema ocorreu. A equipe de suporte da AWS também pode se beneficiar de logs de conexão de rede que mostram exatamente quais bytes a aplicação está enviando e recebendo e quando.

Como corrigir o erro de “tempo limite de conexão”?

Um erro de tempo limite de conexão indica que o host, o AWS service (Serviço da AWS) ou qualquer intermediário (por exemplo, um gateway NAT, um proxy, um balanceador de carga) falhou ao estabelecer uma nova conexão com o servidor dentro do tempo limite de conexão configurado. Os itens a seguir descrevem as causas comuns para esse problema.

  • O tempo limite de conexão configurado é muito baixo. Por padrão, o tempo limite da conexão é de 2 segundos no AWS SDK for Java 2.x. Se você definir o tempo limite de conexão muito baixo, poderá receber esse erro. O tempo limite de conexão recomendado é de 1 segundo se você faz chamadas apenas na região e de 3 segundos se faz solicitações entre regiões.

  • Um proxy configurado incorretamente. Ignore todos os proxies que você configurou para ver se isso resolve o problema. Se isso resolver o problema, o proxy é o motivo do tempo limite de conexão. Pesquise seu proxy específico para determinar por que isso está ocorrendo

Se você não conseguir identificar o problema, execute um TCP dump para uma conexão afetada na borda do cliente da rede (por exemplo, depois de qualquer proxy que você controla) para investigar qualquer problema de rede.

Como corrigir o “java.net.SocketTimeoutException: tempo limite de leitura”?

Um erro de tempo limite de leitura indica que a JVM tentou ler dados do sistema operacional subjacente, mas os dados não foram retornados dentro do tempo configurado por meio do SDK. Esse erro pode ocorrer se o sistema operacional, o AWS service (Serviço da AWS) ou qualquer parte intermediária (por exemplo, um gateway NAT, um proxy, um balanceador de carga) falhar em enviar dados dentro do tempo esperado pela JVM. Como há muitas causas, encontrar uma solução exige que você saiba por que os dados não estão sendo retornados.

Execute um TCP dump para uma conexão afetada na borda do cliente da rede (por exemplo, depois de qualquer proxy que você controla).

Se você perceber que o endpoint da AWS está enviando um TCP RST (redefinição), entre em contato com o serviço afetado. Você deverá fornecer os IDs de solicitação e os carimbos de data e hora de quando o problema ocorreu. A equipe de suporte da AWS também pode se beneficiar de logs de conexão de rede que mostram exatamente quais bytes a aplicação está enviando e recebendo e quando.

Como corrigir o erro “Não foi possível executar a solicitação HTTP: tempo limite da espera para conexão do grupo”?

Esse erro indica que uma solicitação não pode obter uma conexão do grupo dentro do tempo máximo especificado. Para solucionar o problema, recomendamos que você habilite as métricas do SDK do lado do cliente para publicar métricas no Amazon CloudWatch. As métricas HTTP podem ajudar a identificar a causa raiz. Os itens a seguir descrevem as causas comuns desse erro.

  • Vazamento de conexão. Você pode investigar isso verificando as métricas LeasedConcurrency, AvailableConcurrency e MaxConcurrency. Se LeasedConcurrency aumenta até atingir MaxConcurrency. mas nunca diminui, pode haver um vazamento de conexão. Uma causa comum de vazamento é porque uma operação de streaming, como um método getObject do S3, não está fechada. Recomendamos que a aplicação leia todos os dados do fluxo de entrada o mais rápido possível e feche o fluxo de entrada depois. O gráfico a seguir mostra como podem ser as métricas do SDK referente ao vazamento de conexão.

    Uma captura de tela das métricas do CloudWatch que mostram um provável vazamento de conexão.
  • Escassez no pool de conexões.Isso poderá acontecer se a taxa de solicitação for muito alta e o tamanho do pool de conexões que foi configurado não puder atender à demanda da solicitação. O tamanho padrão do pool de conexões é 50 e, quando as conexões no grupo atingem o máximo, o cliente HTTP enfileira as solicitações recebidas até que as conexões estejam disponíveis. O gráfico a seguir mostra como podem ser as métricas do SDK referente à escassez do grupo de conexão.

    Uma captura de tela das métricas do CloudWatch que mostra como pode ser a escassez do pool de conexões.

    Para mitigar esse problema, realize qualquer uma das ações a seguir.

    • Aumente o tamanho do pool de conexões

    • Aumente o tempo limite de aquisição.

    • Diminua a taxa de solicitações.

    Ao aumentar o número máximo de conexões, o throughput do cliente pode aumentar (a menos que a interface de rede já esteja totalmente utilizada). No entanto, você pode eventualmente atingir as limitações do sistema operacional quanto ao número de descritores de arquivo usados pelo processo. Se você já usa totalmente sua interface de rede ou não consegue aumentar a contagem de conexões, tente aumentar o tempo limite de aquisição. Com o aumento, você ganha tempo extra para que as solicitações adquiram uma conexão antes do tempo limite. Se as conexões não forem liberadas, as solicitações subsequentes ainda atingirão o tempo limite.

    Se você não conseguir corrigir o problema usando os dois primeiros mecanismos, diminua a taxa de solicitações tentando as seguintes opções.

    • Suavize suas requisições para que grandes picos de tráfego não sobrecarreguem o cliente.

    • Seja mais eficiente nas chamadas para Serviços da AWS.

    • Aumente o número de hosts enviando solicitações.

  • As threads de E/S estão muito ocupados. Isso só se aplica se você estiver usando um cliente assíncrono do SDK com o NettyNioAsyncHttpClient. Se a métrica AvailableConcurrency não estiver baixa, indicando que as conexões estão disponíveis no pool, mas ConcurrencyAcquireDuration estiver alta, talvez seja porque as threads de E/S não conseguem lidar com as solicitações. Certifique-se de não passar Runnable:run como executor de conclusão futura e de não realizar tarefas demoradas na cadeia de conclusão futura de respostas, pois isso pode bloquear uma thread de E/S. Se esse não for o caso, considere aumentar o número de threads de E/S usando o método eventLoopGroupBuilder. Para referência, o número padrão de threads de E/S para uma instância NettyNioAsyncHttpClient é o dobro do número de núcleos de CPU do host.

  • Alta latência de handshake TLS. Se a métrica AvailableConcurrency estiver próxima de 0 e LeasedConcurrency estiver menor que MaxConcurrency, isso pode indicar que a latência do handshake TLS está alta. O gráfico a seguir mostra como seriam as métricas do SDK para alta latência de handshake TLS.

    Uma captura de tela das métricas do CloudWatch que podem indicar alta latência de handshake TLS.

    Para clientes HTTP oferecidos pelo Java SDK que não são baseados no CRT, tente habilitar os logs de TLS para solucionar problemas de TLS. Para o cliente HTTP baseado no AWS CRT, tente habilitar logs do AWSCRT. Se você perceber que o endpoint da AWS leva muito tempo para realizar um handshake TLS, entre em contato com o serviço afetado.

Como corrigir um NoClassDefFoundError, NoSuchMethodError ou NoSuchFieldError?

Um NoClassDefFoundError indica que não foi possível carregar uma classe no runtime. As duas causas comuns para esse erro são:

  • a classe não existe no classpath porque o JAR está ausente ou a versão errada do JAR está no classpath.

  • a classe falhou ao carregar porque seu inicializador estático gerou uma exceção.

Da mesma forma, NoSuchMethodErrors e NoSuchFieldErrors normalmente resultam de uma versão JAR incompatível. Recomendamos seguir as seguintes etapas:

  1. Verifique suas dependências para ter certeza de que você está usando a mesma versão de todos os jars do SDK. O motivo mais comum pelo qual uma classe, um método ou um campo não pode ser encontrado é quando você atualiza para uma nova versão do cliente, mas continua usando uma versão antiga de dependência do SDK “compartilhada”. A nova versão do cliente pode tentar usar classes que existem somente nas dependências “compartilhadas” mais recentes do SDK. Tente executar mvn dependency:tree ou gradle dependencies (para Gradle) para verificar se todas as versões da biblioteca do SDK coincidem. Para evitar totalmente esse problema no futuro, recomendamos o uso de BOM (Bill of Materials) para gerenciar as versões do módulo do SDK.

    O exemplo a seguir mostra um exemplo de versões mistas do SDK.

    [INFO] +- software.amazon.awssdk:dynamodb:jar:2.20.00:compile [INFO] | +- software.amazon.awssdk:aws-core:jar:2.13.19:compile [INFO] +- software.amazon.awssdk:netty-nio-client:jar:2.20.00:compile

    A versão de dynamodb é 2.20.00 e a versão de aws-core é 2.13.19. A versão do artefato aws-core também deve ser 2.20.00.

  2. Verifique as declarações logo no início de seus logs para ver se uma classe está falhando no carregamento devido a uma falha de inicialização estática. Na primeira vez em que a classe falha ao carregar, ela pode lançar uma exceção diferente e mais útil que especifica por que a classe não pode ser carregada. Essa exceção potencialmente útil ocorre apenas uma vez, portanto, as declarações de log posteriores relatarão apenas que a classe não foi encontrada.

  3. Verifique seu processo de implantação para ter certeza de que ele realmente implementa os arquivos JAR necessários junto com a aplicação. É possível que você esteja criando com a versão correta, mas o processo que cria o classpath para a aplicação está excluindo uma dependência necessária.

Como corrigir um erro “SignatureDoesNotMatch” ou “A assinatura da solicitação que calculamos não corresponde à assinatura que você forneceu”?

Um erro SignatureDoesNotMatch indica que a assinatura gerada pelo AWS SDK para Java e a assinatura gerada pelo AWS service (Serviço da AWS) não coincidem. Os itens a seguir descrevem as possíveis causas.

  • Um proxy ou intermediário modifica a solicitação. Por exemplo, um proxy ou balanceador de carga pode modificar um cabeçalho, um caminho ou uma string de consulta que o SDK assinou.

  • O serviço e o SDK diferem na forma como codificam a solicitação quando cada um gera a string para assinar.

Para depurar esse problema, recomendamos que você habilite o registro em log de depuração para o SDK. Tente reproduzir o erro e encontrar a solicitação canônica gerada pelo SDK. No log, a solicitação canônica é rotulada com AWS4 Canonical Request: ... e a string a ser assinada é rotulada com AWS4 String to sign: ....

Se você não puder habilitar a depuração, por exemplo, porque ela só pode ser reproduzida na produção, adicione uma lógica à aplicação que registre as informações sobre a solicitação quando o erro ocorre. Depois, você pode usar essas informações para tentar replicar o erro fora da produção em um teste de integração com o registro em log de depuração habilitado.

Depois de coletar a solicitação canônica e a string para assinar, compare-as com a especificação do AWS Signature versão 4 para determinar se há algum problema na forma como o SDK gerou a string para assinar. Se algo parece estar errado, você pode criar um relatório de bug do GitHub para o AWS SDK para Java.

Se nada parece estar errado, você pode comparar a string para assinar do SDK com a string para assinar que alguns Serviços da AWS retornam como parte da resposta à falha (Amazon S3, por exemplo). Se isso não estiver disponível, entre em contato com o serviço afetado para ver qual solicitação canônica e string para assinar foram geradas para comparação. Essas comparações podem ajudar a identificar partes intermediárias que podem ter modificado a solicitação ou as diferenças de codificação entre o serviço e o cliente.

Consulte mais informações básicas sobre como assinar solicitações em Assinar solicitações de API da AWS no Guia do usuário do AWS Identity and Access Management.

exemplo da solicitação canônica
PUT /Example-Bucket/Example-Object partNumber=19&uploadId=string amz-sdk-invocation-id:f8c2799d-367c-f024-e8fa-6ad6d0a1afb9 amz-sdk-request:attempt=1; max=4 content-encoding:aws-chunked content-length:51 content-type:application/octet-stream host:xxxxx x-amz-content-sha256:STREAMING-UNSIGNED-PAYLOAD-TRAILER x-amz-date:20240308T034733Z x-amz-decoded-content-length:10 x-amz-sdk-checksum-algorithm:CRC32 x-amz-trailer:x-amz-checksum-crc32
exemplo de uma string para assinar
AWS4-HMAC-SHA256 20240308T034435Z 20240308/us-east-1/s3/aws4_request 5f20a7604b1ef65dd89c333fd66736fdef9578d11a4f5d22d289597c387dc713

Como corrigir o erro “java.lang.IllegalStateException: encerramento do pool de conexões”?

Esse erro indica que o pool de conexões HTTP Apache subjacente foi fechado. Os itens a seguir descrevem as possíveis causas.

  • O cliente SDK foi fechado prematuramente.O SDK só fecha o pool de conexões quando o cliente associado é fechado. Não feche os recursos enquanto eles estiverem em uso.

  • Um java.lang.Error foi lançado. Erros como OutOfMemoryError fazem com que um pool de conexões HTTP do Apache seja encerrado. Examine seus logs em busca de rastreamentos de pilha de erros. Além disso, revise seu código em busca de locais em que ele captura Throwables ou Errors, mas suprime a saída que impede que o erro apareça. Se o código não relatar erros, reescreva-o para que as informações sejam registradas em log. As informações registradas em log ajudam a determinar a causa raiz do erro.

  • Você tentou usar o provedor de credenciais retornado de DefaultCredentialsProvider#create() depois que ele foi fechado. DefaultCredentialsProvider#create retorna uma instância singleton. Portanto, se ela estiver fechada e o código chamar o método resolveCredentials, a exceção será lançada após a expiração das credenciais (ou token) em cache.

    Verifique se há locais no código em que DefaultCredentialsProvider esteja fechado, conforme mostrado nos exemplos a seguir.

    • A instância singleton é fechada chamando DefaultCredentialsProvider#close().

      DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // Singleton instance returned. AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials(); // Make calls to Serviços da AWS. defaultCredentialsProvider.close(); // Explicit close. // Make calls to Serviços da AWS. // After the credentials expire, either of the following calls eventually results in a "Connection pool shut down" exception. credentials = defaultCredentialsProvider.resolveCredentials(); // Or credentials = DefaultCredentialsProvider.create().resolveCredentials();
    • Invoque DefaultCredentialsProvider#create() em um bloco try-with-resources.

      try (DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create()) { AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials(); // Make calls to Serviços da AWS. } // After the try-with-resources block exits, the singleton DefaultCredentialsProvider is closed. // Make calls to Serviços da AWS. DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // The closed singleton instance is returned. // If the credentials (or token) has expired, the following call results in the error. AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();

    Crie uma instância que não seja singleton chamando DefaultCredentialsProvider.builder().build() se o código fechou a instância singleton e você precisa resolver as credenciais usando um DefaultCredentialsProvider.

Como corrigir “Não foi possível carregar credenciais de qualquer um dos provedores na cadeia AwsCredentialsProviderChain”?

Esse erro indica que o AWS SDK for Java 2.x não conseguiu encontrar credenciais válidas da AWS por meio de nenhum dos provedores de credenciais na cadeia de provedores de credenciais padrão. O SDK pesquisa automaticamente as credenciais em uma ordem específica, e esse erro ocorre quando todos os provedores da cadeia não fornecem credenciais válidas.

A mensagem de erro completa geralmente se parece com isto (quebras de linha e indentações adicionadas para melhorar a legibilidade):

Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain( credentialsProviders=[ SystemPropertyCredentialsProvider(), EnvironmentVariableCredentialsProvider(), WebIdentityTokenCredentialsProvider(), ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])), ContainerCredentialsProvider(), InstanceProfileCredentialsProvider() ]) : [ SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., WebIdentityTokenCredentialsProvider(): To use web identity tokens, the 'sts' service module must be on the class path., ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])): Profile file contained no credentials for profile 'default': ProfileFile(sections=[]), ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set., InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.]

Causas comuns e soluções

Analisar a configuração de credenciais

Quando você usa o provedor de credenciais padrão (chamando ServiceClient.create() sem configurar explicitamente as credenciais), o SDK pesquisa as credenciais em uma ordem específica. Analise como a cadeia de provedores de credenciais padrão funciona para entender quais origens de credenciais o SDK verifica e em que ordem.

Certifique-se de que o método de configuração de credenciais que você pretende usar esteja configurado corretamente em seu ambiente:

Para instâncias do Amazon EC2
  • Verifique o perfil do IAM: verifique se um perfil do IAM está anexado à instância.

  • Falhas intermitentes do IMDS: se estiverem ocorrendo falhas intermitentes (geralmente com duração de algumas centenas de milissegundos), isso geralmente indica problemas transitórios de rede que atingem o serviço de metadados de instância (IMDS).

    Soluções:

    • Habilite o registro em log de depuração para analisar o tempo e a frequência das falhas

    • Considere implementar a lógica de novas tentativas na aplicação para falhas relacionadas a credenciais

    • Verifique se há problemas de conectividade de rede entre a instância e o endpoint do IMDS

Para ambientes de contêiner

Confirme se os perfis de tarefa (Amazon ECS) ou as contas de serviço (Amazon EKS) estão configurados e se as variáveis de ambiente necessárias estão definidas.

Para desenvolvimento local

Verifique se as variáveis de ambiente, os arquivos de credenciais ou a configuração do Centro de Identidade do IAM estão em vigor.

Para federação de identidades da web
  • Verifique a configuração: verifique se o arquivo de token de identidade da web existe e se as variáveis de ambiente necessárias estão configuradas.

  • Dependência ausente do módulo do STS: se ocorrer o erro To use web identity tokens, the 'sts' service module must be on the class path, será necessário adicionar o módulo do STS como uma dependência. Isso é comum ao usar a Identidade de Pods do Amazon EKS ou outra autenticação de token de identidade da web.

    Solução: adicione o módulo do STS às dependências do projeto:

    • <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>sts</artifactId> </dependency>

      Para alguns serviços, talvez você também precise da dependência aws-query-protocol:

      <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>aws-query-protocol</artifactId> </dependency>

Problemas de conectividade de rede ou proxy

Se ocorrerem erros Connection refused na cadeia de provedores de credenciais, isso normalmente indica problemas de conectividade de rede quando o SDK tenta alcançar endpoints AWS.

Soluções:

  • Verifique a configuração do proxy se você estiver usando um servidor proxy

  • Verifique se a rede permite conexões HTTPS de saída com endpoints AWS

  • Habilite o registro em log de depuração para ver as tentativas de conexão detalhadas

  • Teste a conectividade usando ferramentas como curl para verificar o acesso da rede aos endpoints AWS