Questions fréquentes sur le dépannage - AWS SDK for Java 2.x

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Questions fréquentes sur le dépannage

Lorsque vous utilisez le AWS SDK for Java 2.x dans vos applications, vous pouvez rencontrer les erreurs d'exécution répertoriées dans cette rubrique. Utilisez les suggestions présentées ici pour vous aider à découvrir la cause première et à résoudre l'erreur.

Comment corriger l'erreur « java.net.SocketException : Réinitialisation de la connexion » ou « Le serveur n'a pas réussi à terminer la réponse » ?

Une erreur de réinitialisation de connexion indique que votre hôte AWS service, le ou tout autre intermédiaire (par exemple, une passerelle NAT, un proxy, un équilibreur de charge) a fermé la connexion avant que la demande ne soit terminée. Les causes étant nombreuses, pour trouver une solution, vous devez savoir pourquoi la connexion est fermée. Les éléments suivants entraînent généralement la fermeture d'une connexion.

  • La connexion est inactive.Cela est courant pour les opérations de streaming, lorsque les données ne sont pas écrites sur ou depuis le fil pendant un certain temps, de sorte qu'un intermédiaire détecte que la connexion est morte et la ferme. Pour éviter cela, assurez-vous que votre application télécharge ou télécharge activement des données.

  • Vous avez fermé le client HTTP ou SDK. Veillez à ne pas fermer les ressources lorsqu'elles sont en cours d'utilisation.

  • Un proxy mal configuré. Essayez de contourner les proxys que vous avez configurés pour voir si cela résout le problème. Si cela résout le problème, le proxy ferme votre connexion pour une raison ou une autre. Recherchez votre proxy spécifique pour déterminer pourquoi il ferme la connexion.

Si vous ne parvenez pas à identifier le problème, essayez d'exécuter un vidage TCP pour une connexion affectée à la périphérie client de votre réseau (par exemple, après tous les proxys que vous contrôlez).

Si vous constatez que le AWS terminal envoie une TCP RST (réinitialisation), contactez le service concerné pour savoir s'il peut déterminer la raison de la réinitialisation. Soyez prêt à fournir des identifiants de demande et des horodatages indiquant le moment où le problème s'est produit. L'équipe d' AWS assistance peut également bénéficier de journaux de connexion indiquant exactement quels octets votre application envoie et reçoit et à quel moment.

Comment corriger le « délai d'attente de connexion » ?

Une erreur de délai de connexion indique que votre hôte AWS service, le ou tout autre intermédiaire (par exemple, une passerelle NAT, un proxy, un équilibreur de charge) n'a pas réussi à établir une nouvelle connexion avec le serveur dans le délai de connexion configuré. Les éléments suivants décrivent les causes courantes de ce problème.

  • Le délai d'expiration de connexion configuré est trop faible. Par défaut, le délai de connexion est de 2 secondes dans le AWS SDK for Java 2.x. Si vous définissez un délai de connexion trop faible, cette erreur peut s'afficher. Le délai de connexion recommandé est de 1 seconde si vous effectuez uniquement des appels régionaux et de 3 secondes si vous effectuez des demandes interrégionales.

  • Un proxy mal configuré. Essayez de contourner les proxys que vous avez configurés pour voir si cela résout le problème. Si cela résout le problème, le proxy est à l'origine du délai d'expiration de la connexion. Recherchez votre proxy spécifique pour déterminer pourquoi cela se produit

Si vous ne parvenez pas à identifier le problème, essayez d'exécuter un vidage TCP pour une connexion affectée à la périphérie client de votre réseau (par exemple, après tout proxy que vous contrôlez) afin d'étudier tout problème réseau.

Comment corriger « java.net.SocketTimeoutException : Expiration du délai de lecture » ?

Une erreur de délai de lecture indique que la machine virtuelle Java a tenté de lire les données du système d'exploitation sous-jacent, mais que les données n'ont pas été renvoyées dans le délai configuré via le SDK. Cette erreur peut se produire si le système d'exploitation AWS service, ou tout autre intermédiaire (par exemple, une passerelle NAT, un proxy, un équilibreur de charge) n'envoie pas de données dans le délai prévu par la JVM. Les causes étant nombreuses, pour trouver une solution, vous devez savoir pourquoi les données ne sont pas renvoyées.

Essayez d'exécuter un vidage TCP pour une connexion affectée à la périphérie client de votre réseau (par exemple, après tous les proxys que vous contrôlez).

Si vous constatez que le AWS terminal envoie une TCP RST (réinitialisation), contactez le service concerné. Soyez prêt à fournir des identifiants de demande et des horodatages indiquant le moment où le problème s'est produit. L'équipe d' AWS assistance peut également bénéficier de journaux de connexion indiquant exactement quels octets votre application envoie et reçoit et à quel moment.

Comment corriger l'erreur « Impossible d'exécuter la requête HTTP : délai d'attente de connexion depuis le pool » ?

Cette erreur indique qu'une demande ne peut pas obtenir de connexion depuis le pool dans le délai maximum spécifié. Pour résoudre ce problème, nous vous recommandons d'activer les métriques côté client du SDK pour publier des métriques sur Amazon. CloudWatch Les métriques HTTP peuvent aider à identifier la cause première. Les éléments suivants décrivent les causes courantes de cette erreur.

  • Fuite de connexion. Vous pouvez étudier cela en cochant LeasedConcurrencyAvailableConcurrency, et en utilisant MaxConcurrency des métriques. S'il LeasedConcurrency augmente jusqu'à atteindre MaxConcurrency mais ne diminue jamais, il se peut qu'il y ait une fuite de connexion. Une fuite est souvent due au fait qu'une opération de streaming, telle qu'une getObject méthode S3, n'est pas fermée. Nous recommandons à votre application de lire toutes les données du flux d'entrée dès que possible et de fermer le flux d'entrée par la suite. Le graphique suivant montre à quoi peuvent ressembler les métriques du SDK en cas de fuite de connexion.

    Capture d'écran CloudWatch des mesures indiquant une fuite de connexion probable.
  • Inanition du pool de connexion.Cela peut se produire si votre taux de demandes est trop élevé et que la taille du pool de connexions configuré ne peut pas répondre à la demande. La taille du pool de connexions par défaut est de 50, et lorsque les connexions du pool atteignent leur maximum, le client HTTP met les demandes entrantes en file d'attente jusqu'à ce que les connexions soient disponibles. Le graphique suivant montre à quoi peuvent ressembler les métriques du SDK en cas d'indisponibilité du pool de connexions.

    Capture d'écran des CloudWatch indicateurs qui montrent à quoi peut ressembler une privation de pool de connexions.

    Pour atténuer ce problème, envisagez de prendre l'une des mesures suivantes.

    • Augmentez la taille du pool de connexions,

    • Augmentez le délai d'acquisition.

    • Ralentissez le taux de demandes.

    En augmentant le nombre maximum de connexions, le débit du client peut augmenter (sauf si l'interface réseau est déjà pleinement utilisée). Cependant, vous pouvez éventuellement atteindre les limites du système d'exploitation concernant le nombre de descripteurs de fichiers utilisés par le processus. Si vous utilisez déjà pleinement votre interface réseau ou si vous ne parvenez pas à augmenter davantage le nombre de connexions, essayez d'augmenter le délai d'acquisition. Avec cette augmentation, vous gagnez du temps supplémentaire pour les demandes visant à établir une connexion avant l'expiration du délai imparti. Si les connexions ne se libèrent pas, les demandes suivantes expireront toujours.

    Si vous ne parvenez pas à résoudre le problème en utilisant les deux premiers mécanismes, ralentissez le taux de demandes en essayant les options suivantes.

    • Simplifiez vos demandes afin que les fortes rafales de trafic ne surchargent pas le client.

    • Soyez plus efficace avec les appels vers AWS services.

    • Augmentez le nombre d'hôtes qui envoient des demandes.

  • Les threads d'E/S sont trop occupés. Cela ne s'applique que si vous utilisez un client SDK asynchrone avec. NettyNioAsyncHttpClient Si la AvailableConcurrency métrique n'est pas faible, ce qui indique que des connexions sont disponibles dans le pool, mais qu'elle ConcurrencyAcquireDuration est élevée, cela peut être dû au fait que les threads d'E/S ne sont pas en mesure de traiter les demandes. Assurez-vous de ne pas vous faire passer Runnable:run pour un futur exécuteur de complétion et d'exécuter une tâche fastidieuse dans la chaîne de complétion future de la réponse, car cela peut bloquer un thread d'E/S. Si ce n'est pas le cas, envisagez d'augmenter le nombre de threads d'E/S en utilisant eventLoopGroupBuilder cette méthode. À titre de référence, le nombre par défaut de threads d'E/S pour une NettyNioAsyncHttpClient instance est le double du nombre de cœurs de processeur de l'hôte.

  • Latence de connexion TLS élevée. Si votre AvailableConcurrency métrique est proche de 0 mais inférieure àMaxConcurrency, cela peut être dû au fait que la latence du handshake TLS est élevée. LeasedConcurrency Le graphique suivant montre à quoi peuvent ressembler les métriques du SDK en cas de latence élevée en matière de prise de contact TLS.

    Capture d'écran des CloudWatch mesures susceptibles d'indiquer une latence de connexion TLS élevée.

    Pour les clients HTTP proposés par le SDK Java qui ne sont pas basés sur le CRT, essayez d'activer les journaux TLS pour résoudre les problèmes liés au TLS. Pour le client HTTP AWS basé sur CRT, essayez d'activer les journaux AWS CRT. Si vous constatez que le AWS point de terminaison semble mettre du temps à effectuer une prise de contact TLS, vous devez contacter le service concerné.

Comment réparer unNoClassDefFoundError, NoSuchMethodError ou NoSuchFieldError ?

A NoClassDefFoundError indique qu'une classe n'a pas pu être chargée lors de l'exécution. Les deux causes les plus fréquentes de cette erreur sont les suivantes :

  • la classe n'existe pas dans le chemin de classe car le fichier JAR est absent ou la mauvaise version du fichier JAR se trouve sur le chemin de classe.

  • la classe n'a pas pu être chargée car son initialiseur statique a généré une exception.

De même, NoSuchMethodError s et NoSuchFieldError s résultent généralement d'une version de JAR incompatible. Nous vous recommandons de suivre les étapes suivantes.

  1. Vérifiez vos dépendances pour vous assurer que vous utilisez la même version de tous les fichiers JAR du SDK. La raison la plus courante pour laquelle une classe, une méthode ou un champ est introuvable est lorsque vous effectuez une mise à niveau vers une nouvelle version du client mais que vous continuez à utiliser une ancienne version de dépendance « partagée » du SDK. La nouvelle version du client peut tenter d'utiliser des classes qui n'existent que dans les nouvelles dépendances « partagées » du SDK. Essayez d'exécuter mvn dependency:tree ou gradle dependencies (pour Gradle) de vérifier que les versions de la bibliothèque du SDK correspondent toutes. Pour éviter complètement ce problème à l'avenir, nous vous recommandons d'utiliser BOM (Bill of Materials) pour gérer les versions des modules du SDK.

    L'exemple suivant montre un exemple de versions mixtes du 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

    La version de dynamodb est 2.20.00 et la version de aws-core est 2.13.19. La version de l'aws-coreartefact doit également être 2.20.00.

  2. Vérifiez les instructions au début de vos journaux pour voir si une classe ne parvient pas à se charger en raison d'un échec d'initialisation statique. La première fois que la classe ne se charge pas, elle peut générer une exception différente, plus utile, qui indique pourquoi la classe ne peut pas être chargée. Cette exception potentiellement utile ne se produit qu'une seule fois, de sorte que les instructions de journal ultérieures indiqueront uniquement que la classe est introuvable.

  3. Vérifiez votre processus de déploiement pour vous assurer qu'il déploie réellement les fichiers JAR requis en même temps que votre application. Il est possible que vous construisiez avec la bonne version, mais le processus qui crée le chemin de classe pour votre application exclut une dépendance requise.

Comment corriger une erreur « » ou une erreur SignatureDoesNotMatch « La signature de demande que nous avons calculée ne correspond pas à la signature que vous avez fournie » ?

Une SignatureDoesNotMatch erreur indique que la signature générée par le AWS SDK for Java et celle générée par le AWS service ne correspondent pas. Les éléments suivants décrivent les causes potentielles.

  • Un mandataire ou un intermédiaire modifie la demande. Par exemple, un proxy ou un équilibreur de charge peut modifier un en-tête, un chemin ou une chaîne de requête signés par le SDK.

  • Le service et le SDK diffèrent dans la manière dont ils encodent la demande lorsque chacun génère la chaîne à signer.

Pour résoudre ce problème, nous vous recommandons d'activer la journalisation du débogage pour le SDK. Essayez de reproduire l'erreur et de trouver la demande canonique générée par le SDK. Dans le journal, la demande canonique est étiquetée avec AWS4 Canonical Request: ... et la chaîne à signer est étiquetéeAWS4 String to sign: ....

Si vous ne pouvez pas activer le débogage, par exemple parce qu'il n'est reproductible qu'en production, ajoutez à votre application une logique qui enregistre les informations relatives à la demande lorsque l'erreur se produit. Vous pouvez ensuite utiliser ces informations pour essayer de reproduire l'erreur en dehors de la production lors d'un test d'intégration avec la journalisation du débogage activée.

Après avoir collecté la demande canonique et la chaîne à signer, comparez-les à la spécification AWS Signature Version 4 pour déterminer s'il existe des problèmes dans la manière dont le SDK a généré la chaîne à signer. Si quelque chose ne va pas, vous pouvez créer un rapport de GitHub bogue auprès du AWS SDK for Java.

Si aucun problème ne s'affiche, vous pouvez comparer la chaîne à signer du SDK avec la chaîne à signer que certains AWS services renvoient dans le cadre de la réponse à l'échec (Amazon S3, par exemple). Si ce n'est pas disponible, vous devez contacter le service concerné pour voir quelle demande canonique et quelle chaîne de signature ils ont générées à des fins de comparaison. Ces comparaisons peuvent aider à identifier les parties intermédiaires susceptibles d'avoir modifié la demande ou les différences de codage entre le service et le client.

Pour plus d'informations générales sur les demandes de signature, consultez la section Signature des demandes d' AWS API dans le guide de AWS Identity and Access Management l'utilisateur.

Exemple d'une demande canonique
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
Exemple d'une chaîne à signer
AWS4-HMAC-SHA256 20240308T034435Z 20240308/us-east-1/s3/aws4_request 5f20a7604b1ef65dd89c333fd66736fdef9578d11a4f5d22d289597c387dc713

Comment corriger l'erreur « java.lang.IllegalStateException : arrêt du pool de connexions » ?

Cette erreur indique que le pool de connexions HTTP Apache sous-jacent a été fermé. Les éléments suivants décrivent les causes potentielles.

  • Le client SDK a été fermé prématurément.Le SDK ferme le pool de connexions uniquement lorsque le client associé est fermé. Veillez à ne pas fermer les ressources lorsqu'elles sont en cours d'utilisation.

  • Un java.lang.Error a été lancé. Des erreurs telles que OutOfMemoryError l'arrêt d'un pool de connexions HTTP Apache. Examinez vos journaux à la recherche de traces d'erreurs. Vérifiez également dans votre code les endroits où il détecte Throwable s ou Error s mais en absorbe le résultat, ce qui empêche l'erreur de réapparaître. Si votre code ne signale aucune erreur, réécrivez-le afin que les informations soient enregistrées. Les informations enregistrées permettent de déterminer la cause première de l'erreur.

  • Vous avez tenté d'utiliser le fournisseur d'informations d'identification renvoyé DefaultCredentialsProvider#create() après sa fermeture. DefaultCredentialsProvider#createrenvoie une instance de singleton. Ainsi, si elle est fermée et que votre code appelle la resolveCredentials méthode, l'exception est déclenchée après l'expiration des informations d'identification (ou jeton) mises en cache.

    Vérifiez dans votre code les endroits où le DefaultCredentialsProvider est fermé, comme indiqué dans les exemples suivants.

    • L'instance singleton est fermée en appelant DefaultCredentialsProvider#close().

      DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // Singleton instance returned. AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials(); // Make calls to AWS services. defaultCredentialsProvider.close(); // Explicit close. // Make calls to AWS services. // 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();
    • Invoquez DefaultCredentialsProvider#create() dans un try-with-resources bloc.

      try (DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create()) { AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials(); // Make calls to AWS services. } // After the try-with-resources block exits, the singleton DefaultCredentialsProvider is closed. // Make calls to AWS services. 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();

    Créez une nouvelle instance non singleton en appelant DefaultCredentialsProvider.builder().build() si votre code a fermé l'instance singleton et que vous devez résoudre les informations d'identification à l'aide d'un. DefaultCredentialsProvider