Surveiller les performances Web sans serveur à l'aide de Cloud Functions


Ce tutoriel explique comment créer une application de surveillance des performances Web à l'aide des technologies sans serveur Google Cloud.

Les performances jouent un rôle majeur dans le succès de toute application Web. L'acquisition et la fidélisation de vos clients pourraient être affectées par des performances médiocres de votre site, et entraîner des répercussions sur vos objectifs d'entreprise. Les performances sont un critère essentiel de réussite à prendre en compte lors des phases de conception, de création et de test de votre application Web.

Toutefois, les performances des pages évoluent au fil du temps, à mesure que votre application se transforme. Il arrive que les développeurs ajoutent ou actualisent des images et des scripts, ou que l'infrastructure de diffusion de l'application sous-jacente elle-même soit modifiée. Par conséquent, il est important de surveiller régulièrement les performances des pages. En règle générale, les métriques de performances sont stockées pour permettre l'analyse historique. La mise en place d'alertes en cas de performances de page inférieures à certains seuils déterminés est une pratique courante.

Objectifs

  • Créer une fonction Cloud qui utilise Headless Chrome pour collecter les métriques de performance des pages Web.
  • Stocker les métriques dans Cloud Storage.
  • Créer une autre fonction Cloud déclenchée par l'événement de création Cloud Storage afin d'analyser les métriques des pages.
  • Stocker les résultats d'analyse dans Firestore.
  • Créer une autre fonction Cloud déclenchée par l'événement de création Firestore afin de publier une alerte sur Pub/Sub si les performances des pages posent problème.
  • Créer une tâche Cloud Scheduler pour déclencher périodiquement la première fonction Cloud.
  • Vérifier les réussites et les échecs dans les sorties.

Coûts

Ce tutoriel utilise des composants facturables de Google Cloud, dont :

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

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Activer les API Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build.

    Activer les API

  5. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  6. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  7. Activer les API Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build.

    Activer les API

Architecture

Les opérations de surveillance des performances Web sont généralement sans état et de courte durée. Elles sont souvent basées sur des événements et s'exécutent selon un calendrier ou sont déclenchées dans le cadre d’un autre processus, tel qu’un pipeline de tests automatisé. C'est pourquoi ces architectures sans serveur sont intéressantes pour la mise en œuvre d'applications d'analyse Web.

Dans ce tutoriel, vous utilisez diverses parties de la pile sans serveur de Google Cloud, y compris Cloud Functions, Firestore, Cloud Scheduler et Pub/Sub. Vous n'avez pas à gérer l'infrastructure pour ces services et vous ne payez que ce que vous utilisez. Le noyau de l'application est mis en œuvre à l'aide de Cloud Functions, qui fournit un environnement d'exécution sans serveur évolutif et basé sur les événements. Cloud Functions vous permet de créer et de connecter des applications à l'aide d'éléments logiques indépendants et faiblement liés.

Le schéma suivant présente l'architecture de la solution sans serveur que vous créez dans ce tutoriel.

Architecture de la solution d'analyse Web sans serveur

Préparer l'environnement

Avant de créer l'environnement sans serveur, vous devez obtenir le code de GitHub, définir les variables et préparer les ressources dont vous aurez besoin ultérieurement pour l'analyse et le stockage.

Obtenir le code et définir les variables d'environnement

  1. Dans Google Cloud Console, ouvrez Cloud Shell.

    Ouvrir Cloud Shell

  2. Clonez le dépôt contenant le code des fonctions Cloud utilisées dans ce tutoriel :

    git clone https://github.com/GoogleCloudPlatform/solutions-serverless-web-monitoring.git
    
  3. Accédez au répertoire des fonctions :

    cd solutions-serverless-web-monitoring/functions
    
  4. Définissez l'ID et le numéro de projet actuels en tant que variables d'interface système :

    export PROJECT=$DEVSHELL_PROJECT_ID
    export PROJECT_NUM=$(gcloud projects list \
        --filter="$PROJECT" \
        --format="value(PROJECT_NUMBER)")
    
  5. Définissez la région de déploiement par défaut de Cloud Functions. L'exemple suivant définit la région sur us-east1, mais vous pouvez la remplacer par n'importe quelle région dans laquelle Cloud Functions est disponible.

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

Créer des buckets Cloud Storage

Dans cette section, vous créez un bucket Cloud Storage pour stocker les données de performances de page collectées. S'il est possible de choisir n'importe quel emplacement ou classe de stockage, il est conseillé de créer des buckets au même emplacement que les fonctions Cloud qui les utiliseront.

  1. Dans Cloud Shell, exportez une variable d'interface système pour les noms des buckets Cloud Storage dans lesquels les métriques seront stockées. Les noms de buckets devant être globalement uniques, votre numéro de projet Google Cloud est donc utilisé comme suffixe dans la commande suivante.

    export METRICS_BUCKET=page-metrics-$PROJECT_NUM
    
  2. Créez les buckets à l'aide de l'outil gsutil :

    gsutil mb -l $REGION gs://$METRICS_BUCKET
    
  3. Mettez à jour le fichier env-vars.yaml avec les noms de bucket. Ce fichier contient des variables d'environnement que vous transmettrez ultérieurement aux fonctions Cloud.

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

Créer une collection Firestore

Plus tard, vous analyserez les métriques de performances des pages. Dans cette section, vous créez une collection Firestore pour stocker les résultats de chaque analyse.

  1. Dans Google Cloud Console, accédez à la page Firestore.

    Accéder à la page Firestore

  2. Si vous n'avez jamais créé de base de données Firestore, procédez comme suit :

    1. Cliquez sur Sélectionner le mode natif pour activer Firestore.
    2. Sélectionnez un emplacement régional proche de la région dans laquelle vos fonctions Cloud seront exécutées.
    3. Cliquez sur Créer une base de données.

    La configuration prend quelques instants.

  3. Cliquez sur Commencer une collection, puis définissez l'ID de collection sur page-metrics.

  4. Cliquez sur Enregistrer.

Créer un sujet et un abonnement Pub/Sub

Si l'analyse a détecté un dysfonctionnement sur une page, vous souhaiterez probablement notifier les systèmes et les parties concernés. Dans cette section, vous créez des sujets Pub/Sub destinés aux messages décrivant les problèmes constatés.

  1. Dans Cloud Shell, créez un sujet Pub/Sub nommé performance-alerts :

    gcloud pubsub topics create performance-alerts
    
  2. Créez un abonnement associé au sujet. L'abonnement vous permet de vérifier que les messages d'alerte sont publiés dans le sujet.

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

Collecter les métriques de performances de la page

De nombreux sites Web utilisent JavaScript pour afficher le contenu de la page de manière dynamique. Cela complique l'analyse des performances, car le client doit émuler un navigateur afin de charger la page Web dans son intégralité. L'environnement Node.js pour Cloud Functions est compatible avec Headless Chrome (mode sans interface graphique de Chrome), qui fournit les fonctionnalités complètes d'un navigateur Web dans un environnement sans serveur.

Puppeteer est une bibliothèque Node.js développée par l'équipe Chrome DevTools, qui fournit une API de haut niveau pour contrôler Headless Chrome. Par défaut, Puppeteer installe une version récente du navigateur avec la bibliothèque. Par conséquent, vous pouvez ajouter Puppeteer en tant que dépendance à la fonction Cloud afin de faciliter l'utilisation de Chrome sans interface graphique dans la fonction.

L'évaluation et l'analyse des performances des pages Web est un domaine vaste et complexe. Dans un souci de simplification, ce tutoriel utilise Puppeteer pour collecter certaines métriques de performances de page de premier niveau. Toutefois, rien ne vous empêche d'utiliser Puppeteer et le CDP (Chrome DevTools Protocol) pour collecter des informations plus détaillées, telles que les traces chronologiques. Si vous souhaitez améliorer la présentation de l'expérience de l'utilisateur final, vous pouvez émuler la congestion du réseau et limiter la bande passante consommée par le processeur. Pour aller plus loin dans l'analyse des performances des pages Web, reportez-vous au site Google Chrome pour les développeurs.

Notez que de nombreux facteurs influent sur le temps de chargement des pages Web, y compris les caractéristiques de performances du client. Il est important d'établir des références à partir des configurations de processeur et de RAM de la fonction Cloud.

L'extrait suivant du fichier tracer/index.js montre comment utiliser Puppeteer pour charger la page 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);
  • Dans Cloud Shell, déployez la fonction Cloud trace :

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

    Le déploiement de la fonction peut prendre plusieurs minutes.

    Les paramètres de déploiement spécifient que la fonction doit avoir un déclencheur HTTP, utiliser l'environnement d'exécution Node.js 10 et disposer de 1 Go de mémoire. Cette quantité de mémoire est nécessaire pour utiliser Headless Chrome. Les variables d'environnement sont fournies à la fonction à l'aide du fichier env-vars.yaml.

Par défaut, les fonctions Cloud déclenchées par HTTP autorisent les appels non authentifiés. Vous devez donc sécuriser la fonction Trace.

  • Supprimez le rôle IAM cloudfunctions.invoker pour allUsers :

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

Analyser les métriques

L'un des objectifs des opérations de surveillance des performances Web consiste à effectuer un suivi par rapport à certains benchmarks. Le dépassement d'un seuil déterminé dans une métrique peut indiquer un problème lié à une version logicielle récente ou à l'infrastructure sous-jacente.

Dans cette section, vous allez créer une fonction Cloud en Python pour analyser les métriques de page et conserver les résultats dans une collection Firestore. La fonction évalue la métrique FirstMeaningfulPaint par rapport à un seuil déterminé, et signale un problème dans le résultat de l'analyse en cas de dépassement. FirstMeaningfulPaint est une métrique centrée sur l'utilisateur qui décrit de manière générale à quel moment une page devient utile pour l'utilisateur. Vous utilisez un déclencheur Cloud Storage pour exécuter la fonction d'analyse chaque fois qu'un nouveau fichier est écrit dans le bucket contenant les métriques.

L'extrait de code suivant du fichier analyzer/main.py montre la logique de la fonction :

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'])
  • Déployez la fonction Cloud 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 fonction est déclenchée par un événement finalize dans le bucket contenant les métriques, qui est envoyé chaque fois qu'un objet est créé dans le bucket. La fonction utilise l'environnement d'exécution Python 3.7.

Alerte sur les échecs

En règle générale, vous souhaitez prendre des mesures si l'analyse des métriques indique une page aux performances médiocres.

Dans cette section, vous créez une fonction Cloud pour envoyer un message à un sujet Pub/Sub si les performances de la page ne sont pas satisfaisantes. La fonction est déclenchée chaque fois qu'un document est créé dans la collection Firestore. Les parties concernées peuvent s'abonner au sujet Pub/Sub et prendre les mesures appropriées. Par exemple, une application d'assistance peut s'abonner aux messages Pub/Sub et envoyer un e-mail, déclencher une page d'aide ou signaler un bug.

L'extrait de code suivant du fichier alerter/main.py montre la logique de la fonction :

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)

Notez que l'alerte n'est envoyée que si le champ d'état indique un échec.

  • Déployez la fonction Cloud 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 fonction est déclenchée par un événement document.create dans la collection Firestore page-metrics. Le suffixe {any} est un caractère générique indiquant que la fonction doit être déclenchée chaque fois qu'un document est créé dans la collection.

Planifier l'analyse

Il est recommandé de surveiller régulièrement les performances des pages. Par exemple, vous pouvez analyser une page donnée toutes les heures, tous les jours ou toutes les semaines. Dans cette section, vous allez créer une tâche Cloud Scheduler pour exécuter régulièrement le pipeline d'analyse en déclenchant la fonction trace.

La tâche Cloud Scheduler est exécutée à l'aide d'un compte de service disposant du rôle IAM cloudfunctions.invoker requis pour la fonction trace.

Il arrive que les pages Web ne répondent pas correctement ou que les requêtes expirent. C'est pourquoi les nouvelles tentatives sont inévitables dans les applications d'analyse Web. Il est donc important d'avoir une logique de relance dans votre application. Cloud Functions accepte les tentatives de fonctions d'arrière-plan.

Les nouvelles tentatives ne sont pas disponibles pour les fonctions Cloud Functions déclenchées par HTTP. Vous ne pouvez donc pas utiliser Cloud Functions pour essayer de nouveau la fonction trace. En revanche, vous pouvez le faire à partir de Cloud Scheduler. Reportez-vous à la documentation sur RetryConfig pour plus d'informations.

  1. Vérifiez que les trois fonctions Cloud ont été correctement déployées et affichent l'état ACTIVE :

    gcloud functions list
    
  2. Créez un nouveau compte de service qui sera utilisé comme identité pour exécuter la tâche Cloud Scheduler :

    gcloud iam service-accounts create tracer-job-sa
    
  3. Attribuez au nouveau compte de service le rôle IAM cloudfunctions.invoker pour la fonction trace :

    gcloud beta functions add-iam-policy-binding trace \
        --role roles/cloudfunctions.invoker \
        --member "serviceAccount:tracer-job-sa@$PROJECT.iam.gserviceaccount.com"
    
  4. Créez une tâche 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
    

    Comme la tâche appelle la fonction trace déclenchée par HTTP, la commande spécifie le type de tâche en tant que http et fournit l'URL de déclenchement de la fonction en tant que valeur uri. La page à analyser, ici www.example.com, est fournie dans l'option message-body. L'option oidc-service-account-email définit le compte de service à utiliser pour l'authentification. La commande indique le nombre de tentatives à effectuer avec l'option max-retry-attempts. La valeur transmise avec l'option schedule définit la planification d'exécution sur 3h00 UTC tous les jours.

Vérifier les résultats

Dans cette section, vous vérifiez que vous obtenez le comportement attendu pour les conditions de réussite et d'échec.

Vérifier le bon déroulement de la tâche

La tâche Cloud Scheduler ne s'exécutera pas avant la prochaine heure planifiée, soit 3:00 a.m. UTC. Pour voir les résultats immédiatement, vous pouvez déclencher manuellement une analyse.

  1. Attendez 90 secondes que l'initialisation de la tâche de planification se termine.
  2. Exécutez la tâche Cloud Scheduler manuellement :

    gcloud scheduler jobs run traceWithRetry
    
  3. Attendez environ 30 secondes que le pipeline de fonctions se termine.

  4. Répertoriez le contenu du bucket contenant les métriques pour indiquer que les métriques de la page ont été collectées :

    gsutil ls -l gs://$METRICS_BUCKET
    
  5. Dans la console Google Cloud, ouvrez la page de la visionneuse Cloud Logging :

    Accéder à la page Logging

    Les messages de journal de chacune des trois fonctions Cloud Functions s'affichent : trace, analyze et alert. La transmission des journaux peut prendre un certain temps et vous devrez peut-être actualiser le volet.

    Console Logging n'affichant aucune erreur

  6. Prenez note de l'ID du document Firestore, qui est répertorié après le texte Created new Firestore document page-metrics/.

  7. Dans la console Google Cloud, accédez à la page Firestore :

    Accéder à la page Firestore

  8. Examinez le document contenant les résultats de l'analyse. Les valeurs du document indiquent un état PASS et contiennent les dernières métriques de performances de la page.

  9. Dans Cloud Shell, vérifiez qu'aucun message d'alerte n'a été envoyé au sujet Pub/Sub en essayant de retirer un message de l'abonnement :

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

    Vous ne voyez aucun élément répertorié.

Vérifier l'échec

  1. Déclenchez manuellement la fonction Trace. Cette fois, vous fournissez la page Tutoriels Google Cloud en tant qu'URL. Cette page contient une quantité importante de contenu dynamique qui augmente le temps de chargement par rapport au seuil maximal défini.

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

    Comme vous possédez le rôle IAM Owner ou Editor du projet, vous disposez des autorisations suffisantes pour appeler la fonction.

  2. Attendez environ 30 secondes que le pipeline de fonctions se termine.

  3. Répertoriez le contenu du bucket des métriques pour vérifier que des métriques supplémentaires ont été collectées :

    gsutil ls -l gs://$METRICS_BUCKET
    

    Vous voyez maintenant deux éléments dans chaque bucket.

  4. Dans la console Google Cloud, accédez à la page de la visionneuse Cloud Logging et filtrez les journaux de la fonction Cloud :

    Accéder à la page Logging

    La fonction analyze comporte une erreur indiquant que la page a dépassé le temps de chargement maximal autorisé. Là encore, vous devrez peut-être actualiser le volet des journaux pour afficher les derniers messages.

    Console Logging affichant des erreurs

  5. Notez l’ID du document Firestore.

  6. Dans la console Google Cloud, accédez à la page Firestore :

    Accéder à la page Firestore

  7. Recherchez le document contenant une description de l'échec de l'analyse.

    Le champ d'état indique FAIL.

  8. Dans Cloud Shell, vérifiez qu'un message d'alerte a été envoyé au sujet Pub/Sub en extrayant un message de l'abonnement.

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

    Cette fois, vous voyez le contenu du message.

Nettoyer

Supprimer le projet

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Étape suivante

  • Familiarisez-vous avec les technologies sans serveur Google Cloud.
  • Découvrez d'autres tutoriels Cloud Functions.
  • Regardez la vidéo de la conférence Google I/O 2018 décrivant d'autres utilisations de Puppeteer et de Headless Chrome.
  • Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Centre d'architecture cloud.