Criação de perfis de aplicações Java

Esta página descreve como modificar a sua aplicação Java para capturar dados de criação de perfis e enviar esses dados para o seu projeto do Google Cloud. Google CloudPara ver informações gerais acerca da criação de perfis, consulte o artigo Conceitos de criação de perfis.

Tipos de perfis para Java:

  • Tempo da CPU
  • Heap (requer o Java 11 ou o ambiente padrão do App Engine, desativado por predefinição)
  • Tempo total (não disponível para o ambiente padrão do App Engine Java 8)

Versões do idioma Java compatíveis:

  • JVMs baseadas em HotSpot (incluindo o Oracle JDK e algumas compilações do OpenJDK) para Java 8, 11 ou posterior.

Versões do agente de criação de perfis suportadas:

  • A versão mais recente do agente é suportada. Geralmente, as versões com mais de um ano não são suportadas. Recomendamos que use a versão do agente lançada mais recentemente.

Sistemas operativos compatíveis:

  • Linux. A criação de perfis de aplicações Java é suportada para kernels Linux cuja biblioteca C padrão é implementada com glibc ou com musl. Para ver informações de configuração específicas dos kernels do Linux Alpine, consulte o artigo Execução no Linux Alpine.

Ambientes suportados:

Ativar a API Profiler

Antes de usar o agente de criação de perfis, certifique-se de que a API Profiler subjacente está ativada. Pode verificar o estado da API e ativá-la, se necessário, através da CLI do Google Cloud ou da Google Cloud consola:

CLI gcloud

  1. Se ainda não instalou a CLI do Google Cloud na sua estação de trabalho, consulte a documentação da CLI do Google Cloud.

  2. Execute o seguinte comando:

    gcloud services enable cloudprofiler.googleapis.com
    

Para mais informações, consulte gcloud services.

Google Cloud consola

  1. Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  2. Se for apresentada a mensagem API ativada, significa que a API já está ativada. Caso contrário, clique no botão Ativar.

Conceda a função do IAM à conta de serviço

Se estiver a implementar a sua aplicação em Google Cloud recursos e se estiver a usar a conta de serviço predefinida e não tiver modificado as concessões de funções para essa conta de serviço, pode ignorar esta secção.

Se realizar qualquer uma das seguintes ações, tem de conceder à conta de serviço a função do IAM de agente do Cloud Profiler (roles/cloudprofiler.agent):

  1. Está a usar a conta de serviço predefinida, mas modificou as concessões de funções.
  2. Está a usar uma conta de serviço criada pelo utilizador.
  3. Está a usar a identidade da carga de trabalho. Conceda a função de agente do Cloud Profiler à conta de serviço do Kubernetes.

Pode conceder uma função de IAM a uma conta de serviço através da Google Cloud consola ou da CLI do Google Cloud. Por exemplo, pode usar o comando gcloud projects add-iam-policy-binding:

gcloud projects add-iam-policy-binding GCP_PROJECT_ID \
    --member serviceAccount:MY_SVC_ACCT_ID@GCP_PROJECT_ID.iam.gserviceaccount.com \
    --role roles/cloudprofiler.agent

Antes de usar o comando anterior, substitua o seguinte:

  • GCP_PROJECT_ID: o ID do seu projeto.
  • MY_SVC_ACCT_ID: o nome da sua conta de serviço.

Para ver informações detalhadas, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.

Instalar o agente do Profiler

Compute Engine

  1. Crie um diretório de instalação, por exemplo, /opt/cprof, para o agente do Profiler:

     sudo mkdir -p /opt/cprof

  2. Transfira o arquivo do agente do storage.googleapis.com repositório e extraia-o para o diretório de instalação:

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

GKE

Modifique o Dockerfile para criar um diretório de instalação para o agente do Profiler, transfira o arquivo do agente e, em seguida, extraia o arquivo para o diretório de instalação.

Linux (biblioteca C baseada no glibc):

Use o seguinte comando de instalação:

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 (biblioteca C baseada no musl):

Use o seguinte comando de instalação:

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

Ambiente flexível

Quando usa a imagem base do tempo de execução do Java 8 da Google ou a imagem base do tempo de execução do Java 9 / Jetty 9, o agente do Profiler está pré-instalado, pelo que não tem de realizar passos adicionais para instalar o agente.

Para todas as outras imagens base, tem de instalar o agente. Por exemplo, o seguinte Dockerfile contém as instruções para usar a imagem openjdk:11-slim, instalar o agente do Profiler e define os parâmetros predefinidos a usar ao iniciar a aplicação:

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

Para usar esta Dockerfile com o ambiente flexível do App Engine, tem de fazer o seguinte:

  • Substitua OPTION1 e OPTION2 pelos valores de configuração do agente necessários para a sua aplicação e substitua PATH_TO_YOUR_JAR_FILE pelo caminho para o seu ficheiro JAR.
  • Coloque o ficheiro Dockerfile no mesmo diretório que o ficheiro app.yaml.
  • Modifique o ficheiro app.yaml para especificar um tempo de execução personalizado. Para mais informações, consulte o artigo Criar tempos de execução personalizados.

Ambiente padrão

Quando usa o ambiente de execução Java, o agente do Profiler está pré-instalado, pelo que não tem de realizar passos adicionais para instalar o agente. Para a versão 11 e posteriores do Java, está pré-instalado no /opt/cprof.

Fora de Google Cloud

  1. Crie um diretório de instalação, por exemplo, /opt/cprof, para o agente do Profiler:

     sudo mkdir -p /opt/cprof

  2. Transfira o arquivo do agente do storage.googleapis.com repositório e extraia-o para o diretório de instalação:

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

Para apresentar uma lista de todas as versões do agente disponíveis para transferência, execute o seguinte comando:

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

A resposta do comando é semelhante à seguinte:

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

Para transferir uma versão específica do agente, transmita o respetivo URL para o comando de transferência. Por exemplo, para transferir o agente criado a 28 de outubro de 2019, usaria a seguinte declaração:

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

A versão do agente é registada durante a respetiva inicialização.

A carregar o agente do Profiler

Para criar um perfil da sua aplicação, inicie o Java como faria normalmente para executar o seu programa, mas especifique as opções de configuração do agente. Especifica o caminho para a biblioteca do agente e pode transmitir opções para a biblioteca.

Para o ambiente padrão do App Engine, o agente é carregado e configurado automaticamente. Avançar para Iniciar o programa, para ver detalhes sobre a configuração e o início do programa.

Configuração do agente

Para configurar o agente de criação de perfis, inclua a flag -agentpath ao iniciar a aplicação:

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

Nesta expressão, INSTALL_DIR é o caminho para o agente de criação de perfis, enquanto OPTION1, OPTION2 e OPTION3 são opções de configuração do agente. Por exemplo, se substituir OPTION1 por -cprof_service=myapp na expressão anterior, define o nome do serviço como myapp. Não existe restrição quanto ao número de opções nem à respetiva ordem. As opções de configuração suportadas estão listadas na tabela seguinte:

Opção de agente Descrição
-cprof_service Se a sua aplicação não estiver a ser executada no App Engine, tem de usar esta opção de configuração para definir o nome do serviço. Para restrições de nomes de serviços, consulte o artigo Argumentos de nome e versão do serviço.
-cprof_service_version Quando quiser analisar os dados de criação de perfis através da IU do Profiler por versão do serviço, use esta opção para definir a versão. Para restrições de versão, consulte os Argumentos de nome e versão do serviço.
-cprof_project_id Quando estiver a executar fora do Google Cloud, use esta opção para especificar o ID do projeto Google Cloud . Para mais informações, consulte o artigo Criar perfis de aplicações em execução fora do Google Cloud.
-cprof_zone_name Quando a sua aplicação está em execução no Google Cloud, o agente de criação de perfis determina a zona através da comunicação com o serviço de metadados do Compute Engine. Se o agente de criação de perfis não conseguir comunicar com o serviço de metadados, tem de usar esta opção.
-cprof_gce_metadata_server_retry_count
-cprof_gce_metadata_server_retry_sleep_sec
Em conjunto, estas duas opções definem a política de repetição que o agente do Profiler usa quando comunica com o serviço de metadados do Compute Engine. para recolher o seu Google Cloud ID do projeto e informações da zona.

A política predefinida é repetir até 3 vezes, aguardando 1 segundo entre as tentativas. Esta política é suficiente para a maioria das configurações.
-cprof_cpu_use_per_thread_timers Para os perfis de tempo da CPU mais precisos, defina esta opção como verdadeira. A utilização desta opção resulta num aumento da sobrecarga por segmento.

O valor predefinido é false.
-cprof_force_debug_non_safepoints Por predefinição, o agente de criação de perfis força a JVM a gerar informações de depuração para todo o código gerado no momento (JIT), além de gerar informações de depuração para todos os pontos de segurança. Isto resulta nas informações de localização ao nível da linha e da função mais precisas para o tempo de CPU e os perfis de memória ao custo de uma sobrecarga adicional do agente. Pode desativar a geração de informações de depuração para código JIT definindo esta opção como falsa.

O valor predefinido é True.
-cprof_wall_num_threads_cutoff Por predefinição, os perfis de parede não são recolhidos se o número total de threads na aplicação exceder 4096. O limite garante que, durante a recolha de perfis, o custo de percorrer a pilha de threads é mínimo. Se o seu serviço tiver normalmente mais de 4096 threads e quiser recolher dados de criação de perfis à custa de sobrecarga adicional, use esta flag para aumentar o limite.

O limite predefinido é de 4096 threads.
-cprof_enable_heap_sampling Para ativar a criação de perfis de memória dinâmica para o Java 11 e superior, defina
-cprof_enable_heap_sampling=true. A criação de perfis de memória dinâmica não é suportada para o Java 10 e inferior.

A criação de perfis de memória está desativada por predefinição.

Quando ativa a criação de perfis de memória, o intervalo de amostragem é definido como 512 KiB por predefinição. Este intervalo é suficiente para a maioria das aplicações e incorre num custo adicional inferior a 0,5% para a aplicação. São suportados intervalos de amostragem de 256 KiB (262144) a 1024 KiB (1048576). Por exemplo, para definir o intervalo de amostragem como 256 KiB, o que duplica a taxa de amostragem, adicione a opção do agente:
-cprof_heap_sampling_interval=262144
Da mesma forma, para definir o intervalo de amostragem para 1024 KiB, o que reduz a taxa de amostragem para metade, adicione a opção do agente:
-cprof_heap_sampling_interval=1048576
Se ativar este tipo de perfil, especifique uma nova versão do serviço quando implementar a sua aplicação. Para mais informações, consulte o artigo Por que motivo não tenho dados para um tipo de perfil específico?

Argumentos de nome e versão do serviço

Quando carrega o agente do Profiler, especifica um argumento service-name e um argumento service-version opcional para o configurar.

O nome do serviço permite que o Profiler recolha dados de criação de perfis para todas as réplicas desse serviço. O serviço de criação de perfis garante uma taxa de recolha de um perfil por minuto, em média, para cada nome de serviço em todas as combinações de versões e zonas de serviço.

Por exemplo, se tiver um serviço com duas versões em execução em réplicas em três zonas, o criador de perfis cria uma média de 6 perfis por minuto para esse serviço.

Se usar nomes de serviços diferentes para as suas réplicas, o serviço é perfilado com mais frequência do que o necessário, com uma sobrecarga correspondentemente mais elevada.

Ao selecionar um nome do serviço:

  • Escolha um nome que represente claramente o serviço na arquitetura da sua aplicação. A escolha do nome do serviço é menos importante se executar apenas um único serviço ou aplicação. É mais importante se a sua aplicação for executada como um conjunto de microsserviços, por exemplo.

  • Certifique-se de que não usa valores específicos do processo, como um ID do processo, na string service-name.

  • A string service-name tem de corresponder a esta expressão regular:

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

Uma boa diretriz é usar uma string estática como imageproc-service como o nome do serviço.

A versão do serviço é opcional. Se especificar a versão do serviço, o Profiler pode agregar informações de criação de perfis de várias instâncias e apresentá-las corretamente. Pode ser usado para marcar diferentes versões dos seus serviços à medida que são implementadas. A IU do Profiler permite-lhe filtrar os dados por versão do serviço. Desta forma, pode comparar o desempenho de versões mais antigas e mais recentes do código.

O valor do argumento service-version é uma string de forma livre, mas os valores deste argumento têm normalmente o aspeto de números de versão, por exemplo, 1.0.0 ou 2.1.2.

Iniciar o programa

Compute Engine

Inicie o Java como faria normalmente para executar o seu programa e adicione as opções de configuração do 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

Modifique o Dockerfile do contentor de serviço para iniciar o Java como faria normalmente para executar o seu programa e adicione as opções de configuração do 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 flexível

Modifique o ficheiro de configuração app.yaml para definir a variável de ambiente PROFILER_ENABLE. Em seguida, inicie o programa como habitualmente:

env_variables:
   PROFILER_ENABLE: true

Consulte o artigo Definir variáveis de ambiente para mais informações.

Ambiente padrão

Java 21 runtime environment

Se não usar serviços agrupados antigos, ative a recolha do Profiler modificando o ficheiro app.yaml para especificar a flag agentpath através de qualquer um dos seguintes métodos:

  • Defina a variável de ambiente JAVA_TOOL_OPTIONS:

    runtime: java21
    env_variables:
      JAVA_TOOL_OPTIONS: "-agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true"
    
  • Especifique o agentpath através do elemento entrypoint:

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

Se usar serviços agrupados antigos, ative a recolha do criador de perfis modificando o ficheiro appengine-web.xml para especificar a flag agentpath através de um dos seguintes métodos:

  • Defina a variável de 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>
  • Defina a variável de 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>
  • Especifique o agentpath através do 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 for configurado um novo tipo de perfil para a recolha, certifique-se de que especifica uma nova versão do serviço quando implementar a sua aplicação. Para mais informações, consulte o artigo Por que motivo não tenho dados para um tipo de perfil específico?

Registo do agente

O agente de criação de perfis pode comunicar informações de registo para o ambiente flexível do App Engine, o Compute Engine e o GKE. O agente de criação de perfis suporta os seguintes níveis de registo:

  • 0: registar todas as mensagens. Nível de registo predefinido.
  • 1: registar mensagens de aviso, erro e fatais.
  • 2: registar mensagens de erro e fatais.
  • 3: registar apenas mensagens fatais e parar a aplicação.

Para ativar a escrita de registos no erro padrão com o nível de registo predefinido, anexe -logtostderr à configuração -agentpath.

Para definir o nível de registo de modo a registar apenas mensagens de erro e fatais, anexe -minloglevel=2 à configuração -agentpath.

Por exemplo, para ativar o registo de mensagens de erro e críticas no erro padrão, acrescente -logtostderr e ‑minloglevel=2 à configuração -agentpath:

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

Resolução de problemas

Esta secção lista problemas específicos da criação de perfis de aplicações Java. Consulte a resolução de problemas para obter ajuda com problemas comuns.

Comportamento Causa Solução
Ativou vários criadores de perfis de memória e não tem dados de perfis. A utilização simultânea de vários criadores de perfis de memória desativa todo o suporte de criação de perfis de memória para Java. Esta é uma limitação da JVM. Ative 1 gerador de perfis.

Execução com o Linux Alpine

O agente de criação de perfis Java para Linux Alpine só é suportado para configurações do Google Kubernetes Engine.

Para instalar o agente de criação de perfis Java mais recente para o Linux Alpine, consulte o artigo Instalar o agente do Profiler.

Erro de autenticação

Se usar imagens do Docker executadas com o Linux Alpine (como golang:alpine ou apenas alpine), pode ver o seguinte erro de autenticação:

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

Tenha em atenção que, para ver o erro, tem de ter o registo do agente ativado.

O erro indica que as imagens do Docker com o Linux Alpine não têm os certificados SSL de raiz instalados por predefinição. Esses certificados são necessários para que o agente de criação de perfis comunique com a API Profiler. Para resolver este erro, adicione o seguinte comando apk ao seu Dockerfile:

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

Em seguida, tem de recriar e voltar a implementar a aplicação.

O que se segue?