Como criar perfis de aplicativos Go

Esta página explica como modificar seu aplicativo Go para capturar dados de criação de perfil e enviá-los para seu projeto do Google Cloud. Para informações gerais sobre criação de perfil, consulte Conceitos de criação de perfil.

Tipos de perfil para Go:

  • Tempo de CPU
  • Heap
  • Heap alocada
  • Contenção (Go mutex)
  • Linhas de execução (Go goroutine)

Versões compatíveis com a linguagem Go:

Versões compatíveis com o agente de criação de perfil:

  • A versão mais recente do agente é compatível. Em geral, lançamentos com mais de um ano não são compatíveis. Recomendamos que você use a versão do agente lançada mais recentemente.

Sistemas operacionais compatíveis:

  • Linux. A criação de perfil de aplicativos Go é compatível com kernels do Linux cuja biblioteca C padrão é implementada com glibc ou musl. Saiba mais sobre informações de configuração específicas aos kernels do Linux Alpine em Como executar no Linux Alpine.

Ambientes compatíveis:

Como ativar a API Profiler

Antes de usar o agente de criação de perfil, garanta que a API Profiler subjacente esteja ativada. É possível verificar o status da API e ativá-la, se necessário, usando a CLI do Google Cloud ou o Console do Google Cloud:

CLI gcloud

  1. Se você 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 este comando:

    gcloud services enable cloudprofiler.googleapis.com
    

Para ver mais informações, consulte gcloud services.

Console do Google Cloud

  1. Enable the required API.

    Enable the API

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

Conceder papel do IAM à conta de serviço

Se você estiver implantando seu aplicativo em recursos do Google Cloud e se você estiver usando a conta de serviço padrão e não tiver modificado as permissões de função para essa conta de serviço, pule esta seção.

Se você fizer qualquer uma das ações a seguir, precisará conceder à conta de serviço o papel do IAM de Agente do Cloud Profiler (roles/cloudprofiler.agent):

  1. Você está usando a conta de serviço padrão, mas modificou as permissões de função dela.
  2. Você está usando uma conta de serviço criada pelo usuário.
  3. Você está usando a Identidade da carga de trabalho, conceda o papel de Agente do Cloud Profiler à conta de serviço do Kubernetes.

É possível conceder um papel do IAM a uma conta de serviço usando o console do Google Cloud ou a Google Cloud CLI. Por exemplo, é possível 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 projeto.
  • MY_SVC_ACCT_ID: o nome da conta de serviço

Para mais informações, consulte Gerenciar o acesso a projetos, pastas e organizações.

Como usar o Cloud Profiler

Em todos os ambientes compatíveis, use o Profiler importando o pacote no seu aplicativo e inicializando-o o mais cedo possível.

Para ativar a criação de perfil de contenção de mutex ("Contenção" na interface), defina a opção de configuração MutexProfiling como true.

Para mais informações sobre a API do Profiler, incluindo todas as opções de configuração, consulte os documentos públicos da API.

Compute Engine

Para o Compute Engine, em profiler.Config, defina Service com um nome para o serviço que está sendo criado e, opcionalmente, defina ServiceVersion com a versão do serviço:


// snippets is an example of starting cloud.google.com/go/profiler.
package main

import (
	"cloud.google.com/go/profiler"
)

func main() {
	cfg := profiler.Config{
		Service:        "myservice",
		ServiceVersion: "1.0.0",
		// ProjectID must be set if not running on GCP.
		// ProjectID: "my-project",

		// For OpenCensus users:
		// To see Profiler agent spans in APM backend,
		// set EnableOCTelemetry to true
		// EnableOCTelemetry: true,
	}

	// Profiler initialization, best done as early as possible.
	if err := profiler.Start(cfg); err != nil {
		// TODO: Handle error.
	}
}

Se você tiver dependências em seu código-fonte que são buscadas manualmente, poderá ser necessário adicionar isto ao script de construção ou ao Dockerfile:

go get cloud.google.com/go/profiler

GKE

Para o GKE, em profiler.Config, defina Service com um nome para o serviço que está sendo criado e, opcionalmente, defina ServiceVersion com a versão do serviço:


// snippets is an example of starting cloud.google.com/go/profiler.
package main

import (
	"cloud.google.com/go/profiler"
)

func main() {
	cfg := profiler.Config{
		Service:        "myservice",
		ServiceVersion: "1.0.0",
		// ProjectID must be set if not running on GCP.
		// ProjectID: "my-project",

		// For OpenCensus users:
		// To see Profiler agent spans in APM backend,
		// set EnableOCTelemetry to true
		// EnableOCTelemetry: true,
	}

	// Profiler initialization, best done as early as possible.
	if err := profiler.Start(cfg); err != nil {
		// TODO: Handle error.
	}
}

Se você tiver dependências em seu código-fonte que são buscadas manualmente, poderá ser necessário adicionar isto ao script de construção ou ao Dockerfile:

go get cloud.google.com/go/profiler

App Engine

Para o ambiente flexível e o ambiente padrão do App Engine, as adições de código são quase idênticas às do Compute Engine e do GKE. Há uma exceção. Nos ambientes do App Engine, os parâmetros Service e ServiceVersion são derivados do ambiente. Portanto, não é necessário especificá-los.


// appengine is an example of starting cloud.google.com/go/profiler on
// App Engine.
package main

import (
	"cloud.google.com/go/profiler"
)

func main() {
	// Profiler initialization, best done as early as possible.
	if err := profiler.Start(profiler.Config{
		// Service and ServiceVersion can be automatically inferred when running
		// on App Engine.
		// ProjectID must be set if not running on GCP.
		// ProjectID: "my-project",
	}); err != nil {
		// TODO: Handle error.
	}
}

Ao executar o aplicativo localmente, defina os parâmetros ProjectID (o ID do projeto do Google Cloud) e Service como profiler.Config, já que eles não podem ser derivados de um ambiente local. Não é necessário definir ServiceVersion.

Se você usa o ambiente padrão do App Engine, consulte Como migrar o aplicativo para o Go 1.11. Você verá informações detalhadas sobre as alterações que você talvez precise fazer no aplicativo. Além disso, você precisa usar a versão 226.0.0 ou mais recente da Google Cloud CLI. Para atualizar a Google Cloud CLI, execute o comando a seguir:

gcloud components update

Para executar o aplicativo, faça o seguinte:

  1. Atualize as dependências:

    go get cloud.google.com/go/profiler
    
  2. Implante o aplicativo no ambiente flexível ou padrão do App Engine:

    gcloud app deploy [DEPLOYMENT]
    

    em que DEPLOYMENT é o caminho para o arquivo de configuração. Por exemplo, DEPLOYMENT pode ser main/app.yaml.

Análise de dados

Depois que o Profiler coletar dados, será possível visualizá-los e analisá-los usando a interface dele.

No console do Google Cloud, acesse a página Profiler:

Acessar o Profiler

Também é possível encontrar essa página usando a barra de pesquisa.

Argumentos de versão e nome de serviço

Ao carregar o agente do Profiler, você especifica um argumento de nome de serviço e um opcional de versão para configurá-lo.

Com o nome de serviço, o Profiler pode coletar dados de criação de perfil de todas as réplicas desse serviço. O criador de perfil garante uma taxa de coleta de um perfil por minuto, em média. Isso é para todos os nomes de serviço em cada combinação de zona e versão.

Por exemplo, se você tiver um serviço com duas versões executadas em réplicas em três zonas, o criador de perfil produzirá uma média de seis perfis por minuto para esse serviço.

Se você usar nomes de serviço diferentes nas réplicas, o serviço terá perfis criados com mais frequência do que o necessário, com uma sobrecarga correspondente maior.

Ao selecionar um nome de serviço:

  • escolha um que represente claramente o serviço na arquitetura do aplicativo. Essa seleção não é tão importante se você executa apenas um serviço ou aplicativo. Ela é mais importante se o aplicativo é executado como um conjunto de microsserviços, por exemplo;

  • não use nenhum valor específico do processo, como o código, na string do nome de serviço;

  • a string do nome de serviço precisa 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 de serviço é opcional. Se você especificá-la, o Profiler poderá agregar informações de criação de perfil de várias instâncias e exibi-las corretamente. É possível usá-la para marcar diferentes versões dos serviços conforme eles são implantados. Com a IU do Profiler, você filtra os dados por versão de serviço. Assim, é possível comparar o desempenho de versões mais antigas e mais recentes do código.

O valor do argumento da versão do serviço é uma string de formato livre. No entanto, os valores desse argumento geralmente se parecem com números de versão. Por exemplo, 1.0.0 ou 2.1.2.

Geração de registros do agente

O agente de criação de perfil mostra informações de depuração nos registros dele. Por padrão, o registro do agente está desativado.

Para ativar a geração de registros do agente, defina a opção DebugLogging como true ao iniciar o agente:

profiler.Start(profiler.Config{..., DebugLogging: true});

Solução de problemas

Nesta seção, listamos problemas específicos da criação de perfil de aplicativos Go. Consulte Solução de problemas para conseguir ajuda com problemas comuns.

Comportamento Causa Solução
Os perfis de tempo de CPU não são coletados para aplicativos criados com -buildmode=c-archive. Perfis de heap, de contenção e de linha de execução são coletados. Problema no GitHub Por padrão, a criação de perfil da CPU não está ativada para aplicativos Go quando a sinalização -buildmode é c-archive ou c-shared. Adicione uma chamada para
signal.Notify(make(
chan os.Signal), syscall.SIGPROF)
antes de chamar profiler.Start.
Resposta ao problema do GitHub.

Como executar com o Alpine Linux

O agente de criação de perfil do Go para Alpine Linux é compatível apenas com as configurações do Google Kubernetes Engine.

Erro de autenticação

Se você usar imagens do Docker executadas com o Linux Alpine (como golang:alpine ou apenas alpine), você poderá encontrar o seguinte erro de autenticação:

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

Para ver o erro, você precisa ativar a geração de registros do agente. Por padrão, o agente para Go não gera nenhuma mensagem de registro.

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

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

Depois, será necessário recriar e reimplantar o aplicativo.

A seguir