Supervisa el rendimiento web sin servidores mediante Cloud Functions


En este instructivo, se describe cómo crear una app de supervisión del rendimiento web mediante tecnologías sin servidores de Google Cloud.

El rendimiento juega un papel fundamental en el éxito de cualquier aplicación web. Si el rendimiento de tu sitio es bajo, es posible que experimentes menos registros y una menor retención de usuarios, lo que probablemente afectará tus objetivos comerciales. El rendimiento debe ser un criterio clave para el éxito cuando diseñes, crees y pruebes tu aplicación web.

Sin embargo, el rendimiento de la página también puede cambiar con el tiempo a medida que evoluciona tu app. Los desarrolladores pueden agregar o actualizar imágenes y secuencias de comandos, o la misma infraestructura subyacente de la app puede cambiar. Por lo tanto, es importante supervisar de manera periódica el rendimiento de la página. Por lo general, debes almacenar las métricas de rendimiento para habilitar el análisis histórico. También se suelen generar alertas si el rendimiento de la página está por debajo de algunos límites definidos.

Objetivos

  • Crear una función de Cloud Functions que use Chrome sin interfaz gráfica para recopilar métricas de rendimiento de páginas web
  • Almacenar las métricas en Cloud Storage
  • Crear otra función de Cloud Functions, que se active por el evento de creación de Cloud Storage, para analizar las métricas de la página
  • Almacenar los resultados del análisis en Firestore
  • Crear otra función de Cloud Functions, que se active por el evento de creación de Firestore, para publicar una alerta en Pub/Sub si el rendimiento de la página es deficiente
  • Crear un trabajo de Cloud Scheduler para activar de manera periódica la primera función de Cloud Functions
  • Verificar los resultados de las situaciones de éxito y de error

Costos

En este instructivo, se usan componentes facturables de Google Cloud, que incluyen lo siguiente:

  • Cloud Functions
  • Cloud Scheduler
  • Cloud Storage
  • Firestore
  • Pub/Sub
  • Container Registry
  • Cloud Build

Usa la calculadora de precios para generar una estimación de los costos según el uso previsto.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  4. Habilita las API de Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build.

    Habilita las API

  5. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  6. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  7. Habilita las API de Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build.

    Habilita las API

Arquitectura

Por lo general, las operaciones de supervisión del rendimiento web son sin estado y de corta duración. También suelen estar basadas en eventos, ya sean programados o activados como parte de otro proceso, como una canalización de prueba automatizada. Estas características hacen que las arquitecturas sin servidores sean una opción interesante para implementar apps de análisis web.

En este instructivo, usarás varias partes de la pila sin servidores de Google Cloud, incluidas Cloud Functions, Firestore, Cloud Scheduler y Pub/Sub. No es necesario que administres la infraestructura de ninguno de estos servicios, y solo pagarás por lo que uses. El núcleo de la app se implementa mediante Cloud Functions, que proporciona un entorno de ejecución sin servidores escalable y controlado por eventos. Con Cloud Functions, puedes crear y conectar apps mediante elementos lógicos independientes y vinculados de manera flexible.

En el siguiente diagrama, se muestra la arquitectura de la solución sin servidores que crearás en este instructivo.

Arquitectura de solución de análisis web sin servidores

Prepara el entorno

Antes de crear el entorno sin servidores, tienes que obtener el código de GitHub, establecer las variables y preparar los recursos que necesitarás luego para el análisis y el almacenamiento.

Obtén el código y establece variables de entorno

  1. En la consola de Google Cloud, abre Cloud Shell.

    Abra Cloud Shell

  2. Clona el repositorio que contiene el código de las funciones de Cloud Functions usadas en este instructivo:

    git clone https://github.com/GoogleCloudPlatform/solutions-serverless-web-monitoring.git
    
  3. Cambia al directorio de funciones:

    cd solutions-serverless-web-monitoring/functions
    
  4. Establece el ID y el número del proyecto actuales como variables de shell:

    export PROJECT=$DEVSHELL_PROJECT_ID
    export PROJECT_NUM=$(gcloud projects list \
        --filter="$PROJECT" \
        --format="value(PROJECT_NUMBER)")
    
  5. Establece la región de implementación predeterminada para las funciones de Cloud Functions. En el siguiente ejemplo, se establece la región en us-east1, pero puedes cambiarla a cualquier región en la que Cloud Functions esté disponible.

    export REGION=us-east1
    gcloud config set functions/region $REGION
    

Crea depósitos de Cloud Storage

En esta sección, crearás un bucket de Cloud Storage para almacenar los datos de rendimiento recopilados de la página. Puedes elegir cualquier ubicación o clase de almacenamiento, pero se recomienda crear depósitos en la misma ubicación que las funciones de Cloud Functions que usarán los depósitos.

  1. En Cloud Shell, exporta una variable de shell para los nombres de los depósitos de Cloud Storage que almacenarán las métricas. Los nombres de bucket s deben ser únicos a nivel global, por lo que, en el siguiente comando, se usa tu número de proyecto de Google Cloud como sufijo en el nombre del bucket.

    export METRICS_BUCKET=page-metrics-$PROJECT_NUM
    
  2. Usa la herramienta de gsutil para crear los depósitos:

    gsutil mb -l $REGION gs://$METRICS_BUCKET
    
  3. Actualiza el archivo env-vars.yaml con los nombres de los depósitos. Este archivo contiene variables de entorno que pasarás a las funciones de Cloud Functions más adelante.

    sed -i "s/\[YOUR_METRICS_BUCKET\]/$METRICS_BUCKET/" env-vars.yaml
    

Crea una colección de Firestore

En una sección posterior, analizarás las métricas de rendimiento de la página. En esta sección, debes crear una colección de Firestore para almacenar los resultados de cada análisis.

  1. En la consola de Google Cloud, ve a la página Firestore.

    Ir a la página de Firestore

  2. Si nunca creaste una base de datos de Firestore, sigue estos pasos:

    1. Haz clic en Seleccionar modo nativo para activar Firestore.
    2. Selecciona una ubicación regional cerca de la región en la que se ejecutará Cloud Functions.
    3. Haz clic en Crear base de datos.

    La configuración toma unos minutos.

  3. Haz clic en Iniciar colección y configura el ID de la colección en page-metrics.

  4. Haz clic en Guardar.

Crea un tema y una suscripción de Pub/Sub

Por lo general, tu objetivo es notificar a los sistemas y las partes interesadas si el análisis indica que una página tiene un rendimiento bajo. En esta sección, crearás temas de Pub/Sub que contendrán mensajes que describen cualquier tipo de rendimiento deficiente.

  1. En Cloud Shell, crea un tema de Pub/Sub llamado performance-alerts:

    gcloud pubsub topics create performance-alerts
    
  2. Crea una suscripción al tema. Usa la suscripción para verificar que los mensajes de alerta se publiquen en el tema.

    gcloud pubsub subscriptions create performance-alerts-sub \
        --topic performance-alerts
    

Recopila métricas de rendimiento de la página

Muchos sitios web usan JavaScript para procesar el contenido de la página de forma dinámica. Esto hace que el análisis de rendimiento sea más complicado, ya que el cliente necesita emular un navegador para cargar por completo la página web. El entorno de ejecución de Node.js para Cloud Functions es compatible con Chrome sin interfaz gráfica, que proporciona la funcionalidad de un navegador web completo en un entorno sin servidores.

Puppeteer es una biblioteca de Node.js compilada por el equipo de herramientas para desarrolladores de Chrome que proporciona una API de alto nivel a fin de controlar Chrome sin interfaz gráfica. De forma predeterminada, Puppeteer instala una versión reciente del navegador junto con la biblioteca. Por lo tanto, puedes agregar Puppeteer como una dependencia a la función de Cloud Functions a fin de usar con facilidad Chrome sin interfaz gráfica dentro de la función.

Medir y analizar el rendimiento de las páginas web es un campo vasto y complejo. Para simplificarlo, en este instructivo, usarás Puppeteer a fin de recopilar algunas métricas de rendimiento de la página de nivel superior. Sin embargo, también puedes usar Puppeteer y el Protocolo de herramientas para desarrolladores de Chrome (CDP) a fin de recopilar información más detallada, como seguimientos de cronogramas. También puedes representar mejor tu experiencia de usuario final si emulas la congestión de la red y limitas la CPU. Para obtener una buena introducción al análisis del rendimiento de las páginas web, consulta el sitio para desarrolladores web de Chrome.

Ten en cuenta que existen muchos factores que influyen en los tiempos de carga de las páginas web, incluidas las características de rendimiento del cliente. Es importante establecer modelos de referencia mediante la configuración de CPU y RAM de la función de Cloud Functions.

En el siguiente fragmento del archivo tracer/index.js, se muestra cómo usar Puppeteer para cargar la página web:

// launch Puppeteer and start a Chrome DevTools Protocol (CDP) session
// with performance tracking enabled.
browser = await puppeteer.launch({
  headless: true,
  args: ['--no-sandbox']
});
const page = await browser.newPage();
const client = await page.target().createCDPSession();
await client.send('Performance.enable');

// browse to the page, capture and write the performance metrics
console.log('Fetching url: '+url.href);
await page.goto(url.href, {
  'waitUntil' : 'networkidle0'
});
const performanceMetrics = await client.send('Performance.getMetrics');
options = createUploadOptions('application/json', page.url());
await writeToGcs(metricsBucket, filename, JSON.stringify(performanceMetrics), options);
  • En Cloud Shell, implementa la función trace de Cloud Functions:

    gcloud functions deploy trace \
        --trigger-http \
        --runtime nodejs10 \
        --memory 1GB \
        --source tracer \
        --env-vars-file env-vars.yaml \
        --quiet
    

    La implementación de la función de Cloud Functions puede tomar varios minutos.

    Los parámetros de implementación especifican que la función debe tener un activador HTTP, debe usar el entorno de ejecución de Node.js 10 y debe tener 1 GB de memoria. Esta cantidad de memoria es necesaria para ejecutar Chrome sin interfaz gráfica. Las variables de entorno se suministran a la función mediante el archivo env-vars.yaml.

De forma predeterminada, las funciones de Cloud Function activadas por HTTP permiten las invocaciones no autenticadas. Por lo tanto, debes proteger la función de seguimiento.

  • Quita la función de IAM cloudfunctions.invoker para allUsers:

    gcloud beta functions remove-iam-policy-binding trace \
        --member allUsers \
        --role roles/cloudfunctions.invoker
    

Analiza las métricas

Un objetivo típico de los ejercicios de supervisión del rendimiento web es realizar un seguimiento del rendimiento en comparación con algunas comparativas definidas. Si una métrica en particular excede un límite esperado, puede indicar un problema con una versión de software reciente o con la infraestructura subyacente.

En esta sección, crearás una función de Cloud Functions en Python para analizar las métricas de la página y conservar los resultados en una colección de Firestore. La función evalúa la métrica FirstMeaningfulPaint respecto de un límite esperado y marca el resultado del análisis como problemático si se excede el límite. FirstMeaningfulPaint es una métrica centrada en el usuario que describe en términos generales cuándo una página es útil para el usuario. Usa un activador de Cloud Storage para ejecutar la función de análisis cada vez que se escribe un archivo nuevo en el bucket que contiene las métricas.

En el siguiente fragmento del archivo analyzer/main.py, se muestra la lógica de la función:

def analyze(data, context):
  """Function entry point, triggered by creation of an object in a GCS bucket.

  The function reads the content of the triggering file, analyses its contents,
  and persists the results of the analysis to a new Firestore document.

  Args:
    data (dict): The trigger event payload.
    context (google.cloud.functions.Context): Metadata for the event.
  """
  page_metrics = get_gcs_file_contents(data)
  max_time_meaningful_paint = int(os.environ.get('MAX_TIME_MEANINGFUL_PAINT'))
  analysis_result = analyze_metrics(data, page_metrics,
                                    max_time_meaningful_paint)
  docref = persist(analysis_result, data['name'])
  logging.info('Created new Firestore document %s/%s describing analysis of %s',
               docref.parent.id, docref.id, analysis_result['input_file'])
  • Implementa la función analyze de Cloud Functions:

    gcloud functions deploy analyze \
        --trigger-resource gs://$METRICS_BUCKET \
        --trigger-event google.storage.object.finalize \
        --runtime python37 \
        --source analyzer \
        --env-vars-file env-vars.yaml
    

    La función se activa mediante un evento finalize en el depósito de métricas, que se envía cada vez que se crea un objeto en el depósito. La función usa el entorno de ejecución de Python 3.7.

Alerta sobre fallas

Por lo general, tu objetivo es tomar medidas si el análisis de métricas indica que la página tiene un rendimiento bajo.

En esta sección, crearás una función de Cloud Functions para enviar un mensaje a un tema de Pub/Sub si el rendimiento de la página no es satisfactorio. La función se activa cada vez que se crea un documento en la colección de Firestore. Las partes interesadas pueden suscribirse al tema de Pub/Sub y tomar las medidas adecuadas. Por ejemplo, una app de asistencia podría suscribirse a los mensajes de Pub/Sub y enviar un correo electrónico, activar un localizador de asistencia o abrir un error.

En el siguiente fragmento del archivo alerter/main.py, se muestra la lógica de la función:

def generate_alert(data, context):
  """Cloud Function entry point, triggered by a change to a Firestore document.

  If the triggering document indicates a Failed status, send the document to
  configured PubSub topic.

  Args:
    data (dict): The event payload.
    context (google.cloud.functions.Context): Metadata for the event.
  """
  doc_fields = data['value']['fields']
  status = doc_fields['status']['stringValue']
  if 'FAIL' in status:
    global publish_client
    if not publish_client:
      publish_client = pubsub.PublisherClient()

    logging.info('Sending alert in response to %s status in document %s',
                 status, context.resource)
    project = os.environ.get('GCP_PROJECT')
    topic = os.environ.get('ALERT_TOPIC')
    fqtn = 'projects/{}/topics/{}'.format(project, topic)
    msg = json.dumps(data['value']).encode('utf-8')
    publish_client.publish(fqtn, msg)

Ten en cuenta que la alerta se envía solo si el campo de estado indica un error.

  • Implementa la función alert de Cloud Functions:

    gcloud functions deploy alert \
        --trigger-event providers/cloud.firestore/eventTypes/document.create \
        --trigger-resource "projects/$PROJECT/databases/(default)/documents/page-metrics/{any}" \
        --runtime python37 \
        --source alerter \
        --env-vars-file env-vars.yaml \
        --entry-point generate_alert
    

    La función se activa mediante un evento document.create en la colección page-metrics de Firestore. El sufijo {any} es un comodín que indica que la función debe activarse cada vez que se crea un documento en la colección.

Programa el análisis

Se recomienda supervisar de manera periódica el rendimiento de la página. Por ejemplo, te recomendamos analizar una página determinada cada hora, cada día o cada semana. En esta sección, crearás un trabajo de Cloud Scheduler para ejecutar de forma periódica la canalización del análisis mediante la activación de la función trace.

El trabajo de Cloud Scheduler se ejecuta mediante una cuenta de servicio a la que se le otorgó la función de IAM cloudfunctions.invoker requerida para la función trace.

A veces, las páginas web no responden de forma correcta o se agota el tiempo de espera de las solicitudes, por lo que los reintentos son inevitables con las apps de análisis web. Por lo tanto, es importante tener una lógica de reintento en tu app. Cloud Functions admite reintentos para las funciones en segundo plano.

Los reintentos no están disponibles para las funciones de Cloud Functions activadas por HTTP, por lo que no puedes usar Cloud Functions para reintentar la función trace. Sin embargo, Cloud Scheduler admite reintentos. Para obtener más información sobre cómo configurar los parámetros de reintentos, consulta la documentación RetryConfig.

  1. Verifica que las tres funciones de Cloud Functions se hayan implementado de forma correcta y muestren el estado ACTIVE:

    gcloud functions list
    
  2. Crea una cuenta de servicio nueva que se usará como la identidad para ejecutar el trabajo de Cloud Scheduler:

    gcloud iam service-accounts create tracer-job-sa
    
  3. Otorga a la cuenta de servicio nueva la función de IAM cloudfunctions.invoker para la función trace:

    gcloud beta functions add-iam-policy-binding trace \
        --role roles/cloudfunctions.invoker \
        --member "serviceAccount:tracer-job-sa@$PROJECT.iam.gserviceaccount.com"
    
  4. Crea un trabajo de Cloud Scheduler:

    gcloud scheduler jobs create http traceWithRetry \
        --uri="https://$REGION-$PROJECT.cloudfunctions.net/trace" \
        --http-method=POST \
        --message-body="{\"url\":\"http://www.example.com\"}" \
        --headers="Content-Type=application/json" \
        --oidc-service-account-email="tracer-job-sa@$PROJECT.iam.gserviceaccount.com" \
        --schedule="0 3 * * *" \
        --time-zone="UTC" \
        --max-retry-attempts=3 \
        --min-backoff=30s
    

    Debido a que el trabajo llamará a la función trace activada por HTTP, el comando especifica el tipo de trabajo como http y proporciona la URL del activador de la función como el valor uri. La página para analizar, en este caso, www.example.com, se proporciona en la marca message-body. La marca oidc-service-account-email define la cuenta de servicio que se usará para la autenticación. El comando indica la cantidad de reintentos que se realizarán mediante la marca max-retry-attempts, y el valor pasado con la marca schedule establece la programación de ejecución a las 3:00 a.m. UTC todos los días.

Verifica los resultados

En esta sección, verificarás que el comportamiento que obtienes sea el esperado para las condiciones de éxito y de falla.

Verifica el éxito

El trabajo de Cloud Scheduler no se ejecutará hasta la próxima hora programada que, en este caso, es a las 3:00 a.m. UTC. Para ver los resultados de inmediato, puedes activar una ejecución de forma manual.

  1. Espera 90 segundos hasta que el trabajo del programador termine de inicializarse.
  2. Ejecuta el trabajo de Cloud Scheduler de forma manual:

    gcloud scheduler jobs run traceWithRetry
    
  3. Espera alrededor de 30 segundos hasta que se complete la canalización de funciones.

  4. Enumera el contenido del bucket de métricas para mostrar que se recopilaron métricas de la página:

    gsutil ls -l gs://$METRICS_BUCKET
    
  5. En la consola de Google Cloud, abre la página del visor de Cloud Logging:

    Ir a la página Logging

    Verás mensajes de registro de cada una de las tres funciones de Cloud Functions: trace, analyze y alert. Los registros demoran unos minutos en procesarse, por lo que es posible que debas actualizar el panel de registros.

    La consola de Logging sin errores

  6. Anota el ID del documento de Firestore, que aparece después del texto Created new Firestore document page-metrics/.

  7. En la consola de Google Cloud, ve a la página Firestone

    Ir a la página de Firestore

  8. Inspecciona el documento que contiene los resultados del análisis. Los valores del documento indican un estado PASS y contienen las últimas métricas de rendimiento de la página.

  9. En Cloud Shell, verifica que no se hayan enviado mensajes de alerta al tema de Pub/Sub. Para ello, intenta extraer un mensaje de la suscripción:

    gcloud pubsub subscriptions pull \
        projects/$PROJECT/subscriptions/performance-alerts-sub \
        --auto-ack
    

    No verás ningún elemento en la lista.

Verifica la falla

  1. Activa de forma manual la función de seguimiento Esta vez, debes proporcionar la página Instructivos de Google Cloud como la URL. Esta página tiene una gran cantidad de contenido dinámico que aumenta el tiempo de carga de la página por encima del límite máximo esperado.

    gcloud functions call trace \
        --data='{"url":"https://cloud.google.com/docs/tutorials"}'
    

    Debido a que tienes la función de IAM de Owner o Editor del proyecto, tienes suficientes permisos para invocar la función.

  2. Espera alrededor de 30 segundos hasta que se complete la canalización de funciones.

  3. Enumera el contenido del bucket de métricas para verificar que se hayan recopilado métricas adicionales:

    gsutil ls -l gs://$METRICS_BUCKET
    

    Ahora verás dos elementos en cada bucket.

  4. En la consola de Google Cloud, ve a la página del visor de Cloud Logging y filtra los registros de Cloud Functions:

    Ir a la página Logging

    Aparecerá un error de la función analyze que indica que la página superó el tiempo de carga máximo permitido. Es posible que debas actualizar de nuevo el panel de registros para ver los mensajes más recientes.

    La consola de Logging con errores

  5. Anota el ID del documento de Firestore.

  6. En la consola de Google Cloud, ve a la página Firestone

    Ir a la página de Firestore

  7. Busca el documento que describe el análisis con errores.

    El campo de estado está marcado como FAIL.

  8. En Cloud Shell, verifica que se haya enviado un mensaje de alerta al tema de Pub/Sub. Para ello, extrae un mensaje de la suscripción.

    gcloud pubsub subscriptions pull \
        projects/$PROJECT/subscriptions/performance-alerts-sub \
        --auto-ack
    

    Esta vez, verás el contenido del mensaje.

Limpia

Borra el proyecto

  1. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

¿Qué sigue?

  • Obtén más información sobre las tecnologías sin servidores de Google Cloud.
  • Explora otros instructivos de Cloud Functions.
  • Mira el video de Google I/O 2018 en el que se describen otros usos de Puppeteer y Chrome sin interfaz gráfica.
  • Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.