Comment exporter un fichier de sauvegarde de tas Java vers un compartiment S3 ?

Lecture de 5 minute(s)
0

Une erreur « heap out of memory » s’est produite dans mon application Java stockée dans Amazon Elastic Container Service (Amazon ECS). Pour résoudre l’erreur, je souhaite créer un fichier .hprof et l’enregistrer dans un compartiment Amazon Simple Storage Service (Amazon S3).

Brève description

Généralement, si vous recevez une exception OutOfMemoryError c’est parce qu’une machine virtuelle Java (JVM) ne peut pas allouer suffisamment de mémoire à un tas. Si une erreur « manque de mémoire » survient lorsqu’une application Java s’exécute dans un conteneur ECS, elle interrompt l’application et arrête les tâches ECS. Les fichiers .hprof enregistrés par l’application ne sont plus disponibles. Pour résoudre l’erreur d’exception et régler les problèmes d’allocation de mémoire, vous devez créer un fichier .hprof et l’enregistrer dans un compartiment S3.

Solution

**Remarque :**La solution suivante résout la plupart des situations d’exception OutOfMemoryError. Pour en savoir plus sur la cause des erreurs de mémoire Java, consultez Understand the OutOfMemoryError exception sur le site Web d’Oracle.

Création d’un compartiment S3

À l’aide de la console Amazon S3, créez un compartiment S3 dans lequel stocker votre fichier .hprof.

Création d’une définition de tâche ECS

Utilisez la console Amazon ECS pour créer une définition de tâche qui servira de plan pour votre application Java.

Indiquez le nom de votre compartiment S3 en tant que variable d’environnement. Les commandes d’initialisation de l’application utilisent également le nom du compartiment S3.

Remarque : HEAP_DUMP_BUCKET est la variable d’environnement des exemples de commandes.

Création d’un rôle IAM pour une tâche ECS

Créez une tâche ECS dans le rôle de gestion des identités et des accès AWS (AWS IAM) qui comporte les autorisations S3:PutObject afin de pouvoir télécharger des fichiers.

Exécution des commandes d’initialisation

Dans le répertoire de travail de la JVM, un espace de sauvegarde par défaut est créé dans un fichier nommé java_pidpid.hprof. Pour indiquer un autre nom de fichier ou de répertoire, utilisez l’option XX:HeapDumpPath=.

Dans les exemples de commandes d’initialisation suivants, la sauvegarde du tas est générée dans le répertoire /tmp/heap_dump.hprof :

CMD ["java", \
    "-XX:+HeapDumpOnOutOfMemoryError", \
    "-XX:HeapDumpPath=/tmp/heap_dump.hprof", \
    "-XX:OnOutOfMemoryError=yum install -y aws-cli > /dev/null && aws s3 mv /tmp/heap_dump.hprof s3://$HEAP_DUMP_BUCKET/'date+%F_%T'.hprof ; kill -9 %p", \
    "MemoryApp" \]

Exemple de flux de commandes d’initialisation

Remarque : si des erreurs surviennent lorsque vous exécutez des commandes de l’interface de la ligne de commande AWS (AWS CLI), consultez la page Résoudre les erreurs liées à AWS CLI. Vérifiez également que vous utilisez bien la version la plus récente de l’AWS CLI.

L’option OnOutOfMemoryError précise quelle commande ou quel script exécuter lorsque vous obtenez une exception OutOfMemoryError. Pour en savoir plus sur l’option OnOutOfMemoryError, consultez Java HotSpot VM command-line options sur le site Web d’Oracle.

Voici comment effectuer le flux de commandes OnOutOfMemoryError :

  1. Installez l’interface de ligne de commande AWS (AWS CLI) dans -y sans aucune interaction. La sortie de la commande est enregistrée dans un fichier temporaire dans /dev/null afin que les informations inutiles concernant l’installation de l’AWS CLI ne soient pas ajoutées aux journaux du conteneur.
  2. Téléchargez le fichier .hprof dans le compartiment S3 avec les autorisations du rôle des tâches ECS. Le fichier .hprof est renommé selon le modèle date+%F_%T.hprof.
  3. Consultation des données du journal Amazon CloudWatch :
    2023-05-02T17:02:37.748+01:00    Hello, world! Hello Java! Good bye memory...
    2023-05-02T17:02:37.748+01:00    Going to sleep for 2 ms...
    2023-05-02T17:02:39.748+01:00    Wake now, lets heap the memory...
    2023-05-02T17:02:39.748+01:00    java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    2023-05-02T17:02:39.748+01:00    Dumping heap to /tmp/heap_dump.hprof ...
    2023-05-02T17:02:39.756+01:00    Heap dump file created [2893599 bytes in 0.008 secs]
    2023-05-02T17:02:39.756+01:00    #
    2023-05-02T17:02:39.757+01:00    # java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    2023-05-02T17:02:39.757+01:00    # -XX:OnOutOfMemoryError="yum install -y aws-cli > /dev/null && aws s3 mv /tmp/heap_dump.hprof s3://$HEAP_DUMP_BUCKET/`date +%F_%T`.hprof ; kill -9 %p"
    2023-05-02T17:02:39.757+01:00    # Executing /bin/sh -c "yum install -y aws-cli > /dev/null && aws s3 mv /tmp/heap_dump.hprof s3://$HEAP_DUMP_BUCKET/`date +%F_%T`.hprof "...
    2023-05-02T17:02:54.663+01:00    Completed 256.0 KiB/2.8 MiB (2.2 MiB/s) with 1 file(s) remaining
    Completed 512.0 KiB/2.8 MiB (4.4 MiB/s) with 1 file(s) remaining
    Completed 768.0 KiB/2.8 MiB (6.6 MiB/s) with 1 file(s) remaining
    Completed 1.0 MiB/2.8 MiB (8.7 MiB/s) with 1 file(s) remaining
    Completed 1.2 MiB/2.8 MiB (10.8 MiB/s) with 1 file(s) remaining
    Completed 1.5 MiB/2.8 MiB (12.9 MiB/s) with 1 file(s) remaining
    Completed 1.8 MiB/2.8 MiB (15.0 MiB/s) with 1 file(s) remaining
    Completed 2.0 MiB/2.8 MiB (17.0 MiB/s) with 1 file(s) remaining
    Completed 2.2 MiB/2.8 MiB (19.1 MiB/s) with 1 file(s) remaining
    Completed 2.5 MiB/2.8 MiB (21.1 MiB/s) with 1 file(s) remaining
    Completed 2.8 MiB/2.8 MiB (23.1 MiB/s) with 1 file(s) remaining
    Completed 2.8 MiB/2.8 MiB (13.0 MiB/s) with 1 file(s) remaining move: ../tmp/heap_dump.hprof to s3://fargate-test-cluster-logs/2023-05-02_16:02:53.hprof
    2023-05-02T17:02:54.705+01:00    Executing /bin/sh -c "kill -9 1"...
    2023-05-02T17:02:54.707+01:00    Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    2023-05-02T17:02:54.707+01:00    at MemoryApp.main(MemoryApp.java:13)

Dans l’exemple précédent de données de journal, l’AWS CLI est installée à l’aide de la commande yum install dans un conteneur qui exécute l’image Amazon Corretto 17. Si l’image du conteneur est basée sur un système d’exploitation (OS) différent, la commande change. Voici des exemples de commandes pour différents systèmes d’exploitation :

  • Fedora Linux : dnf install -y awscli
  • Debian : apt-get install -y awscli
  • Alpine Linux : apk add aws-cli

**Remarque :**Quel que soit le système d’exploitation, vous devez utiliser une commande équivalente à l’exemple de commande yum install qui installe l’AWS CLI.