Monitoraggio delle prestazioni web serverless mediante Cloud Functions


Questo tutorial descrive come creare un'app per il monitoraggio delle prestazioni web utilizzando le tecnologie serverless di Google Cloud.

Il rendimento svolge un ruolo importante per il successo di qualsiasi app web. Se il tuo sito ha un rendimento scarso, potresti riscontrare meno registrazioni e una minore fidelizzazione degli utenti, il che probabilmente inciderà sui tuoi obiettivi commerciali. Il rendimento dovrebbe essere un criterio di successo chiave durante la progettazione, la creazione e il test della tua app web.

Tuttavia, anche le prestazioni delle pagine possono cambiare nel tempo man mano che l'app si evolve. Gli sviluppatori possono aggiungere o aggiornare immagini e script oppure può cambiare l'infrastruttura di pubblicazione dell'app sottostante. Pertanto, è importante monitorare regolarmente il rendimento della pagina. In genere, le metriche sul rendimento vengono archiviate per abilitare l'analisi storica. È pratica comune anche generare avvisi se le prestazioni delle pagine sono inferiori a determinate soglie.

Obiettivi

  • Crea una funzione Cloud Functions che utilizzi Chrome headless per raccogliere metriche sulle prestazioni delle pagine web.
  • Archiviare le metriche in Cloud Storage.
  • Creare un'altra Cloud Function, attivata dall'evento di creazione Cloud Storage, per analizzare le metriche della pagina.
  • Archivia i risultati dell'analisi in Firestore.
  • Crea un'altra Cloud Function, attivata dall'evento di creazione Firestore, per pubblicare un avviso in Pub/Sub se le prestazioni della pagina sono scarse.
  • Crea un job Cloud Scheduler per attivare periodicamente la prima Cloud Function.
  • Verifica gli output per l'esito positivo e gli scenari di errore.

Costi

Questo tutorial utilizza i componenti fatturabili di Google Cloud, tra cui:

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

Utilizza il Calcolatore prezzi per generare una stima dei costi in base all'utilizzo previsto.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  4. Abilita le API Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build.

    Abilita le API

  5. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  6. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  7. Abilita le API Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build.

    Abilita le API

Architettura

Le operazioni di monitoraggio delle prestazioni web sono generalmente stateless e di breve durata. Sono spesso basati su eventi e si verificano in base a una pianificazione o attivati nell'ambito di altri processi, ad esempio una pipeline di test automatizzata. Queste caratteristiche rendono le architetture serverless una scelta accattivante per l'implementazione di app di analisi web.

In questo tutorial, utilizzerai varie parti dello stack serverless di Google Cloud, tra cui Cloud Functions, Firestore, Cloud Scheduler e Pub/Sub. Non devi gestire l'infrastruttura per nessuno di questi servizi e paghi solo per ciò che utilizzi. Il core dell'app è implementato utilizzando Cloud Functions, che fornisce un ambiente di esecuzione serverless scalabile e basato su eventi. Con Cloud Functions, puoi creare e connettere app utilizzando parti logiche indipendenti e a basso accoppiamento.

Il seguente diagramma mostra l'architettura della soluzione serverless creata in questo tutorial.

Architettura della soluzione di analisi web serverless

Preparazione dell'ambiente

Prima di creare l'ambiente serverless, ricevi il codice da GitHub, imposta le variabili e prepara le risorse necessarie in un secondo momento per l'analisi e l'archiviazione.

Recupera il codice e imposta le variabili di ambiente

  1. Nella console Google Cloud, apri Cloud Shell.

    Apri Cloud Shell

  2. Clona il repository che contiene il codice per le funzioni Cloud Functions utilizzate in questo tutorial:

    git clone https://github.com/GoogleCloudPlatform/solutions-serverless-web-monitoring.git
    
  3. Passa alla directory delle funzioni:

    cd solutions-serverless-web-monitoring/functions
    
  4. Imposta l'ID e il numero di progetto correnti come variabili shell:

    export PROJECT=$DEVSHELL_PROJECT_ID
    export PROJECT_NUM=$(gcloud projects list \
        --filter="$PROJECT" \
        --format="value(PROJECT_NUMBER)")
    
  5. Impostare la regione di deployment predefinita per Cloud Functions. L'esempio seguente imposta la regione su us-east1, ma puoi modificarla in qualsiasi regione in cui è disponibile Cloud Functions.

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

Creazione di bucket di Cloud Storage

In questa sezione creerai un bucket Cloud Storage per archiviare i dati sulle prestazioni della pagina raccolti. Puoi scegliere qualsiasi località o classe di archiviazione, ma è buona norma creare bucket nella stessa località delle funzioni Cloud Functions che utilizzeranno i bucket.

  1. In Cloud Shell, esporta una variabile shell per i nomi dei bucket Cloud Storage in cui verranno archiviate le metriche. I nomi dei bucket devono essere univoci a livello globale, pertanto il comando seguente utilizza il numero di progetto Google Cloud come suffisso del nome del bucket.

    export METRICS_BUCKET=page-metrics-$PROJECT_NUM
    
  2. Usa lo strumento gsutil per creare i bucket:

    gsutil mb -l $REGION gs://$METRICS_BUCKET
    
  3. Aggiorna il file env-vars.yaml con i nomi dei bucket. Questo file contiene variabili di ambiente che passerai a Cloud Functions in un secondo momento.

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

Crea una raccolta Firestore

In una sezione successiva analizzerai le metriche sul rendimento della pagina. In questa sezione creerai una raccolta Firestore per archiviare i risultati di ogni analisi.

  1. Nella console Google Cloud, vai alla pagina di Firestore.

    Vai alla pagina di Firestore

  2. Se non hai mai creato un database Firestore prima d'ora, esegui questi passaggi:

    1. Fai clic su Seleziona modalità Native per attivare Firestore.
    2. Seleziona una località regionale vicina a quella in cui verrà eseguito Cloud Functions.
    3. Fai clic su Crea database.

    La configurazione richiede qualche istante.

  3. Fai clic su Avvia raccolta e imposta l'ID raccolta su page-metrics.

  4. Fai clic su Salva.

Crea un argomento e una sottoscrizione Pub/Sub

In genere è opportuno informare le parti e i sistemi interessati se l'analisi indica che una pagina ha prestazioni scarse. In questa sezione creerai argomenti Pub/Sub che contengono messaggi che descrivono eventuali prestazioni scadenti.

  1. In Cloud Shell, crea un argomento Pub/Sub denominato performance-alerts:

    gcloud pubsub topics create performance-alerts
    
  2. Creare una sottoscrizione all'argomento. Puoi usare la sottoscrizione per verificare che i messaggi di avviso vengano pubblicati nell'argomento.

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

Raccolta delle metriche sul rendimento delle pagine

Molti siti web utilizzano JavaScript per visualizzare dinamicamente i contenuti delle pagine. Ciò rende più complicata l'analisi del rendimento, poiché il client deve emulare un browser per caricare completamente la pagina web. Il runtime Node.js per Cloud Functions supporta il Chrome headless, che fornisce la funzionalità di un browser web completo in un ambiente serverless.

Puppeteer è una libreria Node.js creata dal team Chrome DevTools che fornisce un'API di alto livello per controllare Chrome headless. Per impostazione predefinita, Puppeteer installa una versione recente del browser insieme alla libreria. Pertanto, puoi aggiungere Puppeteer come dipendenza alla Cloud Function per utilizzare facilmente Chrome headless all'interno della funzione.

La misurazione e l'analisi del rendimento delle pagine web è un campo ampio e complesso. Per semplicità, in questo tutorial userai Puppeteer per raccogliere alcune metriche di primo livello sul rendimento delle pagine. Tuttavia, puoi anche utilizzare Puppeteer e il protocollo CDP (Chrome DevTools) per raccogliere informazioni più dettagliate, ad esempio le tracce cronologiche. Puoi anche rappresentare meglio l'esperienza dell'utente finale emulando la congestione della rete ed eseguendo la limitazione della CPU. Per una buona introduzione all'analisi delle prestazioni delle pagine web, visita il sito per sviluppatori web di Chrome.

Tieni presente che ci sono molti fattori che influenzano i tempi di caricamento delle pagine web, comprese le caratteristiche delle prestazioni del client. È importante stabilire linee di riferimento utilizzando le configurazioni di CPU e RAM della Cloud Function.

Il seguente snippet del file tracer/index.js mostra come utilizzare Pupeteer per caricare la pagina 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);
  • In Cloud Shell, esegui il deployment della Cloud Function trace:

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

    Il deployment della Cloud Function può richiedere diversi minuti.

    I parametri di deployment specificano che la funzione deve avere un trigger HTTP, utilizzare il runtime Node.js 10 e avere 1 GB di memoria. Questa quantità di memoria è necessaria per eseguire Chrome headless. Le variabili di ambiente vengono fornite alla funzione utilizzando il file env-vars.yaml

Per impostazione predefinita, le funzioni Cloud Functions attivate da HTTP consentono chiamate non autenticate. Di conseguenza, devi proteggere la funzione di traccia.

  • Rimuovi il ruolo IAM cloudfunctions.invoker per allUsers:

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

Analizzare le metriche

Un obiettivo tipico degli esercizi di monitoraggio delle prestazioni web è monitorare le prestazioni rispetto ad alcuni benchmark definiti. Se una determinata metrica supera una soglia prevista, può indicare un problema con una release software recente o un problema dell'infrastruttura sottostante.

In questa sezione creerai una Cloud Function in Python per analizzare le metriche della pagina e mantenere i risultati in una raccolta Firestore. La funzione valuta la metrica FirstMeaningfulPaint in base a una soglia prevista e contrassegna il risultato dell'analisi come problematico se la soglia viene superata. FirstMeaningfulPaint è una metrica incentrata sull'utente che descrive in modo generale quando una pagina diventa utile per l'utente. Puoi utilizzare un trigger di Cloud Storage per eseguire la funzione di analisi ogni volta che viene scritto un nuovo file nel bucket contenente le metriche.

Il seguente snippet del file analyzer/main.py mostra la logica della funzione:

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'])
  • Esegui il deployment della Cloud Function analyze:

    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 funzione viene attivata da un evento finalize nel bucket delle metriche, che viene inviato ogni volta che viene creato un oggetto nel bucket. La funzione utilizza il runtime Python 3.7.

Avvisi sugli errori

In genere, devi intraprendere le azioni necessarie se l'analisi delle metriche indica una pagina con rendimento scarso.

In questa sezione creerai una Cloud Function per inviare un messaggio a un argomento Pub/Sub se le prestazioni della pagina non sono soddisfacenti. La funzione viene attivata ogni volta che viene creato un documento nella raccolta Firestore. Gli interessati possono iscriversi all'argomento Pub/Sub e intraprendere le azioni appropriate. Ad esempio, un'app di assistenza potrebbe iscriversi ai messaggi Pub/Sub e inviare un'email, attivare un pager di assistenza o aprire un bug.

Il seguente snippet del file alerter/main.py mostra la logica della funzione:

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)

Nota che l'avviso viene inviato solo se il campo dello stato indica un errore.

  • Esegui il deployment della Cloud Function alert:

    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 funzione viene attivata da un evento document.create nella raccolta Firestore page-metrics. Il suffisso {any} è un carattere jolly che indica che la funzione deve essere attivata ogni volta che viene creato un documento nella raccolta.

Pianificazione dell'analisi

È buona norma monitorare regolarmente le prestazioni delle pagine. Ad esempio, potresti voler analizzare una determinata pagina ogni ora, ogni giorno o ogni settimana. In questa sezione creerai un job Cloud Scheduler per eseguire periodicamente la pipeline di analisi attivando la funzione trace.

Il job Cloud Scheduler viene eseguito utilizzando un account di servizio a cui è stato concesso il ruolo IAM cloudfunctions.invoker richiesto per la funzione trace.

A volte le pagine web non rispondono correttamente o le richieste scadono, quindi i nuovi tentativi sono inevitabili con le app di analisi web. Pertanto, è importante che la logica di nuovo tentativo nell'app sia presente nell'app. Cloud Functions supporta i nuovi tentativi per le funzioni in background.

I nuovi tentativi non sono disponibili per le funzioni Cloud Functions attivate da HTTP, quindi non puoi utilizzare Cloud Functions per ritentare la funzione trace. Tuttavia, Cloud Scheduler supporta i nuovi tentativi. Per ulteriori informazioni sulla configurazione dei parametri di nuovo tentativo, consulta la documentazione di RetryConfig.

  1. Verifica che il deployment delle tre funzioni Cloud Functions sia stato eseguito correttamente e che sia visualizzato lo stato ACTIVE:

    gcloud functions list
    
  2. Crea un nuovo account di servizio che verrà utilizzato come identità per eseguire il job di Cloud Scheduler:

    gcloud iam service-accounts create tracer-job-sa
    
  3. Concedi al nuovo account di servizio il ruolo IAM cloudfunctions.invoker per la funzione 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 job 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
    

    Poiché il job chiama la funzione trace attivata tramite HTTP, il comando specifica il tipo di job come http e fornisce l'URL del trigger della funzione come valore uri. La pagina da analizzare, in questo caso www.example.com, è fornita nel flag message-body. Il flag oidc-service-account-email definisce l'account di servizio da utilizzare per l'autenticazione. Il comando indica il numero di nuovi tentativi utilizzando il flag max-retry-attempts e il valore trasmesso con il flag schedule imposta la pianificazione dell'esecuzione ogni giorno alle 03:00 UTC.

Verifica dei risultati

In questa sezione verificherai di aver ottenuto il comportamento previsto sia per le condizioni di successo che per quelle di errore.

Verifica l'esito positivo

Il job Cloud Scheduler non verrà eseguito fino all'orario pianificato successivo, in questo caso le 03:00 UTC. Per vedere immediatamente i risultati, puoi attivare manualmente un'esecuzione.

  1. Attendi 90 secondi per il completamento dell'inizializzazione del job dello scheduler.
  2. Esegui il job Cloud Scheduler manualmente:

    gcloud scheduler jobs run traceWithRetry
    
  3. Attendi circa 30 secondi per il completamento della pipeline della funzione.

  4. Elenca i contenuti del bucket delle metriche per mostrare che le metriche della pagina sono state raccolte:

    gsutil ls -l gs://$METRICS_BUCKET
    
  5. Nella console Google Cloud, apri la pagina del visualizzatore di Cloud Logging:

    Vai alla pagina Logging

    Vedrai i messaggi di log di ciascuna delle tre funzioni Cloud Functions: trace, analyze e alert. Il flusso dei log può richiedere alcuni istanti, quindi potrebbe essere necessario aggiornare il riquadro dei log.

    La console di logging non mostra errori

  6. Prendi nota dell'ID documento Firestore, indicato dopo il testo Created new Firestore document page-metrics/

  7. Nella console Google Cloud, vai alla pagina di Firestore:

    Vai alla pagina di Firestore

  8. Esamina il documento che contiene i risultati dell'analisi. I valori del documento indicano uno stato PASS e contengono le più recenti metriche sul rendimento della pagina.

  9. In Cloud Shell, verifica che non siano stati inviati messaggi di avviso all'argomento Pub/Sub provando a eseguire il pull di un messaggio dalla sottoscrizione:

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

    Non visualizzi alcun elemento nell'elenco.

Verifica non riuscita

  1. Attiva manualmente la funzione di traccia. Questa volta, devi fornire la pagina Tutorial Google Cloud come URL. Questa pagina ha molti contenuti dinamici che aumentano il tempo di caricamento della pagina oltre la soglia massima prevista.

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

    Poiché disponi del ruolo IAM progetto Owner o Editor, disponi di autorizzazioni sufficienti per richiamare la funzione.

  2. Attendi circa 30 secondi per il completamento della pipeline della funzione.

  3. Elenca i contenuti del bucket delle metriche per verificare che siano state raccolte altre metriche:

    gsutil ls -l gs://$METRICS_BUCKET
    

    Ora vedrai due elementi in ogni bucket.

  4. Nella console Google Cloud, vai alla pagina del visualizzatore Cloud Logging e filtra i log della funzione Cloud Function:

    Vai alla pagina Logging

    Visualizzi un errore della funzione analyze che indica che la pagina ha superato il tempo di caricamento massimo consentito. Ancora una volta, potresti dover aggiornare il riquadro dei log per vedere i messaggi più recenti.

    Console di logging che mostra errori

  5. Prendi nota dell'ID documento Firestore.

  6. Nella console Google Cloud, vai alla pagina di Firestore:

    Vai alla pagina di Firestore

  7. Trova il documento che descrive l'analisi non riuscita.

    Il campo dello stato è contrassegnato come FAIL.

  8. In Cloud Shell, verifica che un messaggio di avviso sia stato inviato all'argomento Pub/Sub eseguendo il pull di un messaggio dalla sottoscrizione.

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

    Questa volta vedrai il contenuto del messaggio.

Esegui la pulizia

Elimina il progetto

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Passaggi successivi

  • Scopri di più sulle tecnologie serverless di Google Cloud.
  • Esplora altri tutorial su Cloud Functions.
  • Guarda il video di Google I/O '18 che descrive altri utilizzi di Puppeteer e Chrome headless.
  • Esplora le architetture di riferimento, i diagrammi e le best practice su Google Cloud. Visita il nostro Cloud Architecture Center.