Profiler des applications Java

Cette page explique comment modifier votre application Java afin de récupérer des données de profilage et les envoyer à votre projet Google Cloud Platform (GCP). Pour obtenir des informations générales sur le profilage, consultez la page Concepts du profilage.

Types de profil pour Java :

  • Temps CPU
  • Tas de mémoire (Alpha, nécessite Java 11 et l'environnement standard App Engine)
  • Durée d'exécution (non disponible pour l'environnement standard App Engine)

Versions de langages compatibles avec Java :

  • OpenJDK et JDK Oracle pour Java 7, 8, 9 ou 11.

Systèmes d'exploitation compatibles :

  • Versions de Linux dont la bibliothèque C standard est intégrée à glibc.

Environnements compatibles :

Activer l'API Profiler

Avant d'utiliser l'agent de profilage, assurez-vous que l'API Profiler sous-jacente est activée. Vous pouvez vérifier l'état de l'API et l'activer, si nécessaire, à l'aide de l'outil de ligne de commande gcloud du SDK Cloud ou de Cloud Console comme suit :

SDK Cloud

  1. Si vous n'avez pas encore installé le SDK Cloud sur votre poste de travail, consultez la page SDK Google Cloud.

  2. Exécutez la commande suivante :

    gcloud services enable cloudprofiler.googleapis.com
    

Pour en savoir plus, consultez la page sur gcloud services.

Cloud Console

  1. Accédez à la page API et services :

    Accéder à la page API et services

  2. Sélectionnez le projet à utiliser pour accéder à l'API.

  3. Cliquez sur le bouton Add APIs and Services (Ajouter des API et des services).

    Ajouter des API et des services

  4. Recherchez l'API Profiler.

  5. Dans les résultats de recherche, sélectionnez API Stackdriver Profiler.

  6. Si API activée s'affiche, l'API est déjà activée. Sinon, cliquez sur le bouton Activer.

Installer l'agent Profiler

Compute Engine

  1. Créez un répertoire d'installation pour l'agent Profiler (par exemple, /opt/cprof) :

     sudo mkdir -p /opt/cprof

  2. Téléchargez l'archive de l'agent à partir du dépôt storage.googleapis.com, puis extrayez-la dans le répertoire d'installation :

    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | sudo tar xzv -C /opt/cprof

GKE

Modifiez le Dockerfile pour créer un répertoire d'installation pour l'agent Profiler, téléchargez ensuite l'archive de l'agent et extrayez-la dans le répertoire d'installation :

RUN mkdir -p /opt/cprof && \
  wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
  | tar xzv -C /opt/cprof

Environnement flexible

Lorsque vous utilisez l'image de base de l'environnement d'exécution Java 8 de Google ou l'image de base de l'environnement d'exécution Java 9/Jetty 9, l'agent Profiler est préinstallé. Par conséquent, aucune étape supplémentaire n'est requise pour installer l'agent.

Toutes les autres images de base nécessitent l'installation de l'agent. Par exemple, le Dockerfile suivant contient les instructions d'utilisation de l'image openjdk:11-slim, qui permet d'installer l'agent Profiler, et définit les paramètres par défaut à utiliser lors du démarrage de l'application :

FROM openjdk:11-slim

COPY . .
RUN  apt-get update \
     && apt-get install wget \
     && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /opt/cprof && \
    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | tar xzv -C /opt/cprof

CMD ["java", "-agentpath:/opt/cprof/profiler_java_agent.so=[OPTION1],[OPTION2]", "-jar", "PATH/TO/YOUR/JARFILE"]

Pour utiliser ce Dockerfile dans l'environnement flexible App Engine, procédez comme suit :

Environnement standard

Lorsque vous utilisez l'environnement d'exécution Java 8 de Google ou l'environnement d'exécution Java 11 (version bêta), l'agent Profiler est préinstallé. Par conséquent, aucune étape supplémentaire n'est requise pour installer l'agent.

En dehors de GCP

  1. Créez un répertoire d'installation pour l'agent Profiler (par exemple, /opt/cprof) :

     sudo mkdir -p /opt/cprof

  2. Téléchargez l'archive de l'agent à partir du dépôt storage.googleapis.com, puis extrayez-la dans le répertoire d'installation :

    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | sudo tar xzv -C /opt/cprof

Charger l'agent Profiler

Pour profiler votre application, démarrez Java comme vous le feriez normalement pour exécuter votre programme, mais spécifiez les options de configuration de l'agent. Lorsque vous indiquez le chemin d'accès à la bibliothèque de l'agent, vous pouvez transmettre des options à cette dernière.

Pour l'environnement standard App Engine, l'agent est chargé et configuré automatiquement. Pour en savoir plus sur la configuration et le démarrage de votre programme, consultez la section Démarrer votre programme.

Configurer l'agent

Pour configurer l'agent de profilage, incluez l'indicateur -agentpath au démarrage de votre application :

 -agentpath:[INSTALL_DIR]/profiler_java_agent.so=[OPTION1],[OPTION2],[OPTION3]

Dans cette expression, [INSTALL_DIR] est le chemin d'accès de l'agent de profilage, et [OPTION1], [OPTION2] et [OPTION3] sont des options de configuration de l'agent. Par exemple, si vous remplacez [OPTION1] par -cprof_service=myapp dans l'expression précédente, vous définissez le nom du service sur myapp. L'ordre et le nombre des options ne sont soumis à aucune limite. Les options de configuration compatibles sont répertoriées dans le tableau suivant :

Option de l'agent Description
-cprof_service Si votre application n'est pas exécutée sur App Engine, cette option de configuration vous permet de définir le nom du service. Pour connaître les restrictions relatives au nom de service, reportez-vous à la section Arguments de nom et de version de service.
-cprof_service_version Lorsque vous souhaitez pouvoir analyser des données de profilage à l'aide de l'interface utilisateur de Profiler avec la version du service, spécifiez la version à l'aide de cette option Pour connaître les restrictions relatives à la version, reportez-vous à la section Arguments de nom et de version de service.
-cprof_project_id Lorsque vous exécutez une application en dehors de GCP, spécifiez votre ID de projet GCP à l'aide de cette option. Pour en savoir plus, consultez la section Profiler des applications s'exécutant en dehors de GCP.
-cprof_zone_name Lorsque votre application est exécutée sur GCP, l'agent de profilage détermine la zone en communiquant avec le service de métadonnées de Compute Engine. Si l'agent de profilage ne peut pas communiquer avec le service de métadonnées, vous devez utiliser cette option.
-cprof_gce_metadata_server_retry_count
-cprof_gce_metadata_server_retry_sleep_sec
Utilisées conjointement, ces deux options définissent le règlement relatif aux tentatives d'exécution suivi par l'agent Profiler lorsqu'il communique avec le service de métadonnées de Compute Engine pour récupérer votre ID de projet GCP et les informations concernant votre zone.

Le règlement par défaut consiste en trois tentatives à une seconde d'intervalle. Ce règlement suffit pour la plupart des configurations.
-cprof_cpu_use_per_thread_timers Pour les profils de temps CPU les plus précis, définissez cette option sur "true" (vrai). L'utilisation de cette option entraîne une augmentation des coûts par thread.

La valeur par défaut est Faux (false).
-cprof_force_debug_non_safepoints Par défaut, l'agent de profilage oblige la JVM à générer des informations de débogage pour l'intégralité du code généré juste-à-temps (JIT, Just-In-Time), en plus de générer des informations de débogage pour tous les points de restauration. En conséquence, vous obtenez des informations extrêmement précises sur la fonction et sur l'emplacement au niveau de la ligne pour les profils de tas de mémoire et de Temps CPU, en échange de coûts supplémentaires. Pour désactiver les informations de débogage relatives au code juste-à-temps (JIT, Just-In-Time), définissez cette option sur "false" (faux).

La valeur par défaut est Vrai (true).
-cprof_wall_num_threads_cutoff Par défaut, les profils de durée d'exécution ne sont pas récupérés si le nombre total de threads dans l'application est supérieur à 4 096. Cette limite garantit un coût minime relatif à l'acheminement de la pile de threads lors de la collecte de profils Si votre service comporte normalement plus de 4 096 threads et si vous acceptez de payer des coûts supplémentaires pour collecter des données de profilage, vous pouvez augmenter cette limite à l'aide de cet indicateur.

La limite par défaut est de 4 096 threads.
-cprof_enable_heap_sampling Pour activer le profilage de tas de mémoire pour Java 11 ou une version supérieure, définissez
-cprof_enable_heap_sampling sur true (vrai). Le profilage de tas de mémoire n'est pas compatible avec Java 10 ou une version antérieure.

Le profilage de tas de mémoire est désactivé par défaut.

Lorsque vous activez le profilage de tas de mémoire, l'intervalle d'échantillonnage est défini sur 512 Kio par défaut. Cet intervalle suffit pour la plupart des applications et implique un coût inférieur à 0,5 % pour l'application. Les intervalles d'échantillonnage compris entre 256 Kio (262144) et 1024 Kio (1048576) sont compatibles. Par exemple, pour définir l'intervalle d'échantillonnage sur 256 Kio, et ainsi doubler le taux d'échantillonnage, ajoutez l'option de l'agent suivante :

-cprof_heap_sampling_interval=262144
De même, pour définir l'intervalle d'échantillonnage sur 1 024 Kio, et ainsi réduire de moitié le taux d'échantillonnage, ajoutez l'option de l'agent suivante :

-cprof_heap_sampling_interval=1048576

Arguments de nom et de version de service

Lorsque vous chargez l'agent Profiler, vous devez spécifier un argument de nom de service et un argument facultatif de version de service pour le configurer.

Le nom de service permet à Profiler de collecter des données de profilage pour toutes les instances dupliquées de ce service. Le service du profileur assure un taux de collecte de l'ordre d'un profil par minute, en moyenne, et ce pour chaque nom de service dans chaque combinaison de zones et de versions de service.

Par exemple, si deux versions d'un service s'exécutent sur des instances dupliquées dans trois zones, le profileur créera en moyenne six profils par minute pour ce service.

Si vous utilisez différents noms de service pour vos instances dupliquées, votre service sera profilé plus souvent que nécessaire, entraînant une surcharge proportionnelle.

Lorsque vous sélectionnez un nom de service, respectez ces instructions :

  • Choisissez un nom qui représente clairement le service dans votre architecture d'application. Le choix du nom de service est moins important si vous n'exécutez qu'un seul service ou qu'une seule application. En revanche, il est plus important lorsque votre application s'exécute sous la forme d'un ensemble de microservices, par exemple.

  • Assurez-vous de ne pas utiliser de valeurs spécifiques au processus, telles qu'un ID de processus, dans la chaîne du nom de service.

  • La chaîne du nom de service doit correspondre à l'expression régulière ci-dessous :

    ^[a-z]([-a-z0-9_.]{0,253}[a-z0-9])?$

Nous vous recommandons d'utiliser une chaîne statique telle que imageproc-service comme nom de service.

La version de service est facultative. Si vous la spécifiez, Profiler peut regrouper les informations de profilage de plusieurs instances et les afficher correctement. Vous pouvez spécifier ce paramètre pour marquer différentes versions de vos services au fur et à mesure de leur déploiement. L'interface utilisateur de Profiler vous permet de filtrer les données par version de service. De cette façon, vous pouvez comparer les performances des versions de code les plus anciennes et les plus récentes.

La valeur de l'argument service-version est une chaîne de forme libre, mais les valeurs de cet argument ressemblent généralement à des numéros de version, par exemple 1.0.0 ou 2.1.2.

Démarrer votre programme

Compute Engine

Démarrez Java comme vous le feriez normalement pour exécuter votre programme, mais spécifiez les options de configuration de l'agent comme suit :

java \
    -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myservice,-cprof_service_version=1.0.0 \
    [JAVA OPTIONS] -jar PATH/TO/YOUR/JARFILE [PROGRAM OPTIONS]

GKE

Modifiez le Dockerfile du conteneur de service pour qu'il démarre Java comme vous le feriez normalement pour exécuter votre programme, puis ajoutez les options de configuration de l'agent indiquées ci-dessous :

CMD ["java", \
    "-agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myservice,-cprof_service_version=1.0.0", \
    "-javaopt1=val1", "-javaopt2=val2", "-jar", "PATH/TO/YOUR/JARFILE", \
    "-programopt1=val1", "-programopt2=val2"]

Environnement flexible

Modifiez le fichier de configuration app.yaml en définissant la variable d'environnement PROFILER_ENABLE. Démarrez ensuite votre programme comme d'habitude :

env_variables:
   PROFILER_ENABLE: true

Pour en savoir plus, consultez la section Définir des variables d'environnement.

Environnement standard

Modifiez le fichier de configuration app.yaml ou appengine-web.xml en spécifiant la variable d'environnement GAE_PROFILER_MODE. Profiler collectera les profils de temps CPU et de tas de mémoire, une fois par minute en moyenne, sur toutes les instances du même déploiement :

app.yaml:

env_variables:
   GAE_PROFILER_MODE: cpu,heap

appengine-web.xml:

  <env-variables>
    <env-var name="GAE_PROFILER_MODE" value="cpu,heap" />
  </env-variables>

Démarrez ensuite votre programme comme d'habitude.

Pour en savoir plus, consultez la section Définir des variables d'environnement.

Journaliser avec l'agent

L'agent de profilage peut collecter des informations de journalisation pour l'environnement flexible App Engine, Compute Engine et GKE. L'agent de profilage est compatible avec les niveaux de journalisation suivants :

  • 0 : journalise tous les messages. Niveau de journalisation par défaut.
  • 1 : journalise les messages d'avertissement, les messages d'erreur et les messages d'erreur fatale.
  • 2 : journalise les messages d'erreur et les messages d'erreur fatale.
  • 3 : ne journalise que les messages d'erreur fatale et arrête l'application.

Pour activer l'écriture de journaux sur l'erreur standard avec le niveau de journalisation par défaut, ajoutez l'indicateur -logtostderr à la configuration -agentpath.

Pour que le niveau de journalisation n'enregistre que les messages d'erreur et les messages d'erreur fatale, ajoutez l'indicateur -minloglevel=2 à la configuration -agentpath.

Par exemple, pour activer la journalisation des messages d'erreur et des messages d'erreur fatale sur l'erreur standard, ajoutez les indicateurs -logtostderr et ‑minloglevel=2 à la configuration -agentpath :

 java -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myapp,-logtostderr,-minloglevel=2 -jar myApp.jar

Étape suivante

Pour en savoir plus sur le graphique et les commandes de Profiler, consultez la page Utiliser l'interface de Stackdriver Profiler. Pour obtenir des informations avancées, consultez les sections suivantes :

Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Stackdriver Profiler