Profilazione delle applicazioni Java

Questa pagina descrive come modificare l'applicazione Java per acquisire i dati di profilazione e inviarli al progetto Google Cloud. Per informazioni generali sulla profilazione, consulta Concetti di profilazione.

Tipi di profilo per Java:

  • Tempo CPU
  • Heap (richiede Java 11 o l'ambiente standard di App Engine, disattivato per impostazione predefinita)
  • Tempo totale di esecuzione (non disponibile per l'ambiente standard Java 8 App Engine)

Versioni del linguaggio Java supportate:

  • JVM basate su HotSpot (incluse Oracle JDK e alcune build OpenJDK) per Java 8, 11 o versioni successive.

Versioni dell'agente di profilazione supportate:

  • È supportata la release più recente dell'agente. In genere, le release precedenti a un anno non sono supportate. Ti consigliamo di utilizzare una versione rilasciata di recente dell'agente.

Sistemi operativi supportati:

  • Linux. La profilazione delle applicazioni Java è supportata per i kernel Linux la cui libreria C standard è implementata con glibc o con musl. Per informazioni sulla configurazione specifiche per i kernel Linux Alpine, consulta Esecuzione su Linux Alpine.

Ambienti supportati:

Abilitazione dell'API Profiler

Prima di utilizzare l'agente di profilazione, assicurati che l'elemento sottostante L'API Profiler è abilitata. Puoi controllare lo stato dell'API e attivarla se necessario utilizzando Google Cloud CLI o la console Google Cloud:

Interfaccia a riga di comando gcloud

  1. Se non hai già installato Google Cloud CLI sul tuo consulta la documentazione di Google Cloud CLI.

  2. Esegui questo comando:

    gcloud services enable cloudprofiler.googleapis.com
    

Per ulteriori informazioni, consulta gcloud services.

Console Google Cloud

  1. Enable the required API.

    Enable the API

  2. Se viene visualizzato API abilitata, l'API è già abilitata. In caso contrario, fai clic sul pulsante Attiva.

Installazione dell'agente Profiler

Compute Engine

  1. Crea una directory di installazione, ad esempio /opt/cprof, per Agente Profiler:

     sudo mkdir -p /opt/cprof

  2. Scarica l'archivio degli agenti da storage.googleapis.com repository ed estrarlo nella directory di installazione:

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

GKE

Modifica Dockerfile per creare una directory di installazione per l'agente Profiler, scarica l'archivio dell'agente e poi estrailo nella directory di installazione.

Linux (libreria C basata su glibc):

Utilizza il seguente comando di installazione:

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

Linux Alpine (libreria C basata su musl):

Utilizza il seguente comando di installazione:

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

Ambiente flessibile

Quando utilizzi il Immagine di base del runtime Java 8 il runtime Java 9 / Jetty 9 di base, l'agente Profiler è preinstallato, quindi non sono necessari passaggi aggiuntivi per installare l'agente.

Per tutte le altre immagini di base, devi installare l'agente. Ad esempio, il Dockerfile seguente contiene le istruzioni per utilizzare l'immagine openjdk:11-slim, installare l'agente Profiler e definisce i parametri predefiniti da utilizzare all'avvio dell'applicazione:

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_JAR_FILE"]

Per utilizzare questo Dockerfile con l'ambiente flessibile di App Engine, devi procedi nel seguente modo:

  • Sostituisci OPTION1 e OPTION2 con i valori di configurazione dell'agente necessari per la tua applicazione e PATH_TO_YOUR_JAR_FILE con il percorso del file JAR.
  • Inserisci Dockerfile nella stessa directory del file app.yaml.
  • Modifica il file app.yaml per specificare un runtime personalizzato. Per ulteriori informazioni, consulta Creare runtime personalizzati.

Ambiente standard

Quando utilizzi l'ambiente di runtime Java, l'agente Profiler è preinstallato, quindi i passaggi aggiuntivi da eseguire per installare l'agente. Per Java 11 e versioni successive, è preinstallato in /opt/cprof.

Al di fuori di Google Cloud

  1. Crea una directory di installazione, ad esempio /opt/cprof, per Agente Profiler:

     sudo mkdir -p /opt/cprof

  2. Scarica l'archivio dell'agente dal repository storage.googleapis.com e estrailo nella directory di installazione:

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

Per elencare tutte le versioni dell'agente disponibili per il download, esegui questo comando:

gcloud storage ls gs://cloud-profiler/java/cloud-profiler-*

La risposta al comando è simile alla seguente:

gs://cloud-profiler/java/cloud-profiler-java-agent_20191014_RC00.tar.gz
gs://cloud-profiler/java/cloud-profiler-java-agent_20191021_RC00.tar.gz
gs://cloud-profiler/java/cloud-profiler-java-agent_20191028_RC00.tar.gz

Per scaricare una versione specifica dell'agente, passa il relativo URL a il comando di download. Ad esempio, per scaricare l'agente creato il 28 ottobre 2019, utilizzeresti la seguente affermazione:

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

La versione dell'agente viene registrata durante l'inizializzazione.

Caricamento dell'agente Profiler

Per eseguire il profiling dell'applicazione, avvia Java come faresti normalmente per eseguire il programma, ma specifica le opzioni di configurazione dell'agente. Specifica il percorso della raccolta di agenti e puoi passare opzioni alla raccolta.

Per l'ambiente standard App Engine, l'agente viene caricato automaticamente e configurato. Passa direttamente ad Avvio del programma. per informazioni dettagliate sulla configurazione e sull'avvio del programma.

Configurazione agente

Per configurare l'agente di profilazione, includi il flag -agentpath all'avvio la tua applicazione:

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

In questa espressione, INSTALL_DIR è il percorso dell'agente di profiling, mentre OPTION1, OPTION2 e OPTION3 sono opzioni di configurazione dell'agente. Per ad esempio, se sostituisci OPTION1 con -cprof_service=myapp nella precedente , quindi imposti il nome del servizio su myapp. Non esistono limitazioni sul numero di opzioni o sul loro ordine. Le opzioni di configurazione supportate sono elencate nella tabella seguente:

Opzione agente Descrizione
-cprof_service Se la tua applicazione non è in esecuzione su App Engine, devi utilizza questa opzione di configurazione per impostare il nome del servizio. Per le limitazioni relative ai nomi dei servizi, vedi Argomenti Nome servizio e versione.
-cprof_service_version Se vuoi avere la possibilità di analizzare i dati di profilazione utilizzando il UI Profiler in base alla versione del servizio, usa questa opzione per impostare la versione. Per i limiti di versione, vedi Argomenti Nome servizio e versione.
-cprof_project_id Quando esegui l'operazione al di fuori di Google Cloud, utilizza questa opzione per specificare l'ID progetto Google Cloud. Per ulteriori informazioni, consulta Eseguire il profiling delle applicazioni in esecuzione all'esterno di Google Cloud.
-cprof_zone_name Quando la tua applicazione è in esecuzione su Google Cloud, l'agente di profilazione determina la zona tramite di comunicare con Servizio di metadati di Compute Engine. Se l'agente di profilazione non riesce a comunicare con il servizio di metadati, devi utilizzare questa opzione.
-cprof_gce_metadata_server_retry_count
-cprof_gce_metadata_server_retry_sleep_sec
Insieme, queste due opzioni definiscono il criterio di ripetizione utilizzato dall'agente del profiler quando comunica con il servizio di metadati di Compute Engine. per raccogliere l'ID progetto Google Cloud e le informazioni sulla zona.

Il criterio predefinito è di riprovare fino a 3 volte, aspettando 1 secondo tra un tentativo e l'altro. Questo criterio è sufficiente per la maggior parte delle configurazioni.
-cprof_cpu_use_per_thread_timers Per i profili di tempo della CPU più precisi, imposta questa opzione su true. L'utilizzo di questa opzione comporta un aumento del sovraccarico per thread.

Il valore predefinito è false.
-cprof_force_debug_non_safepoints Per impostazione predefinita, l'agente di profilazione obbliga la JVM a generare il debug per il codice generato JIT, in aggiunta alla generazione delle informazioni di debug per tutti i punti di interesse. Il risultato è la funzione più accurata e le informazioni sulla posizione a livello di riga per il tempo della CPU e i profili dell'heap a spese di un overhead aggiuntivo dell'agente. Puoi disattiva la generazione di informazioni di debug per il codice JIT impostando questa opzione su false.

Il valore predefinito è true.
-cprof_wall_num_threads_cutoff Per impostazione predefinita, i profili del wall non vengono raccolti se il numero totale di thread nell'applicazione è maggiore di 4096. Il limite garantisce che durante il profilo raccolta, il costo di attraversare lo stack di thread è minimo. Se il servizio normalmente ha più di 4096 thread e se vuoi per raccogliere i dati di profilazione a scapito di costi aggiuntivi, usa questo flag per aumentare il limite.

Il limite predefinito è 4096 thread.
-cprof_enable_heap_sampling Per attivare la profilazione dell'heap per Java 11 e versioni successive, imposta
-cprof_enable_heap_sampling=true. La profilazione dell'heap non è supportata per Java 10 e versioni precedenti.

La profilazione dell'heap è disattivata per impostazione predefinita.

Quando abiliti la profilazione heap, l'intervallo di campionamento viene impostato su 512 KiB per impostazione predefinita. Questo intervallo è sufficiente per la maggior parte delle applicazioni e comporta meno dello 0,5% di overhead per l'applicazione. Sono supportati intervalli di campionamento da 256 KiB (262144) a 1024 KiB (1048576). Ad esempio, per impostare l'intervallo di campionamento su 256 KiB, che raddoppia la frequenza di campionamento, aggiungi l'opzione dell'agente:
-cprof_heap_sampling_interval=262144
Analogamente, per impostare l'intervallo di campionamento su 1024 KiB, dimezzando frequenza di campionamento, aggiungi l'opzione dell'agente:
-cprof_heap_sampling_interval=1048576
Se attivi questo tipo di profilo, specifica una nuova versione del servizio quando esegui il deployment dell'applicazione. Per ulteriori informazioni, vedi Perché non ho i dati per un tipo di profilo specifico?

Argomenti per nome e versione del servizio

Quando carichi l'agente Profiler, specifichi un argomento service-name e un un argomento facoltativo service-version per configurarlo.

Il nome del servizio consente a Profiler di raccogliere i dati di profilazione per tutte le repliche del servizio. Il servizio profiler garantisce tasso di raccolta di un profilo al minuto, in media, per ogni servizio in ogni combinazione di versioni e zone del servizio.

Ad esempio, se hai un servizio con due versioni in esecuzione su repliche in tre zone, il profiler creerà in media 6 profili al minuto per quel servizio.

Se utilizzi nomi di servizi diversi per le repliche, il servizio verrà sottoposto a profilazione più spesso del necessario, con un overhead di conseguenza più elevato.

Quando selezioni un nome di servizio:

  • Scegli un nome che rappresenti chiaramente il servizio nell'architettura dell'applicazione. La scelta del nome del servizio è meno importante se esegui solo un singolo servizio o una singola applicazione. È più importante che la tua applicazione viene eseguito come un insieme di microservizi, ad esempio.

  • Assicurati di non utilizzare valori specifici per il processo, ad esempio un ID processo, nella stringa service-name.

  • La stringa del nome del servizio deve corrispondere a questa espressione regolare:

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

Una buona linea guida è utilizzare una stringa statica come imageproc-service come nome del servizio.

La versione del servizio è facoltativa. Se specifichi la versione del servizio, Profiler può aggregare le informazioni di profilazione da più le istanze VM e visualizzarle correttamente. Può essere utilizzato per contrassegnare versioni diverse degli tuoi servizi durante il loro dispiegamento. La UI di Profiler ti consente filtrare i dati in base alla versione del servizio; In questo modo, puoi confrontare il rendimento delle versioni più vecchie e più recenti del codice.

Il valore dell'argomento service-version è una stringa in formato libero, ma valori per questo argomento generalmente sono i numeri di versione, ad esempio 1.0.0 o 2.1.2.

Avvio del programma

Compute Engine

Avvia Java come faresti normalmente per eseguire il tuo programma e aggiungi il le opzioni di configurazione dell'agente:

java \
    -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myapp,-cprof_service_version=1.0.0 \
    JAVA_OPTIONS -jar PATH_TO_YOUR_JAR_FILE PROGRAM_OPTIONS

GKE

Modifica il file Dockerfile del contenitore del servizio per avviare Java come faresti normalmente per eseguire il programma e aggiungi le opzioni di configurazione dell'agente:

CMD ["java", \
    "-agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myapp,-cprof_service_version=1.0.0", \
     "-jar", "PATH_TO_YOUR_JAR_FILE" ]
    

Ambiente flessibile

Modifica il file di configurazione app.yaml per impostare la variabile di ambiente PROFILER_ENABLE. Quindi avvia il programma come di consueto:

env_variables:
   PROFILER_ENABLE: true

Per ulteriori informazioni, consulta la sezione Definire le variabili di ambiente.

Ambiente standard

Ambiente di runtime Java 21

Se non utilizzi i servizi in bundle precedenti, attiva la raccolta del profiler modificando il file app.yaml in modo da specificare il flag agentpath utilizzando uno dei seguenti metodi:

  • Imposta il parametro Variabile di ambiente JAVA_TOOL_OPTIONS:

    runtime: java21
    env_variables:
      JAVA_TOOL_OPTIONS: "-agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true"
    
  • Specifica agentpath utilizzando l'elemento entrypoint:

    runtime: java21
    entrypoint: java \
      -agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true \
      Main.java
    

Se utilizzi i servizi in bundle legacy, attiva la raccolta profiler modificando il valore appengine-web.xml file per specificare il flag agentpath utilizzando uno dei seguenti metodi:

  • Imposta il parametro Variabile di ambiente JAVA_USER_OPTS:

    <?xml version="1.0" encoding="utf-8"?>
    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <env-variables>
    <env-var name="JAVA_USER_OPTS" value="-agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true" />
    </env-variables>
    </appengine-web-app>
  • Imposta la variabile di ambiente CPROF_ENABLE:

    <?xml version="1.0" encoding="utf-8"?>
    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <env-variables>
    <env-var name="CPROF_ENABLE" value="-agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true" />
    </env-variables>
    </appengine-web-app>
  • Specifica agentpath utilizzando il parametro Elemento entrypoint:

    <?xml version="1.0" encoding="utf-8"?>
    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
      <entrypoint>
       java
       -agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true
      </entrypoint>
    </appengine-web-app>

Se per la raccolta è configurato un nuovo tipo di profilo, assicurati di specificare un una nuova versione del servizio quando esegui il deployment dell'applicazione. Per ulteriori informazioni, consulta Perché non ho dati per un tipo di profilo specifico?

Logging agente

L'agente di profilazione può segnalare informazioni di log per l'ambiente flessibile App Engine, Compute Engine e GKE. L'agente di profilazione supporta i seguenti livelli di logging:

  • 0: registra tutti i messaggi. Livello di registrazione predefinito.
  • 1: registra avvisi, errori e messaggi di errore irreversibile.
  • 2: registra i messaggi di errore e di errore irreversibile.
  • 3: registra solo i messaggi irreversibili e interrompi l'applicazione.

Per abilitare la scrittura dei log in errore standard con il livello di logging predefinito, aggiungi -logtostderr alla configurazione -agentpath.

Per impostare il livello di logging in modo da registrare solo i messaggi di errore e fatali, aggiungere -minloglevel=2 alla configurazione -agentpath.

Ad esempio, per attivare il logging dei messaggi di errore e fatali in errore standard, aggiungere -logtostderr e ‑minloglevel=2 alla configurazione-agentpath:

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

Risoluzione dei problemi

Questa sezione elenca i problemi specifici alla profilazione delle applicazioni Java. Consulta la sezione Risoluzione dei problemi. per ricevere assistenza in merito a problemi comuni.

Comportamento Causa Soluzione
Hai abilitato più profiler heap e non hai dati del profilo. L'utilizzo simultaneo di più profiler dell'heap disattiva tutto il supporto per il profiling dell'heap per Java. Si tratta di una limitazione JVM. Attiva un profiler.

Esecuzione con Linux alpino

L'agente di profilazione Java per Linux Alpine è supportato solo per le configurazioni di Google Kubernetes Engine.

Per installare l'agente di profilazione Java più recente per Linux Alpine, consulta Installazione dell'agente di profilazione.

Errore di autenticazione

Se utilizzi immagini Docker eseguite con Linux alpino (ad es. golang:alpine o solo alpine), potrebbe essere visualizzato il seguente errore di autenticazione:

connection error: desc = "transport: authentication handshake failed: x509: failed to load system roots and no roots provided"

Tieni presente che per visualizzare l'errore devi aver attivato la registrazione degli agenti.

L'errore indica che le immagini Docker con Linux Alpine non hanno certificati SSL radice installati per impostazione predefinita. Questi certificati sono necessari per l'agente di profilazione per comunicare con l'API profiler. Per risolvere questo errore, aggiungi il seguente comando apk al tuo Dockerfile:

FROM alpine
...
RUN apk add --no-cache ca-certificates

Devi quindi ricreare la build ed eseguire nuovamente il deployment dell'applicazione.

Passaggi successivi