1. Présentation
La série d'ateliers de programmation sur la station de migration sans serveur (tutoriels pratiques et d'auto-formation) et les vidéos associées visent à aider les développeurs sans serveur Google Cloud à moderniser leurs applications en les guidant dans une ou plusieurs migrations, principalement en abandonnant les anciens services. Vous améliorez ainsi la portabilité de vos applications, et vous bénéficiez de plus d'options et de flexibilité. Vous pouvez ainsi intégrer un plus large éventail de produits Cloud et y accéder, et passer plus facilement à de nouvelles langues. Bien qu'elle s'adresse initialement aux utilisateurs les plus anciens du cloud, principalement les développeurs d'environnements App Engine (standard), cette série est suffisamment large pour inclure d'autres plates-formes sans serveur telles que Cloud Functions et Cloud Run, ou ailleurs, le cas échéant.
L'objectif de cet atelier de programmation est de montrer aux développeurs Python 2 App Engine comment migrer des tâches d'extraction de la file d'attente des tâches App Engine vers Cloud Pub/Sub. Il existe également une migration implicite d'App Engine NDB vers Cloud NDB pour l'accès à Datastore (principalement abordée dans le module 2), ainsi qu'une mise à niveau vers Python 3.
Dans le module 18, vous apprendrez à ajouter l'utilisation de tâches pull à votre application. Dans ce module, vous allez utiliser l'application du module 18 terminée et migrer son utilisation vers Cloud Pub/Sub. Ceux qui utilisent les files d'attente pour les tâches push migrent vers Cloud Tasks et doivent, à la place, se reporter aux modules 7 à 9.
Vous apprendrez à
- Remplacez l'utilisation de la file d'attente de tâches App Engine (tâches d'extraction) par Cloud Pub/Sub.
- Remplacez l'utilisation d'App Engine NDB par Cloud NDB (consultez également le module 2).
- Porter l'application vers Python 3
Prérequis
- Un projet Google Cloud Platform avec un compte de facturation GCP actif
- Des connaissances de base en Python
- Une connaissance correcte des commandes Linux courantes
- Connaissances de base sur le développement et le déploiement d'applications App Engine
- Exemple d'application App Engine fonctionnelle (module 18)
Enquête
Comment allez-vous utiliser ce tutoriel ?
<ph type="x-smartling-placeholder">Quel est votre niveau d'expérience avec Python ?
Quel est votre niveau d'expérience avec les services Google Cloud ?
<ph type="x-smartling-placeholder">2. Contexte
La file d'attente de tâches App Engine accepte les tâches d'envoi et de retrait. Pour améliorer la portabilité des applications, Google Cloud recommande de migrer des anciens services groupés tels que Task Queue vers d'autres services cloud autonomes ou équivalents.
- La tâche d'envoi de la file d'attente de tâches doit migrer vers Cloud Tasks.
- tâches d'extraction de la file d'attente de tâches doivent migrer vers Cloud Pub/Sub.
Les modules 7 à 9 traitent de la migration des tâches d'envoi, tandis que les modules 18 à 19 sont consacrés à la migration des tâches d'extraction. Bien que Cloud Tasks corresponde plus précisément aux tâches d'envoi de la file d'attente de tâches, Pub/Sub n'est pas aussi proche des tâches d'extraction de la file d'attente de tâches.
Pub/Sub offre plus de fonctionnalités que la fonctionnalité d'extraction fournie par la file d'attente de tâches. Par exemple, Pub/Sub dispose également de la fonctionnalité push, mais Cloud Tasks ressemble davantage aux tâches d'envoi de file d'attente de tâches. La transmission push Pub/Sub n'est donc pas couverte par les modules de migration. Dans cet atelier de programmation du module 19, vous verrez comment faire passer le mécanisme de mise en file d'attente des files d'attente de retrait de la file d'attente de tâches à Pub/Sub, ainsi qu'effectuer la migration d'App Engine NDB vers Cloud NDB pour accéder à Datastore, en répétant la migration du module 2.
Alors que le code du module 18 est "annoncé" en tant qu'application exemple Python 2, la source elle-même est compatible avec Python 2 et 3, et elle le reste même après la migration vers Cloud Pub/Sub (et Cloud NDB) dans le module 19.
Ce tutoriel comprend les étapes suivantes:
- Configuration/Préparation
- Mettre à jour la configuration
- Modifier le code d'application
3. Configuration/Préparation
Cette section explique comment effectuer les opérations suivantes :
- Configurer votre projet Cloud
- Obtenir un exemple d'application de référence
- (Re)Déployer et valider l'application de référence
- Activer de nouveaux services/API Google Cloud
Cette procédure permet de s'assurer que vous commencez avec du code fonctionnel et qu'il est prêt pour la migration vers les services Cloud.
1. Configurer le projet
Si vous avez terminé l'atelier de programmation du module 18, réutilisez ce projet (et ce même code). Vous pouvez également créer un projet ou réutiliser un autre projet existant. Assurez-vous que le projet dispose d'un compte de facturation actif et d'une application App Engine activée. Recherchez l'ID de votre projet, car vous en aurez besoin au cours de cet atelier de programmation. Utilisez-le chaque fois que vous rencontrez la variable PROJECT_ID
.
2. Obtenir un exemple d'application de référence
L'une des conditions préalables est une application App Engine opérationnelle du module 18. Vous devez donc suivre son atelier de programmation (recommandé ; lien ci-dessus) ou copier le code du module 18 à partir du dépôt. Que vous utilisiez la vôtre ou la nôtre, c'est ici que nous allons commencer ("DÉMARRER"). Cet atelier de programmation vous guide tout au long de la migration et se termine par un code ressemblant à celui du dossier du dépôt du module 19 ("FINISH").
- DÉBUT: dossier du module 18 (Python 2)
- FINISH: dossier du module 19 (Python 2 et 3)
- Dépôt complet (pour cloner ou télécharger le fichier ZIP)
Quelle que soit l'application du module 18 que vous utilisez, le dossier doit se présenter comme suit, éventuellement avec un dossier lib
:
$ ls README.md appengine_config.py queue.yaml templates app.yaml main.py requirements.txt
3. (Re)Déployer et valider l'application de référence
Exécutez les étapes suivantes pour déployer l'application du module 18:
- Supprimez le dossier
lib
s'il y en a un, puis exécutezpip install -t lib -r requirements.txt
pour remplir à nouveaulib
. Si Python 2 et 3 sont installés sur votre ordinateur de développement, vous devrez peut-être utiliserpip2
à la place. - Assurez-vous d'avoir installé et initialisé l'outil de ligne de commande
gcloud
, et vérifié son utilisation. - (Facultatif) Définissez votre projet Cloud avec
gcloud config set project
PROJECT_ID
si vous ne souhaitez pas saisirPROJECT_ID
avec chaque commandegcloud
que vous émettez. - Déployer l'exemple d'application avec
gcloud app deploy
- Vérifiez que l'application fonctionne comme prévu sans problème. Si vous avez terminé l'atelier de programmation du module 18, l'application affiche les principaux visiteurs ainsi que les visites les plus récentes (voir ci-dessous). Si ce n'est pas le cas, il est possible qu'il n'y ait pas de nombre de visiteurs à afficher.
Avant de migrer l'application exemple du module 18, vous devez activer les services cloud que l'application modifiée utilisera.
4. Activer de nouveaux services/API Google Cloud
L'ancienne application utilisait des services groupés App Engine qui ne nécessitent pas de configuration supplémentaire, contrairement aux services Cloud autonomes. L'application mise à jour utilisera à la fois Cloud Pub/Sub et Cloud Datastore (via la bibliothèque cliente Cloud NDB). App Engine et les deux API Cloud proposent le niveau "Toujours sans frais" de niveau supérieur, et tant que vous ne dépassez pas ces limites, aucuns frais ne devraient vous être facturés pour suivre ce tutoriel. Vous pouvez activer les API Cloud à partir de la console Cloud ou de la ligne de commande, selon vos préférences.
Depuis Cloud Console
Dans Cloud Console, accédez à la page Bibliothèque du gestionnaire d'API (pour le projet approprié), puis recherchez les API Cloud Datastore et Cloud Pub/Sub à l'aide de la barre de recherche au milieu de la page:
Cliquez sur le bouton Activer pour chaque API séparément. Vous serez peut-être invité à saisir vos informations de facturation. Par exemple, voici la page de la bibliothèque de l'API Cloud Pub/Sub:
Depuis la ligne de commande
Bien qu'elle soit visuellement utile pour activer les API de la console, certaines préfèrent utiliser la ligne de commande. Exécutez la commande gcloud services enable pubsub.googleapis.com datastore.googleapis.com
pour activer les deux API en même temps:
$ gcloud services enable pubsub.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Vous serez peut-être invité à saisir vos informations de facturation. Si vous souhaitez activer d'autres API Cloud et connaître leurs URI, vous les trouverez en bas de la page de la bibliothèque de chaque API. Par exemple, observez pubsub.googleapis.com
comme le "nom du service". au bas de la page Pub/Sub juste au-dessus.
Une fois ces étapes terminées, votre projet pourra accéder aux API. Il est maintenant temps de mettre à jour l'application pour utiliser ces API.
4. Créer les ressources Pub/Sub
Récapitulons l'ordre séquentiel du workflow de la file d'attente de tâches du module 18:
- Le module 18 a utilisé le fichier
queue.yaml
pour créer une file d'attente de retrait nomméepullq
. - L'application ajoute des tâches à la file d'attente de retrait pour suivre les visiteurs.
- Les tâches finissent par être traitées par un nœud de calcul, qui est loué pour une durée limitée (une heure).
- Les tâches sont exécutées en fonction du nombre de visiteurs récents.
- Les tâches sont supprimées de la file d'attente une fois terminées.
Vous allez répliquer un workflow similaire avec Pub/Sub. La section suivante présente la terminologie de base de Pub/Sub, ainsi que trois méthodes différentes pour créer les ressources Pub/Sub nécessaires.
Terminologie liée aux files d'attente de tâches App Engine (pull) et Cloud Pub/Sub
Passer à Pub/Sub nécessite un léger ajustement de votre vocabulaire. Vous trouverez ci-dessous les catégories principales, ainsi que les termes associés aux deux produits. Consultez également le guide de migration, qui propose des comparaisons similaires.
- Mise en file d'attente de la structure des données:avec la file d'attente de tâches, les données sont placées dans des files d'attente de retrait. avec Pub/Sub, les données sont stockées dans des sujets.
- Unités de données en file d'attente : les tâches d'extraction avec Task Queue sont appelées messages avec Pub/Sub.
- Processeurs de données:avec la file d'attente de tâches, les nœuds de calcul accèdent aux tâches d'extraction. avec Pub/Sub, vous avez besoin d'abonnements/abonnés pour recevoir des messages
- Extraction de données : louer une tâche d'extraction revient à extraire un message d'un sujet (via un abonnement).
- Nettoyage/achèvement : supprimer une tâche de file d'attente de tâches d'une file d'attente de retrait lorsque vous avez terminé revient à confirmer la réception d'un message Pub/Sub.
Bien que le produit mis en file d'attente change, le workflow reste relativement similaire:
- Plutôt qu'une file d'attente de retrait, l'application utilise un sujet nommé
pullq
. - Plutôt que d'ajouter des tâches à une file d'attente de retrait, l'application envoie des messages à un sujet (
pullq
). - Plutôt que de louer des tâches de la file d'attente de retrait, un abonné nommé
worker
extrait les messages du sujetpullq
. - L'application traite les charges utiles des messages, en incrémentant le nombre de visiteurs dans Datastore.
- Plutôt que de supprimer des tâches de la file d'attente de retrait, l'application accuse réception des messages traités.
Avec Task Queue, la configuration implique la création d'une file d'attente de retrait. Pour configurer Pub/Sub, vous devez créer un sujet et un abonnement. Dans le module 18, nous avons traité queue.yaml
en dehors de l'exécution de l'application. Nous devons maintenant
faire la même chose avec Pub/Sub.
Trois options s'offrent à vous pour créer des sujets et des abonnements:
- Depuis la console Cloud
- Depuis la ligne de commande, ou
- À partir du code (script Python court)
Choisissez l'une des options ci-dessous et suivez les instructions correspondantes pour créer vos ressources Pub/Sub.
Depuis la console Cloud
Pour créer un sujet à partir de la console Cloud, procédez comme suit:
- Accédez à la page Sujets Pub/Sub de la console Cloud.
- Cliquez sur Créer un sujet en haut de la page. une nouvelle boîte de dialogue s'ouvre (voir l'image ci-dessous).
- Dans le champ ID du sujet, saisissez
pullq
. - Décochez toutes les options cochées, puis sélectionnez Clé de chiffrement gérée par Google.
- Cliquez sur le bouton Créer un sujet.
Voici à quoi ressemble la boîte de dialogue de création de sujet:
Maintenant que vous disposez d'un sujet, vous devez créer un abonnement pour ce sujet:
- Accédez à la page Abonnements Pub/Sub de la console Cloud.
- Cliquez sur Créer un abonnement en haut (voir l'image ci-dessous).
- Saisissez
worker
dans le champ ID d'abonnement. - Choisissez
pullq
dans le menu déroulant Sélectionner un sujet Cloud Pub/Sub et notez son "chemin d'accès complet". Exemple :projects/PROJECT_ID/topics/pullq
- Dans Type de distribution, sélectionnez Extraction.
- Laissez toutes les autres options telles quelles et cliquez sur le bouton Créer.
L'écran de création d'abonnement se présente comme suit:
Vous pouvez également créer un abonnement depuis la page Sujets. Ce "raccourci" peut vous aider à associer des sujets aux abonnements. Pour en savoir plus sur la création d'abonnements, consultez la documentation.
Depuis la ligne de commande
Les utilisateurs Pub/Sub peuvent créer des sujets et des abonnements à l'aide des commandes gcloud pubsub topics create
TOPIC_ID
et gcloud pubsub subscriptions create
SUBSCRIPTION_ID
--topic=
TOPIC_ID
, respectivement. Si vous les exécutez avec une TOPIC_ID
de pullq
et une SUBSCRIPTION_ID
de worker
, vous obtenez le résultat suivant pour le projet PROJECT_ID
:
$ gcloud pubsub topics create pullq Created topic [projects/PROJECT_ID/topics/pullq]. $ gcloud pubsub subscriptions create worker --topic=pullq Created subscription [projects/PROJECT_ID/subscriptions/worker].
Consultez également cette page dans la documentation du guide de démarrage rapide. L'utilisation de la ligne de commande peut simplifier les workflows dans lesquels des sujets et des abonnements sont créés régulièrement. À cette fin, ces commandes peuvent être utilisées dans des scripts shell.
À partir du code (script Python court)
Une autre façon d'automatiser la création de sujets et d'abonnements consiste à utiliser l'API Pub/Sub dans le code source. Vous trouverez ci-dessous le code du script maker.py
dans le dossier du dépôt du module 19.
from __future__ import print_function
import google.auth
from google.api_core import exceptions
from google.cloud import pubsub
_, PROJECT_ID = google.auth.default()
TOPIC = 'pullq'
SBSCR = 'worker'
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)
def make_top():
try:
top = ppc_client.create_topic(name=TOP_PATH)
print('Created topic %r (%s)' % (TOPIC, top.name))
except exceptions.AlreadyExists:
print('Topic %r already exists at %r' % (TOPIC, TOP_PATH))
def make_sub():
try:
sub = psc_client.create_subscription(name=SUB_PATH, topic=TOP_PATH)
print('Subscription created %r (%s)' % (SBSCR, sub.name))
except exceptions.AlreadyExists:
print('Subscription %r already exists at %r' % (SBSCR, SUB_PATH))
try:
psc_client.close()
except AttributeError: # special Py2 handler for grpcio<1.12.0
pass
make_top()
make_sub()
L'exécution de ce script produit le résultat attendu (à condition qu'il n'y ait pas d'erreur):
$ python3 maker.py Created topic 'pullq' (projects/PROJECT_ID/topics/pullq) Subscription created 'worker' (projects/PROJECT_ID/subscriptions/worker)
L'appel de l'API pour créer des ressources existantes génère une exception google.api_core.exceptions.AlreadyExists
générée par la bibliothèque cliente, gérée correctement par le script:
$ python3 maker.py Topic 'pullq' already exists at 'projects/PROJECT_ID/topics/pullq' Subscription 'worker' already exists at 'projects/PROJECT_ID/subscriptions/worker'
Si vous débutez avec Pub/Sub, consultez le livre blanc sur l'architecture Pub/Sub pour obtenir plus d'informations.
5. Mettre à jour la configuration
Les mises à jour de la configuration incluent la modification de différents fichiers de configuration et la création de l'équivalent des files d'attente de retrait App Engine, mais dans l'écosystème Cloud Pub/Sub.
Supprimer le fichier queue.yaml
Comme Pub/Sub n'utilise pas ce fichier, nous allons nous éloigner complètement de la file d'attente de tâches. Par conséquent, supprimez queue.yaml
. Plutôt que de créer une file d'attente de retrait, vous allez créer un sujet Pub/Sub (et un abonnement).
requirements.txt
Ajoutez google-cloud-ndb
et google-cloud-pubsub
à requirements.txt
afin de joindre flask
à partir du module 18. Le fichier requirements.txt
mis à jour du module 19 doit maintenant se présenter comme suit:
flask
google-cloud-ndb
google-cloud-pubsub
Ce fichier requirements.txt
ne comporte aucun numéro de version, ce qui signifie que les dernières versions sont sélectionnées. En cas d'incompatibilité, suivez la pratique standard qui consiste à utiliser des numéros de version pour verrouiller des versions fonctionnelles d'une application.
app.yaml
Les modifications apportées à app.yaml
varient selon que vous utilisez Python 2 ou une mise à niveau vers Python 3.
Python 2
La mise à jour de requirements.txt
ci-dessus ajoute l'utilisation des bibliothèques clientes Google Cloud. Celles-ci nécessitent une prise en charge supplémentaire d'App Engine, à savoir quelques bibliothèques intégrées, setuptools
et grpcio
. L'utilisation des bibliothèques intégrées nécessite une section libraries
dans app.yaml
et les numéros de version des bibliothèques, ou "dernière version". pour connaître les dernières nouveautés
disponibles sur les serveurs App Engine. Le app.yaml
du module 18 ne comporte pas encore l'une de ces sections:
AVANT:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Ajoutez une section libraries
à app.yaml
, ainsi que des entrées pour setuptools
et grpcio
, en sélectionnant leurs dernières versions. Ajoutez également un espace réservé runtime
pour Python 3, commenté avec une version 3.x actuelle (par exemple, 3.10) au moment de la rédaction de ce document. Avec ces modifications, app.yaml
se présente désormais comme suit:
APRÈS:
#runtime: python310
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: setuptools
version: latest
- name: grpcio
version: latest
Python 3
Pour les utilisateurs de Python 3 et de app.yaml
, il s'agit de supprimer des éléments. Dans cette section, vous allez supprimer la section handlers
, les instructions threadsafe
et api_version
, et vous ne créerez pas de section libraries
.
Les environnements d'exécution de deuxième génération ne fournissent pas de bibliothèques tierces intégrées. Par conséquent, une section libraries
n'est pas nécessaire dans app.yaml
. De plus, la copie (parfois appelée "fournisseur" ou "auto-regroupement") non intégrée aux packages tiers n'est plus nécessaire. Il vous suffit de répertorier les bibliothèques tierces utilisées par votre application dans requirements.txt
.
La section handlers
dans app.yaml
permet de spécifier les gestionnaires d'application (script) et de fichiers statiques. Étant donné que l'environnement d'exécution Python 3 nécessite que les frameworks Web effectuent leur propre routage, tous les gestionnaires de scripts doivent être remplacés par auto
. Si votre application (comme celle du module 18) ne diffuse pas de fichiers statiques, toutes les routes sont alors auto
, ce qui les rend non pertinentes. Par conséquent, la section handlers
n'est pas non plus nécessaire. Vous devez donc la supprimer.
Enfin, les instructions threadsafe
et api_version
ne sont pas utilisées dans Python 3. Vous devez donc les supprimer également. En résumé, vous devez supprimer toutes les sections de app.yaml
pour ne conserver que la directive runtime
, en spécifiant une version moderne de Python 3, par exemple 3.10. Voici à quoi ressemble app.yaml
avant et après ces mises à jour:
AVANT:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
APRÈS:
runtime: python310
Pour ceux qui ne souhaitent pas tout supprimer de leur app.yaml
pour Python 3, nous avons fourni un autre fichier app3.yaml
dans le dossier du dépôt du module 19. Si vous souhaitez plutôt l'utiliser pour les déploiements, veillez à ajouter ce nom de fichier à la fin de votre commande: gcloud app deploy app3.yaml
. Dans le cas contraire, votre application sera déployée par défaut avec le fichier app.yaml
Python 2 que vous n'avez pas modifié.
appengine_config.py
Si vous effectuez une mise à niveau vers Python 3, appengine_config.py
n'est pas nécessaire. Supprimez-le. La compatibilité avec les bibliothèques tierces n'est pas nécessaire, car il suffit de les spécifier dans requirements.txt
. Si vous utilisez Python 2, continuez votre lecture.
Le appengine_config.py
du module 18 contient le code approprié pour les bibliothèques tierces, par exemple Flask et les bibliothèques clientes Cloud qui viennent d'être ajoutées à requirements.txt
:
AVANT:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Cependant, ce code seul ne suffit pas pour prendre en charge les bibliothèques intégrées que vous venez d'ajouter (setuptools
, grpcio
). Quelques lignes supplémentaires sont nécessaires. Modifiez appengine_config.py
pour qu'il se présente comme suit:
APRÈS:
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
Pour en savoir plus sur les modifications requises pour prendre en charge les bibliothèques clientes Cloud, consultez la documentation sur la migration de services groupés.
Autres mises à jour de configuration
Si vous avez un dossier lib
, supprimez-le. Si vous utilisez Python 2, réapprovisionnez le dossier lib
en exécutant la commande suivante:
pip install -t lib -r requirements.txt # or pip2
Si Python 2 et 3 sont installés sur votre système de développement, vous devrez peut-être utiliser pip2
au lieu de pip
.
6. Modifier le code d'application
Cette section présente les mises à jour du fichier d'application principal, main.py
, en remplaçant l'utilisation des files d'attente de retrait de la file d'attente des tâches App Engine par Cloud Pub/Sub. Aucune modification n'a été apportée au modèle Web, templates/index.html
. Les deux applications doivent fonctionner de manière identique et afficher les mêmes données.
Mettre à jour les importations et l'initialisation
Plusieurs mises à jour sont disponibles pour les importations et l'initialisation:
- Pour les importations, remplacez App Engine NDB et Task Queue par Cloud NDB et Pub/Sub.
- Renommez
pullq
en remplaçantQUEUE
par un nomTOPIC
. - Avec les tâches d'extraction, le nœud de calcul les a louées pendant une heure, mais avec Pub/Sub, les délais avant expiration sont mesurés pour chaque message. Vous devez donc supprimer la constante
HOUR
. - Les API Cloud nécessitent l'utilisation d'un client API. Vous devez donc les lancer pour Cloud NDB et Cloud Pub/Sub, ce dernier fournissant des clients pour les sujets et les abonnements.
- Pub/Sub nécessite l'ID du projet Cloud. Vous devez donc l'importer et l'obtenir à partir de
google.auth.default()
. - Pub/Sub requiert des "chemins d'accès complets" pour les sujets et les abonnements. Vous devez donc les créer à l'aide des fonctions pratiques
*_path()
.
Vous trouverez ci-dessous les importations et l'initialisation du module 18, ainsi que la façon dont les sections devraient se présenter après la mise en œuvre des modifications ci-dessus. La majeure partie du nouveau code se compose de différentes ressources Pub/Sub:
AVANT:
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb
HOUR = 3600
LIMIT = 10
TASKS = 1000
QNAME = 'pullq'
QUEUE = taskqueue.Queue(QNAME)
app = Flask(__name__)
APRÈS:
from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, pubsub
LIMIT = 10
TASKS = 1000
TOPIC = 'pullq'
SBSCR = 'worker'
app = Flask(__name__)
ds_client = ndb.Client()
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
_, PROJECT_ID = google.auth.default()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)
Accéder aux mises à jour du modèle de données
Le modèle de données Visit
ne change pas. L'accès à Datastore nécessite l'utilisation explicite du gestionnaire de contexte client de l'API Cloud NDB, ds_client.context()
. Dans le code, cela signifie que vous encapsulez les appels Datastore dans store_visit()
et fetch_visits()
dans des blocs Python with
. Cette mise à jour est identique à ce qui est abordé dans le module 2.
La modification la plus pertinente pour Pub/Sub consiste à remplacer la mise en file d'attente d'une tâche d'extraction dans la file d'attente de tâches par la publication d'un message Pub/Sub dans le sujet pullq
. Vous trouverez ci-dessous le code avant et après ces mises à jour:
AVANT:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit in Datastore and queue request to bump visitor count'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
QUEUE.add(taskqueue.Task(payload=remote_addr, method='PULL'))
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
APRÈS:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit in Datastore and queue request to bump visitor count'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
ppc_client.publish(TOP_PATH, remote_addr.encode('utf-8'))
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Mises à jour du modèle de données du nombre de visiteurs
Le modèle de données VisitorCount
ne change pas et effectue fetch_counts()
, sauf pour encapsuler sa requête Datastore dans un bloc with
, comme illustré ci-dessous:
AVANT:
class VisitorCount(ndb.Model):
visitor = ndb.StringProperty(repeated=False, required=True)
counter = ndb.IntegerProperty()
def fetch_counts(limit):
'get top visitors'
return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)
APRÈS:
class VisitorCount(ndb.Model):
visitor = ndb.StringProperty(repeated=False, required=True)
counter = ndb.IntegerProperty()
def fetch_counts(limit):
'get top visitors'
with ds_client.context():
return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)
Mettre à jour le code des nœuds de calcul
Le code du nœud de calcul se met à jour jusqu'au remplacement de la bibliothèque NDB par Cloud NDB et de la file d'attente de tâches avec Pub/Sub, mais son workflow reste le même.
- Encapsuler les appels Datastore dans le bloc
with
du gestionnaire de contexte Cloud NDB - Le nettoyage de la file d'attente de tâches consiste à supprimer toutes les tâches de la file d'attente de retrait. Avec Pub/Sub, les "ID de confirmation" sont collectées dans
acks
, puis supprimées/confirmées à la fin. - Les tâches d'extraction de la file d'attente de tâches sont allouées de la même manière que l'extraction des messages Pub/Sub. Alors que la suppression des tâches d'extraction est effectuée avec les objets de tâche eux-mêmes, les messages Pub/Sub sont supprimés via leurs ID de confirmation.
- Les charges utiles des messages Pub/Sub nécessitent des octets (et non des chaînes Python). Par conséquent, lorsque vous publiez et récupérez des messages dans un sujet, et que vous encodez et décodez UTF-8, respectivement.
Remplacez log_visitors()
par le code mis à jour ci-dessous afin d'implémenter les modifications que vous venez de décrire:
AVANT:
@app.route('/log')
def log_visitors():
'worker processes recent visitor counts and updates them in Datastore'
# tally recent visitor counts from queue then delete those tasks
tallies = {}
tasks = QUEUE.lease_tasks(HOUR, TASKS)
for task in tasks:
visitor = task.payload
tallies[visitor] = tallies.get(visitor, 0) + 1
if tasks:
QUEUE.delete_tasks(tasks)
# increment those counts in Datastore and return
for visitor in tallies:
counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
if not counter:
counter = VisitorCount(visitor=visitor, counter=0)
counter.put()
counter.counter += tallies[visitor]
counter.put()
return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
len(tasks), len(tallies))
APRÈS:
@app.route('/log')
def log_visitors():
'worker processes recent visitor counts and updates them in Datastore'
# tally recent visitor counts from queue then delete those tasks
tallies = {}
acks = set()
rsp = psc_client.pull(subscription=SUB_PATH, max_messages=TASKS)
msgs = rsp.received_messages
for rcvd_msg in msgs:
acks.add(rcvd_msg.ack_id)
visitor = rcvd_msg.message.data.decode('utf-8')
tallies[visitor] = tallies.get(visitor, 0) + 1
if acks:
psc_client.acknowledge(subscription=SUB_PATH, ack_ids=acks)
try:
psc_client.close()
except AttributeError: # special handler for grpcio<1.12.0
pass
# increment those counts in Datastore and return
if tallies:
with ds_client.context():
for visitor in tallies:
counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
if not counter:
counter = VisitorCount(visitor=visitor, counter=0)
counter.put()
counter.counter += tallies[visitor]
counter.put()
return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
len(msgs), len(tallies))
Aucune modification n'a été apportée au gestionnaire d'application principal root()
. Aucune modification n'est nécessaire non plus dans le fichier de modèle HTML, templates/index.html
. Toutes les mises à jour nécessaires sont ainsi incluses. Félicitations, vous avez ouvert votre nouvelle application du module 19 à l'aide de Cloud Pub/Sub !
7. Résumé/Nettoyage
Déployez votre application pour vérifier qu'elle fonctionne comme prévu et dans toutes les sorties renvoyées. Exécutez également le worker pour traiter le nombre de visiteurs. Après la validation de l'application, effectuez toutes les étapes de nettoyage et réfléchissez aux prochaines étapes.
Déployer et vérifier l'application
Assurez-vous d'avoir déjà créé le sujet pullq
et l'abonnement worker
. Si c'est le cas et que votre application exemple est prête à l'emploi, déployez-la avec gcloud app deploy
. Le résultat doit être identique à celui de l'application du module 18, à la différence que vous avez correctement remplacé l'intégralité du mécanisme de mise en file d'attente sous-jacent:
L'interface Web de l'application vérifie maintenant que cette partie de l'application fonctionne. Bien que cette partie de l'application interroge et affiche les principaux visiteurs et les visites les plus récentes, n'oubliez pas que l'application enregistre cette visite et crée une tâche d'extraction pour ajouter ce visiteur au décompte total. Cette tâche se trouve maintenant dans la file d'attente en attente de traitement.
Vous pouvez l'exécuter avec un service de backend App Engine, une tâche cron
, en accédant à /log
ou en émettant une requête HTTP de ligne de commande. Voici un exemple d'exécution qui échappe à l'appel du code de nœud de calcul avec curl
(remplacez PROJECT_ID
):
$ curl https://PROJECT_ID.appspot.com/log DONE (with 1 task[s] logging 1 visitor[s])
Le nouveau décompte sera ensuite reflété lors de la prochaine visite du site Web. Et voilà !
Effectuer un nettoyage
Général
Si vous avez terminé, nous vous recommandons de désactiver votre application App Engine afin d'éviter que des frais ne vous soient facturés. Toutefois, si vous souhaitez effectuer d'autres tests, la plate-forme App Engine dispose d'un quota sans frais. Tant que vous ne dépassez pas ce niveau d'utilisation, aucuns frais ne vous seront facturés. Cela concerne le calcul, mais des frais peuvent également s'appliquer pour les services App Engine concernés. Pour en savoir plus, consultez sa page des tarifs. Si cette migration implique d'autres services Cloud, ceux-ci sont facturés séparément. Dans les deux cas, le cas échéant, consultez la section "Informations spécifiques à cet atelier de programmation" ci-dessous.
Afin d'informer l'ensemble des utilisateurs, le déploiement sur une plate-forme de calcul sans serveur Google Cloud comme App Engine entraîne des coûts minimes de compilation et de stockage. Cloud Build et Cloud Storage disposent de leur propre quota sans frais. Le stockage de cette image utilise une partie de ce quota. Cependant, vous pouvez résider dans une région qui n'offre pas ce type de version sans frais. Vous devez donc surveiller l'utilisation de votre espace de stockage afin de réduire les coûts potentiels. "Dossiers" Cloud Storage spécifiques vous devez examiner:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
- Les liens de stockage ci-dessus dépendent de votre
PROJECT_ID
et de votre *LOC
*ation (par exemple, "us
") si votre application est hébergée aux États-Unis.
En revanche, si vous ne comptez pas utiliser cette application ou d'autres ateliers de programmation liés à la migration, et que vous souhaitez tout supprimer complètement, arrêtez votre projet.
Spécifique à cet atelier de programmation
Les services listés ci-dessous sont propres à cet atelier de programmation. Pour en savoir plus, consultez la documentation de chaque produit:
- Différents composants de Cloud Pub/Sub disposent d'une version sans frais. déterminez votre utilisation globale pour avoir une meilleure idée des implications en termes de coûts et consultez sa page de tarification pour en savoir plus.
- Le service App Engine Datastore est fourni par Cloud Datastore (Cloud Firestore en mode Datastore), également disponible avec une version sans frais. consultez la page des tarifs pour en savoir plus.
Étapes suivantes
Au-delà de ce tutoriel, d'autres modules de migration à envisager concernant l'abandon des anciens services groupés sont les suivants:
- Module 2: Migrer de l'environnement
ndb
App Engine vers Cloud NDB - Modules 7 à 9: migration de la file d'attente des tâches App Engine (tâches d'envoi) vers Cloud Tasks
- Modules 12 à 13: Migrer de Memcache d'App Engine vers Cloud Memorystore
- Modules 15 à 16: effectuer la migration d'un paquet d'application App Engine vers Cloud Storage
App Engine n'est plus la seule plate-forme sans serveur de Google Cloud. Si vous disposez d'une petite application App Engine ou d'une application aux fonctionnalités limitées et que vous souhaitez la transformer en microservice autonome, ou si vous voulez diviser une application monolithique en plusieurs composants réutilisables, nous vous recommandons de passer à Cloud Functions. Si la conteneurisation fait désormais partie de votre workflow de développement d'applications, en particulier si elle consiste en un pipeline CI/CD (intégration continue/livraison continue ou déploiement), envisagez de migrer vers Cloud Run. Ces scénarios sont abordés dans les modules suivants:
- Effectuer une migration d'App Engine vers Cloud Functions: consultez le Module 11
- Effectuer une migration d'App Engine vers Cloud Run: consultez le module 4 pour conteneuriser votre application avec Docker, ou le module 5 pour effectuer cette opération sans conteneur, ni connaissance de Docker ou
Dockerfile
.
Le passage à une autre plate-forme sans serveur est facultatif. Nous vous recommandons de réfléchir aux meilleures options pour vos applications et cas d'utilisation avant d'apporter des modifications.
Quel que soit le module de migration que vous envisagez ensuite, tout le contenu de la station de migration sans serveur (ateliers de programmation, vidéos, code source [si disponible]) est accessible dans son dépôt Open Source. Le fichier README
du dépôt fournit également des indications sur les migrations à prendre en compte et sur l'ordre d'exécution approprié. des modules de migration.
8. Ressources supplémentaires
Vous trouverez ci-dessous des ressources supplémentaires destinées aux développeurs qui étudient plus en détail ce module de migration ou le module de migration associé, ainsi que les produits associés. Vous y trouverez, par exemple, des emplacements où vous pouvez envoyer des commentaires sur ce contenu, des liens vers le code et diverses documents susceptibles de vous être utiles.
Commentaires et problèmes concernant les ateliers de programmation
Si vous rencontrez des problèmes avec cet atelier de programmation, commencez par faire une recherche avant de les signaler. Liens vers la recherche et la création d'un signalement :
Ressources de migration
Le tableau ci-dessous contient des liens vers les dossiers de dépôt des modules 18 (START) et 19 (FINISH).
Atelier de programmation | Python 2 | Python 3 |
(n/a) | ||
Module 19 (cet atelier de programmation) | (Identique à Python 2, mais utilisez app3.yaml, sauf si vous avez mis à jour app.yaml comme indiqué ci-dessus.) |
Références en ligne
Vous trouverez ci-dessous des ressources pertinentes pour ce tutoriel:
File d'attente de tâches d'App Engine
- Présentation des files d'attente de tâches App Engine
- Présentation des files d'attente de retrait de la file d'attente de tâches App Engine
- Application exemple complète d'application de file d'attente de retrait pour les files d'attente de retrait App Engine
- Créer des files d'attente de retrait dans une file d'attente de tâches
- Vidéo de lancement de la file d'attente de retrait Google I/O 2011 ( application exemple Votelator)
- Documentation de référence sur
queue.yaml
queue.yaml
et Cloud Tasks- Guide de migration des files d'attente de retrait vers Pub/Sub
Cloud Pub/Sub
- Page du produit Cloud Pub/Sub
- Utiliser les bibliothèques clientes Pub/Sub
- Exemples de la bibliothèque cliente Python Pub/Sub
- Documentation sur la bibliothèque cliente Python Pub/Sub
- Créer et gérer les sujets Pub/Sub
- Consignes relatives aux noms des sujets Pub/Sub
- Créer et gérer les abonnements Pub/Sub
- Exemple d'application App Engine (flexible) (déployable également vers l'environnement standard ; Python 3)
- Dépôt de l'application exemple ci-dessus
- Abonnements pull Pub/Sub
- Abonnements push Pub/Sub
- Exemple d'application push App Engine pour Pub/Sub (Python 3)
- Dépôt d'un exemple d'application Pub/Sub pour App Engine
- Informations tarifaires Pub/Sub
- Cloud Tasks ou Cloud Pub/Sub ? (push vs pull)
App Engine NDB et Cloud NDB (Datastore)
- Documentation App Engine NDB
- Dépôt App Engine NDB
- Documentation Google Cloud NDB
- Dépôt Google Cloud NDB
- Informations tarifaires concernant Cloud Datastore
Plate-forme App Engine
- Documentation App Engine
- Environnement d'exécution App Engine (environnement standard) Python 2
- Utiliser les bibliothèques intégrées d'App Engine dans la version Python 2 d'App Engine
- Environnement d'exécution App Engine (environnement standard) Python 3
- Différences entre Python 2 et Trois environnements d'exécution App Engine (environnement standard)
- Guide de migration App Engine (environnement standard) pour Python 2 vers 3
- Informations sur les tarifs et les quotas d'App Engine
- Lancement de la plate-forme App Engine de deuxième génération (2018)
- Comparaison entre les première et plates-formes de deuxième génération
- Compatibilité à long terme avec les anciens environnements d'exécution
- Exemples de migration de la documentation
- Exemples de migrations via des contributions de la communauté
Autres informations sur le cloud
- Python sur Google Cloud Platform
- Bibliothèques clientes Google Cloud Python
- "Toujours sans frais" de Google Cloud niveau
- SDK Google Cloud (outil de ligne de commande
gcloud
) - Toute la documentation Google Cloud
Vidéos
- Station de migration sans serveur
- Expéditions sans serveur
- S'abonner à Google Cloud Tech
- S'abonner à Google Developers
Licence
Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.