Elaborar perfiles de aplicaciones de Go

En esta página se describe cómo modificar tu aplicación Go para recoger datos de perfil y enviarlos a tu proyecto de Google Cloud. Para obtener información general sobre la creación de perfiles, consulta el artículo Conceptos de la creación de perfiles.

.

Tipos de perfiles de Go:

  • Tiempo de CPU
  • Montículo
  • Montículo asignado
  • Contención (mutex de Go)
  • Hilos (gorutinas de Go)

Versiones del lenguaje Go compatibles:

Versiones compatibles del agente de creación de perfiles:

  • Se admite la versión más reciente del agente. Por lo general, no se admiten las versiones que tengan más de un año. Te recomendamos que uses la versión más reciente del agente.

Sistemas operativos compatibles:

  • Linux. La creación de perfiles de aplicaciones Go es compatible con los kernels de Linux cuya biblioteca C estándar se implementa con glibc o con musl. Para obtener información sobre la configuración específica de los kernels de Linux Alpine, consulta Ejecutar en Linux Alpine.

Entornos admitidos:

Habilitar la API Profiler

Antes de usar el agente de creación de perfiles, asegúrate de que la API Profiler subyacente esté habilitada. Puedes comprobar el estado de la API y habilitarla si es necesario mediante la CLI de Google Cloud o la consola de Google Cloud :

CLI de gcloud

  1. Si aún no has instalado Google Cloud CLI en tu estación de trabajo, consulta la documentación de Google Cloud CLI.

  2. Ejecuta el siguiente comando:

    gcloud services enable cloudprofiler.googleapis.com
    

Para obtener más información, consulta 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. Si se muestra API habilitada, significa que la API ya está habilitada. Si no es así, haz clic en el botón Habilitar.

Asignar un rol de gestión de identidades y accesos a una cuenta de servicio

Si vas a implementar tu aplicación en recursos de Google Cloud y usas la cuenta de servicio predeterminada sin haber modificado las concesiones de roles de esa cuenta, puedes saltarte esta sección.

Si haces alguna de las siguientes acciones, debes conceder a la cuenta de servicio el rol de gestión de identidades y accesos Agente de Cloud Profiler (roles/cloudprofiler.agent):

  1. Estás usando la cuenta de servicio predeterminada, pero has modificado sus concesiones de roles.
  2. Estás usando una cuenta de servicio creada por un usuario.
  3. Si usas Workload Identity, concede el rol Agente de Cloud Profiler a la cuenta de servicio de Kubernetes.

Para asignar un rol de gestión de identidades y accesos a una cuenta de servicio, puedes usar laGoogle Cloud consola o la CLI de Google Cloud. Por ejemplo, puedes usar el 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 el comando anterior, sustituye lo siguiente:

  • GCP_PROJECT_ID: tu ID de proyecto.
  • MY_SVC_ACCT_ID: el nombre de tu cuenta de servicio.

Para obtener información detallada, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

Usar Cloud Profiler

En todos los entornos compatibles, se usa Profiler importando el paquete en la aplicación y, a continuación, inicializando Profiler lo antes posible en la aplicación.

Para habilitar la creación de perfiles de contención de mutex ("Contención" en la interfaz), defina la opción de configuración MutexProfiling en true.

Para obtener más información sobre la API Profiler, incluidas todas las opciones de configuración, consulta la documentación pública de la API.

Compute Engine

En Compute Engine, en profiler.Config, define Service con un nombre para el servicio que se va a crear un perfil y, de forma opcional, define ServiceVersion con la versión del servicio:


// 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.
	}
}

Si tiene dependencias en su código fuente que se obtienen manualmente, es posible que tenga que añadir lo siguiente a su script de compilación o Dockerfile:

go get cloud.google.com/go/profiler

GKE

En GKE, en profiler.Config, define Service con un nombre para el servicio del que se va a crear un perfil y, de forma opcional, define ServiceVersion con la versión del servicio:


// 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.
	}
}

Si tiene dependencias en su código fuente que se obtienen manualmente, es posible que tenga que añadir lo siguiente a su script de compilación o Dockerfile:

go get cloud.google.com/go/profiler

App Engine

En el entorno flexible de App Engine y en el entorno estándar de App Engine, las adiciones de código son casi idénticas a las de Compute Engine y GKE. Hay una excepción. En ambos entornos de App Engine, los parámetros Service y ServiceVersion se derivan del entorno, por lo que no es necesario especificarlos.


// 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.
	}
}

Cuando ejecutes la aplicación de forma local, define los parámetros ProjectID (el ID de tu proyectoGoogle Cloud ) y Service en profiler.Config, ya que no se pueden obtener de un entorno local. No es necesario que configures ServiceVersion.

Si usas el entorno estándar de App Engine, consulta el artículo Migrar tu aplicación a Go 1.11 para obtener información detallada sobre los cambios que podrías tener que hacer en tu aplicación. Además, debes usar la versión 226.0.0 de Google Cloud CLI o una posterior. Para actualizar Google Cloud CLI, ejecuta el siguiente comando:

gcloud components update

Para ejecutar la aplicación, sigue estos pasos:

  1. Actualiza las dependencias:

    go get cloud.google.com/go/profiler
    
  2. Despliega la aplicación en tu entorno flexible de App Engine o en tu entorno estándar de App Engine:

    gcloud app deploy [DEPLOYMENT]
    

    donde DEPLOYMENT es la ruta a tu archivo de configuración. Por ejemplo, DEPLOYMENT podría ser main/app.yaml.

Análisis de datos

Una vez que Profiler haya recogido datos, podrá verlos y analizarlos mediante la interfaz de Profiler.

En la Google Cloud consola, ve a la página Perfilador:

Ve a Profiler.

También puedes encontrar esta página mediante la barra de búsqueda.

Argumentos de nombre y versión del servicio

Cuando carga el agente de Profiler, especifica un argumento service-name y un argumento service-version opcional para configurarlo.

El nombre del servicio permite a Profiler recoger datos de perfil de todas las réplicas de ese servicio. El servicio de creación de perfiles asegura una frecuencia de recogida de un perfil por minuto, de media, para cada nombre de servicio en cada combinación de versiones y zonas de servicio.

Por ejemplo, si tienes un servicio con dos versiones que se ejecutan en réplicas de tres zonas, el creador de perfiles creará una media de seis perfiles por minuto para ese servicio.

Si usas nombres de servicio diferentes para tus réplicas, tu servicio se perfilará con más frecuencia de la necesaria, con una sobrecarga correspondientemente mayor.

Al seleccionar un nombre de servicio, ten en cuenta lo siguiente:

  • Elige un nombre que represente claramente el servicio en la arquitectura de tu aplicación. La elección del nombre del servicio es menos importante si solo ejecutas un servicio o una aplicación. Es más importante si tu aplicación se ejecuta como un conjunto de microservicios, por ejemplo.

  • No utilices ningún valor específico del proceso, como un ID de proceso, en la cadena service-name.

  • La cadena service-name debe coincidir con esta expresión regular:

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

Una buena práctica es usar una cadena estática como imageproc-service como nombre del servicio.

La versión del servicio es opcional. Si especificas la versión del servicio, Profiler puede agregar información de perfil de varias instancias y mostrarla correctamente. Se puede usar para marcar diferentes versiones de tus servicios a medida que se implementan. La interfaz de usuario de Profiler te permite filtrar los datos por versión del servicio. De esta forma, puedes comparar el rendimiento de versiones anteriores y más recientes del código.

El valor del argumento service-version es una cadena de formato libre, pero los valores de este argumento suelen ser números de versión, como 1.0.0 o 2.1.2.

Registro de agentes

El agente de creación de perfiles puede registrar información de depuración en sus registros. De forma predeterminada, el registro del agente está inhabilitado.

Para habilitar el registro del agente, asigna el valor true a la opción DebugLogging al iniciar el agente:

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

Solución de problemas

En esta sección se enumeran los problemas específicos de la creación de perfiles de aplicaciones Go. Consulta la sección Solución de problemas para obtener ayuda con problemas habituales.

Comportamiento Causa Solución
Los perfiles de tiempo de CPU no se recogen en las aplicaciones creadas con -buildmode=c-archive. Se recogen los perfiles de montículo, contención y conversación. Incidencia de GitHub De forma predeterminada, la creación de perfiles de CPU no está habilitada en las aplicaciones Go cuando la marca -buildmode es c-archive o c-shared. Añade una llamada a
signal.Notify(make(
chan os.Signal), syscall.SIGPROF)
antes de llamar a profiler.Start.
Respuesta a la incidencia de GitHub.

Ejecutar con Linux Alpine

El agente de creación de perfiles de Go para Linux Alpine solo se admite en configuraciones de Google Kubernetes Engine.

Error de autenticación

Si usas imágenes de Docker que se ejecutan con Linux Alpine (como golang:alpine o alpine), es posible que veas el siguiente error de autenticación:

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

Ten en cuenta que, para ver el error, debes tener habilitado el registro del agente. De forma predeterminada, el agente de Go no genera ningún mensaje de registro.

El error indica que las imágenes de Docker con Linux Alpine no tienen instalados los certificados SSL raíz de forma predeterminada. Estos certificados son necesarios para que el agente de creación de perfiles se comunique con la API Profiler. Para resolver este error, añade el siguiente comando apk a tu Dockerfile:

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

Después, debes volver a compilar y desplegar la aplicación.

Siguientes pasos