Ce tutoriel montre comment une application d'interface (dans ce cas, une page Web) peut gérer de grands volumes de données entrantes lorsque vous utilisez Google Cloud. Le tutoriel décrit certains des défis liés aux flux à volume élevé. L'exemple d'application fourni avec ce tutoriel montre comment utiliser WebSockets pour visualiser un flux dense de messages publiés dans un sujet Pub/Sub, en les traitant rapidement afin de toujours disposer d'une interface performante.
Ce tutoriel est destiné aux développeurs qui maîtrisent la communication de navigateur à serveur via HTTP et l'écriture d'applications d'interface à l'aide de HTML, CSS et JavaScript. Pour ce tutoriel, nous partons du principe que vous avez une certaine expérience de Google Cloud et que vous maîtrisez les outils de ligne de commande Linux.
Objectifs
- Créer et configurer une instance de machine virtuelle (VM) avec les composants nécessaires pour diffuser les charges utiles d'un abonnement Pub/Sub aux clients de navigateur.
- Configurer un processus sur la VM pour vous abonner à un sujet Pub/Sub et délivrer les messages individuels dans un journal.
- Installer un serveur Web pour diffuser du contenu statique et diffuser le résultat de la commande shell aux clients WebSocket.
- Visualiser les agrégations de flux WebSocket et des exemples de messages individuels dans un navigateur en HTML, CSS et JavaScript.
Coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Avant de commencer
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- Ouvrez Cloud Shell pour exécuter les commandes répertoriées dans ce tutoriel.
Vous allez exécuter toutes les commandes de terminal à partir de Cloud Shell.
- Activez l'API Compute Engine et l'API Pub/Sub :
gcloud services enable compute pubsub
Une fois que vous avez terminé ce tutoriel, évitez de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.
Présentation
Alors que de plus en plus d'applications utilisent des modèles événementiels, il est important que les applications d'interface puissent établir des connexions simples à faible friction avec les services de messagerie qui constituent la base de ces architectures.
Il existe plusieurs options pour diffuser des données vers des clients de navigateur Web : la plus courante est WebSockets. Ce tutoriel explique comment installer un processus qui s'abonne à un flux de messages publiés sur un sujet Pub/Sub et acheminer ces messages vers des clients connectés via WebSockets.
Dans le cadre de ce tutoriel, vous travaillez sur le sujet Pub/Sub disponible publiquement utilisé dans l'atelier de programmation Google Dataflow NYC Taxi Tycoon. Cet article fournit un flux en temps réel d'une simulation de télémétrie de taxis basée sur l'historique des données de course relevées à New York à partir des ensembles de données de l'historique des courses de la Commission des taxis et limousines.
Architecture
Le schéma suivant montre l'architecture du tutoriel que vous créez dans ce tutoriel.
Le diagramme montre un éditeur de message qui se trouve en dehors du projet et qui contient la ressource Compute Engine. L'éditeur envoie des messages à un sujet Pub/Sub. L'instance Compute Engine transmet les messages via WebSockets à un navigateur qui exécute un tableau de bord basé sur HTML5 et JavaScript.
Ce tutoriel utilise une combinaison d'outils pour relier Pub/Sub et Websockets :
pulltop
est un programme Node.js que vous installez dans le cadre de ce tutoriel. L'outil s'abonne à un sujet Pub/Sub et diffuse les messages reçus en sortie standard.websocketd
est un petit outil de ligne de commande qui encapsule un programme d'interface de ligne de commande existant et lui permet d'être accessible via WebSocket.
En combinant pulltop
et websocketd
, vous pouvez diffuser les messages du sujet Pub/Sub dans un navigateur à l'aide de WebSockets.
Ajustement du débit des sujets Pub/Sub
Le sujet Pub/Sub public de NYC Taxi Tycoon génère entre 2 000 et 2 500 simulations de mises à jour de courses en taxi par seconde, jusqu'à 8 Mo ou plus par seconde. Le contrôle de flux intégré dans Pub/Sub ralentit automatiquement la fréquence des messages d'un abonné si Pub/Sub détecte une file d'attente croissante de messages non confirmés. Par conséquent, vous pouvez constater une forte variabilité de la fréquence de messages entre différents postes de travail, connexions réseau et code de traitement d'interface.
Traitement efficace des messages du navigateur
Étant donné le grand nombre de messages envoyés par le flux WebSocket, vous devez être attentif à l'écriture du code d'interface qui traite ce flux.
Par exemple, vous pourriez créer des éléments HTML de façon dynamique pour chaque message. Toutefois, à la fréquence attendue, la mise à jour de la page de chaque message risquerait de verrouiller la fenêtre du navigateur. Les fréquentes allocations de mémoire résultant de la création dynamique d'éléments HTML prolongent également la durée de récupération de mémoire, ce qui nuit à l'expérience utilisateur. En bref, vous ne souhaitez pas appeler document.createElement()
pour chacun des quelque 2 000 messages reçus chaque seconde.
Voici la marche à suivre pour gérer ce flux dense de messages :
- Calculez et mettez à jour en continu un ensemble de métriques de flux en temps réel, en affichant la majorité des informations sur les messages observés sous forme de valeurs globales.
- Utilisez un tableau de bord basé sur un navigateur pour visualiser un petit échantillon de messages individuels selon une planification prédéfinie, en affichant uniquement les événements de dépôt et de prise en charge en temps réel.
La figure suivante montre le tableau de bord créé dans le cadre de ce tutoriel.
La figure illustre une latence de dernier message de 24 millisecondes à une fréquence de près de 2 100 messages par seconde. Si les chemins de code critiques pour le traitement de chaque message individuel ne se terminent pas à temps, le nombre de messages observés par seconde diminue à mesure que la dernière latence augmente.
L'échantillonnage des courses est effectué à l'aide de l'API JavaScript setInterval
définie pour un cycle toutes les trois secondes, ce qui empêche l'interface de créer un nombre considérable d'éléments DOM au cours de sa durée de vie. (La grande majorité d'entre eux sont presque impossibles à observer à des taux supérieurs à 10 par seconde.)
Le tableau de bord commence à traiter les événements au milieu du flux. Les courses déjà en cours sont donc reconnues comme nouvelles par le tableau de bord, sauf si elles ont déjà été vues. Le code utilise un tableau associatif pour stocker chaque course observée, indexée par la valeur ride_id
, et supprime la référence à une course particulière lorsque le passager est déposé. Les courses à l'état "en route" ou "déposé" ajoutent une référence à ce tableau, sauf (pour "en route") si la course a déjà été observée.
Installer et configurer le serveur WebSocket
Pour commencer, créez une instance Compute Engine que vous utiliserez comme serveur WebSocket. Une fois l'instance créée, installez-y les outils dont vous aurez besoin ultérieurement.
Dans Cloud Shell, définissez la zone Compute Engine par défaut. L'exemple suivant montre
us-central1-a
, mais vous pouvez utiliser n'importe quelle zone.gcloud config set compute/zone us-central1-a
Créez une instance Compute Engine nommée
websocket-server
dans la zone par défaut :gcloud compute instances create websocket-server --tags wss
Ajoutez une règle de pare-feu qui autorise le trafic TCP sur le port
8000
vers toute instance marquée commewss
:gcloud compute firewall-rules create websocket \ --direction=IN \ --allow=tcp:8000 \ --target-tags=wss
Si vous utilisez un projet existant, assurez-vous que le port TCP
22
est ouvert pour autoriser la connectivité SSH à l'instance.Par défaut, la règle de pare-feu
default-allow-ssh
est activée dans le réseau par défaut. Toutefois, si vous ou votre administrateur avez supprimé la règle par défaut dans un projet existant, le port TCP22
n'est peut-être pas ouvert. (Si vous avez créé un projet pour ce tutoriel, la règle est activée par défaut, et aucune action de votre part n'est requise.)Ajoutez une règle de pare-feu qui autorise le trafic TCP sur le port
22
vers toute instance marquée commewss
:gcloud compute firewall-rules create wss-ssh \ --direction=IN \ --allow=tcp:22 \ --target-tags=wss
Connectez-vous à l'instance via SSH :
gcloud compute ssh websocket-server
À la commande de terminal de l'instance, basculez les comptes sur
root
pour pouvoir installer le logiciel :sudo -s
Installez les outils
git
etunzip
:apt-get install -y unzip git
Installez le binaire
websocketd
sur l'instance :cd /var/tmp/ wget \ https://github.com/joewalnes/websocketd/releases/download/v0.3.0/websocketd-0.3.0-linux_386.zip unzip websocketd-0.3.0-linux_386.zip mv websocketd /usr/bin
Installer Node.js et le code du tutoriel
Dans un terminal de l'instance, installez Node.js :
curl -sL https://deb.nodesource.com/setup_10.x | bash - apt-get install -y nodejs
Téléchargez le dépôt source du tutoriel :
exit cd ~ git clone https://github.com/GoogleCloudPlatform/solutions-pubsub-websockets.git
Modifiez les autorisations sur
pulltop
pour autoriser l'exécution :cd solutions-pubsub-websockets chmod 755 pulltop/pulltop.js
Installez les dépendances
pulltop
:cd pulltop npm install sudo npm link
Vérifier que pulltop peut lire les messages
Sur l'instance, exécutez
pulltop
sur le sujet public :pulltop projects/pubsub-public-data/topics/taxirides-realtime
Si
pulltop
fonctionne, un flux de résultats semblable à celui-ci s'affiche :{"ride_id":"9729a68d-fcde-484b-bc32-bf29f5188628","point_idx":328,"latitude" :40.757360000000006,"longitude":-73.98228,"timestamp":"2019-03-22T20:03:51.6 593-04:00","meter_reading":11.069151,"meter_increment":0.033747412,"ride_stat us":"enroute","passenger_count":1}
Appuyez sur
Ctrl+C
pour arrêter le flux.
Établir le flux de messages vers websocketd
Maintenant que pulltop
peut lire le sujet Pub/Sub, vous pouvez démarrer le processus websocketd
pour commencer à envoyer des messages au navigateur.
Capturer des messages de sujet dans un fichier local
Pour ce tutoriel, vous allez capturer le flux de messages que vous recevez de pulltop
et l'écrire dans un fichier local. La capture du trafic des messages dans un fichier local entraîne une augmentation de l'espace de stockage, mais dissocie également l'opération du processus websocketd
des messages de sujet Pub/Sub diffusés. La capture locale des informations permet de suspendre temporairement la diffusion Pub/Sub (par exemple pour ajuster les paramètres de contrôle de flux) sans forcer la réinitialisation des clients WebSocket actuellement connectés. Lorsque le flux de messages est rétabli, websocketd
reprend automatiquement la diffusion des messages aux clients.
Sur l'instance, exécutez
pulltop
sur le sujet public et redirigez le message vers le fichier localtaxi.json
. La commandenohup
demande au système d'exploitation de maintenir le processuspulltop
en cours d'exécution si vous vous déconnectez ou fermez le terminal.nohup pulltop \ projects/pubsub-public-data/topics/taxirides-realtime > \ /var/tmp/taxi.json &
Vérifiez que les messages JSON sont écrits dans le fichier :
tail /var/tmp/taxi.json
Si les messages sont écrits dans le fichier
taxi.json
, le résultat est semblable à celui-ci :{"ride_id":"9729a68d-fcde-484b-bc32-bf29f5188628","point_idx":328,"latitude" :40.757360000000006,"longitude":-73.98228,"timestamp":"2019-03-22T20:03:51.6 593-04:00","meter_reading":11.069151,"meter_increment":0.033747412,"ride_sta tus":"enroute","passenger_count":1}
Accédez au dossier Web de votre application :
cd ../web
Démarrez
websocketd
pour lancer la diffusion du contenu du fichier local à l'aide de WebSockets :nohup websocketd --port=8000 --staticdir=. tail -f /var/tmp/taxi.json &
La commande
websocketd
est exécutée en arrière-plan. L'outilwebsocketd
utilise le résultat de la commandetail
et diffuse chaque élément en tant que message WebSocket.Vérifiez le contenu de
nohup.out
pour vous assurer que le serveur a démarré correctement :tail nohup.out
Si tout fonctionne correctement, le résultat ressemble à ce qui suit :
Mon, 25 Mar 2019 14:03:53 -0400 | INFO | server | | Serving using application : /usr/bin/tail -f /var/tmp/taxi.json Mon, 25 Mar 2019 14:03:53 -0400 | INFO | server | | Serving static content from : .
Visualiser les messages
Les messages individuels concernant les courses envoyés au sujet Pub/Sub ont la structure suivante :
{ "ride_id": "562127d7-acc4-4af9-8fdd-4eedd92b6e69", "point_idx": 248, "latitude": 40.74644000000001, "longitude": -73.97144, "timestamp": "2019-03-24T00:46:08.49094-04:00", "meter_reading": 8.40615, "meter_increment": 0.033895764, "ride_status": "enroute", "passenger_count": 1 }
En fonction de ces valeurs, vous calculez plusieurs métriques pour l'en-tête du tableau de bord. Les calculs sont exécutés une seule fois par événement de course entrant. Les valeurs sont les suivantes :
- Latence du dernier message. Il s'agit du nombre de secondes entre l'horodatage de l'événement de la dernière course constatée et l'heure actuelle (dérivée de l'horloge du système qui héberge le navigateur Web).
- Courses actives. Nombre de courses en cours. Ce nombre peut augmenter rapidement et diminuer lorsqu'une valeur
ride_status
pourdropoff
est observée. - Fréquence des messages. Nombre moyen d'événements de course traités par seconde.
- Montant total au compteur. Somme des compteurs pour toutes les courses actives. Ce nombre diminue à mesure que les clients sont déposés.
- Nombre total de passagers. Nombre de passagers toutes courses confondues. Ce nombre diminue à mesure que les courses sont terminées.
- Nombre moyen de passagers par course. Nombre total de courses, divisé par le nombre total de passagers.
- Montant moyen au compteur par passager. Montant total au compteur divisé par le nombre total de passagers.
En plus des métriques et des exemples de courses individuels, le tableau de bord affiche une notification d'alerte au-dessus de la grille des exemples lorsqu'un client est pris en charge ou déposé.
Obtenez l'adresse IP externe de l'instance actuelle :
curl -H "Metadata-Flavor: Google" http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip; echo
Copiez l'adresse IP.
Sur votre ordinateur local, ouvrez un nouveau navigateur Web et saisissez l'URL suivante :
http://$ip-address:8000
Une page contenant le tableau de bord de ce tutoriel s'affiche :
Cliquez sur l'icône représentant un taxi en haut pour ouvrir une connexion au flux et commencer à traiter les messages.
Les courses individuelles sont visualisées avec un échantillon de neuf courses actives toutes les trois secondes :
Vous pouvez cliquer sur l'icône représentant un taxi à tout moment pour démarrer ou arrêter le flux WebSocket. Si la connexion WebSocket est interrompue, l'icône devient rouge et les mises à jour des métriques et des courses individuelles sont interrompues. Pour vous reconnecter, cliquez à nouveau sur l'icône représentant un taxi.
Performances
La capture d'écran suivante montre l'outil de contrôle des performances des Outils pour les développeurs Chrome alors que l'onglet du navigateur traite environ 2 100 messages par seconde.
Avec une distribution des messages à une latence d'environ 30 ms, l'utilisation du processeur est en moyenne d'environ 80 %. L'utilisation de la mémoire est au minimum de 29 Mo avec un total de 57 Mo alloué et augmente ou diminue librement.
Nettoyer
Supprimer des règles de pare-feu
Si vous avez utilisé un projet existant pour ce tutoriel, vous pouvez supprimer les règles de pare-feu que vous avez créées. Il est recommandé de réduire les ports ouverts.
Supprimez la règle de pare-feu que vous avez créée pour autoriser TCP sur le port
8000
:gcloud compute firewall-rules delete websocket
Si vous avez également créé une règle de pare-feu pour autoriser la connectivité SSH, supprimez-la pour autoriser TCP sur le port
22
:gcloud compute firewall-rules delete wss-ssh
Supprimer le projet
Si vous ne souhaitez plus utiliser ce projet, vous pouvez le supprimer.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Étape suivante
- En savoir plus sur Pub/Sub et le protocole WebSockets
- Ajoutez votre clé API Google Maps Platform à
cabdash.js
afin de géolocaliser les courses avec prise en charge et dépôt. - Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Cloud Architecture Center.