1. Descripción general
La serie de codelabs Serverless Migration Station (instructivos prácticos y autoaprendizaje) y los videos relacionados tienen como objetivo ayudar a los desarrolladores de Google Cloud sin servidores a modernizar sus apps guiándolos a través de una o más migraciones, en especial al alejarse de los servicios heredados. De esta manera, tus apps serán más portátiles, y tendrás más opciones y flexibilidad, lo que te permitirá integrarlas con una variedad más amplia de productos de Cloud y acceder a ella, y actualizar con mayor facilidad a versiones de idiomas más recientes. Aunque inicialmente se enfoca en los primeros usuarios de Cloud, principalmente los desarrolladores de App Engine (entorno estándar), esta serie es lo suficientemente amplia como para incluir otras plataformas sin servidores como Cloud Functions y Cloud Run, o cualquier otra, si corresponde.
En este codelab, aprenderás a usar las tareas push de la lista de tareas en cola de App Engine en la app de ejemplo del codelab del módulo 1. La entrada de blog y el video del módulo 7 complementan este instructivo, ya que proporcionan una breve descripción general del contenido de este instructivo.
En este módulo, agregaremos el uso de tareas push y, luego, migraremos ese uso a Cloud Tasks en el Módulo 8 y, luego, a Python 3 y Cloud Datastore en el Módulo 9. Aquellos que usen listas de tareas en cola para tareas de extracción migrarán a Cloud Pub/Sub y, en su lugar, deberán consultar los módulos 18-19.
En un próximo lab,
- Usa la API o el servicio empaquetado de la lista de tareas en cola de App Engine
- Agrega el uso de tareas de envío a una app básica de Flask en App Engine NDB de Python 2.
Requisitos
- Un proyecto de Google Cloud con una cuenta de facturación de GCP activa
- Habilidades básicas de Python
- Conocimiento práctico de los comandos comunes de Linux
- Conocimientos básicos sobre el desarrollo y la implementación de aplicaciones de App Engine
- Una app de App Engine del Módulo 1 que funcione (completa su codelab [recomendado] o copia la app del repositorio)
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia en Python?
¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?
2. Información general
La lista de tareas en cola de App Engine admite tareas de envío y extracción. Para mejorar la portabilidad de la aplicación, el equipo de Google Cloud recomienda migrar de servicios en paquetes heredados, como la lista de tareas en cola, a otros servicios independientes o equivalentes de terceros de Cloud.
- Los usuarios de la tarea push de la lista de tareas en cola deben migrar a Cloud Tasks.
- Los usuarios de la tarea de extracción de la lista de tareas en cola deben migrar a Cloud Pub/Sub.
La migración de tareas de extracción se aborda en los módulos 18 a 19 de migración, mientras que los módulos 7 a 9 se enfocan en la migración de tareas de envío. Para migrar desde tareas push de lista de tareas en cola de App Engine, agrega su uso a la app existente de Flask y App Engine NBS que resulta del codelab del módulo 1. En esa aplicación, una nueva vista de página registra una nueva visita y muestra las visitas más recientes del usuario. Dado que las visitas anteriores nunca se vuelven a mostrar y ocupan espacio en Datastore, crearemos una tarea de envío para borrar automáticamente las visitas más antiguas. Más adelante, en el módulo 8, migraremos la app de la lista de tareas en cola a Cloud Tasks.
En este instructivo, se muestran los siguientes pasos:
- Configurar/trabajo previo
- Actualizar configuración
- Modifica el código de la aplicación
3. Configurar/trabajo previo
Esta sección explica cómo:
- Configura el proyecto de Cloud
- Obtén app de ejemplo del modelo de referencia
- (Re)Implementa y valida la app de referencia
Con estos pasos, te aseguras de comenzar a trabajar con código.
1. Configura el proyecto
Si completaste el codelab del módulo 1, te recomendamos que vuelvas a usar ese mismo proyecto (y código). Como alternativa, puedes crear un proyecto completamente nuevo o reutilizar otro proyecto existente. Asegúrate de que el proyecto tenga una cuenta de facturación activa y App Engine esté habilitado.
2. Obtén app de ejemplo del modelo de referencia
Uno de los requisitos previos de este codelab es tener una app de App Engine del módulo 1 que funcione. Completa el codelab del módulo 1 (recomendado) o copia la app del módulo 1 del repositorio. Ya sea que uses el tuyo o el nuestro, comenzaremos en el código del módulo 1. En este codelab, se explica cada paso y se concluye con un código similar al que se encuentra en la carpeta del repositorio del módulo 7 “FINISH”.
- INICIO: Carpeta del módulo 1 (Python 2)
- FIN: Carpeta del módulo 7 (Python 2)
- Repositorio completo (para clonar o descargar un archivo ZIP)
Independientemente de la app del Módulo 1 que uses, la carpeta debería tener el siguiente aspecto, posiblemente con una carpeta lib
:
$ ls README.md main.py templates app.yaml requirements.txt
3. (vuelve a) implementa la aplicación de modelo de referencia
Ejecuta los siguientes pasos para (volver a) implementar la app del Módulo 1:
- Borra la carpeta
lib
si hay una y ejecutapip install -t lib -r requirements.txt
para volver a propagarlib
. Es posible que debas usar el comandopip2
en su lugar si tienes instalados Python 2 y 3. - Asegúrate de haber instalado e inicializado la herramienta de línea de comandos de
gcloud
y de haber revisado su uso. - Configura tu proyecto de Cloud con
gcloud config set project
PROJECT_ID
si no quieres ingresar tuPROJECT_ID
con cada comandogcloud
emitido. - Implementa la app de ejemplo con
gcloud app deploy
- Confirma que la app del Módulo 1 se ejecute como se espera sin problemas y muestre las visitas más recientes (como se ilustra a continuación).
4. Actualizar configuración
No es necesario realizar cambios en los archivos de configuración estándar de App Engine (app.yaml
, requirements.txt
, appengine_config.py
).
5. Modifica archivos de la aplicación
El archivo principal de la aplicación es main.py
, y todas las actualizaciones de esta sección pertenecen a ese archivo. También hay una pequeña actualización en la plantilla web, templates/index.html
. Estos son los cambios que se implementarán en esta sección:
- Actualizar importaciones
- Agregar tarea de envío
- Agregar controlador de tareas
- Actualizar plantilla web
1. Actualizar importaciones
Una importación de google.appengine.api.taskqueue
incorpora la funcionalidad de lista de tareas en cola. También se requieren algunos paquetes de la biblioteca estándar de Python:
- Dado que agregaremos una tarea para borrar las visitas más antiguas, la app deberá procesar las marcas de tiempo, es decir, el uso de
time
ydatetime
. - Para registrar información útil sobre la ejecución de la tarea, necesitamos
logging
.
Si agregas todas estas importaciones, verás a continuación el aspecto que tendrá tu código antes y después de estos cambios:
ANTES:
from flask import Flask, render_template, request
from google.appengine.ext import ndb
DESPUÉS:
from datetime import datetime
import logging
import time
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb
2. Agregar tarea de envío (intercalar datos para la tarea, poner en cola una tarea nueva)
La documentación de la lista de aplicaciones en cola indica lo siguiente: "Para procesar una tarea, debes agregarla a una lista de aplicaciones en cola. App Engine proporciona una lista de aplicaciones en cola predeterminada, llamada default
, que está configurada y lista para usar con la configuración predeterminada. Si lo deseas, puedes agregar todas tus tareas a la cola predeterminada, sin tener que crear ni configurar otras colas”. En este codelab, se usa la cola default
para abreviar. Para obtener más información sobre cómo definir tus propias listas de aplicaciones en cola, con características iguales o diferentes, consulta la documentación sobre cómo crear listas de aplicaciones en cola.
El objetivo principal de este codelab es agregar una tarea (a la lista de aplicaciones en cola default
) cuyo trabajo es borrar las visitas anteriores de Datastore que ya no se muestran. La app de referencia registra cada visita (solicitud de GET
a /
) mediante la creación de una nueva entidad Visit
y, luego, recupera y muestra las visitas más recientes. No se volverá a mostrar ni se usará ninguna de las visitas más antiguas, por lo que la tarea push borra todas las visitas anteriores a la más antigua. Para lograrlo, el comportamiento de la app debe cambiar un poco:
- Cuando consultes las visitas más recientes, en lugar de mostrarlas de inmediato, modifica la app para guardar la marca de tiempo de la última
Visit
, la más antigua que se muestra. Es seguro borrar todas las visitas anteriores a esta. - Crea una tarea de envío con esta marca de tiempo como carga útil y dirígela al controlador de tareas, accesible a través de un
POST
HTTP a/trim
. Específicamente, usa las utilidades estándar de Python para convertir la marca de tiempo de Datastore y enviarla (como un número de punto flotante) a la tarea, pero también registrarla (como una cadena) y mostrar esa cadena como un valor centinela para mostrar al usuario.
Todo esto se lleva a cabo en fetch_visits()
, y así se verá antes y después de realizar las actualizaciones:
ANTES:
def fetch_visits(limit):
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch(limit))
DESPUÉS:
def fetch_visits(limit):
'get most recent visits and add task to delete older visits'
data = Visit.query().order(-Visit.timestamp).fetch(limit)
oldest = time.mktime(data[-1].timestamp.timetuple())
oldest_str = time.ctime(oldest)
logging.info('Delete entities older than %s' % oldest_str)
taskqueue.add(url='/trim', params={'oldest': oldest})
return (v.to_dict() for v in data), oldest_str
3. Agrega un controlador de tareas (código que se llama cuando se ejecuta la tarea)
Si bien la eliminación de las visitas anteriores se podría haber realizado con facilidad en fetch_visits()
, ten en cuenta que esta función no tiene mucho que ver con el usuario final. Es una funcionalidad auxiliar y una buena opción para procesar de forma asíncrona fuera de las solicitudes estándar de la app. El usuario final aprovechará el beneficio de realizar consultas más rápidas, ya que habrá menos información en Datastore. Crea una nueva función trim()
, llamada a través de una solicitud POST
de la lista de tareas en cola a /trim
, que hace lo siguiente:
- Extrae la "visita más antigua" carga útil de marca de tiempo
- Emite una consulta de Datastore para encontrar todas las entidades anteriores a esa marca de tiempo.
- Opta por una opción más rápida de "solo claves" porque no se necesitan datos reales del usuario.
- Registra la cantidad de entidades que se borrarán (incluido cero).
- Llama a
ndb.delete_multi()
para borrar cualquier entidad (se omite si no se puede). - Muestra una cadena vacía (junto con un código de retorno HTTP 200 implícito).
Puedes ver todo esto en trim()
a continuación. Agrégala a main.py
justo después de fetch_visits()
:
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = request.form.get('oldest', type=float)
keys = Visit.query(
Visit.timestamp < datetime.fromtimestamp(oldest)
).fetch(keys_only=True)
nkeys = len(keys)
if nkeys:
logging.info('Deleting %d entities: %s' % (
nkeys, ', '.join(str(k.id()) for k in keys)))
ndb.delete_multi(keys)
else:
logging.info('No entities older than: %s' % time.ctime(oldest))
return '' # need to return SOME string w/200
4. Actualizar plantilla web
Actualiza la plantilla web, templates/index.html
, con este condicional de Jinja2 para mostrar la marca de tiempo más antigua si existe esa variable:
{% if oldest is defined %}
<b>Deleting visits older than:</b> {{ oldest }}</p>
{% endif %}
Agrega este fragmento después de la lista de visitas que se muestra, pero antes de cerrar el cuerpo, para que tu plantilla se vea así:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
{% if oldest is defined %}
<b>Deleting visits older than:</b> {{ oldest }}</p>
{% endif %}
</body>
</html>
6. Resumen/limpieza
En esta sección, se finaliza este codelab implementando la app y verificando que funcione según lo previsto y en cualquier resultado reflejado. Después de validar la app, realiza una limpieza y considera los pasos siguientes.
Implementa y verifica la aplicación
Implementa la app con gcloud app deploy
. El resultado debería ser idéntico al de la app del Módulo 1, excepto por una línea nueva en la parte inferior que muestra qué visitas se borrarán:
Felicitaciones por completar el codelab. Tu código ahora debería coincidir con el que hay en la carpeta del repositorio del módulo 7. Ya está todo listo para migrar a Cloud Tasks en el módulo 8.
Limpia
General
Si ya terminaste, te recomendamos que inhabilites la aplicación de App Engine para evitar que se te facture. Sin embargo, si deseas probar o experimentar un poco más, la plataforma de App Engine tiene una cuota gratuita y, siempre y cuando no superes ese nivel de uso, no se te debería cobrar. Eso es para procesamiento, pero es posible que también se apliquen cargos por servicios relevantes de App Engine, así que consulta la página de precios para obtener más información. Si esta migración implica otros servicios de Cloud, estos se facturan por separado. En ambos casos, si corresponde, consulta la sección "Específico de este codelab" a continuación.
Para una divulgación completa, la implementación en una plataforma de procesamiento sin servidores de Google Cloud, como App Engine, genera costos menores de compilación y almacenamiento. Cloud Build tiene su propia cuota gratuita, al igual que Cloud Storage. El almacenamiento de esa imagen ocupa parte de esa cuota. Sin embargo, es posible que vivas en una región que no cuenta con ese nivel gratuito, así que ten en cuenta el uso que haces del almacenamiento para minimizar posibles costos. “Carpetas” específicas de Cloud Storage que debes revisar incluyen
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
- Los vínculos de almacenamiento anteriores dependen de tu
PROJECT_ID
y *LOC
*; por ejemplo, "us
" si tu app está alojada en EE.UU.
Por otro lado, si no vas a continuar con esta aplicación o algún otro codelab de migración relacionado y quieres borrar todo por completo, cierra tu proyecto.
Información específica de este codelab
Los servicios que se indican a continuación son exclusivos de este codelab. Consulta la documentación de cada producto para obtener más información:
- De acuerdo con la página de precios de servicios en paquetes heredados, como la lista de tareas en cola, el servicio de lista de tareas en cola de App Engine no genera facturación adicional.
- El servicio de App Engine Datastore lo proporciona Cloud Datastore (Cloud Firestore en modo Datastore), que también tiene un nivel gratuito. consulta su página de precios para obtener más información.
Próximos pasos
En esta "migración", agregaste el uso de la lista de aplicaciones en cola de la lista de tareas en cola a la app de ejemplo del Módulo 1, lo que agregó compatibilidad con el seguimiento de visitantes, lo que generó la app de ejemplo del Módulo 7. En la próxima migración, aprenderás a actualizar desde las tareas de envío de App Engine a Cloud Tasks, en caso de que decidas hacerlo. A partir del otoño de 2021, los usuarios ya no tendrán que migrar a Cloud Tasks cuando actualicen a Python 3. Obtén más información sobre este tema en la siguiente sección.
Si sí quieres pasar a Cloud Tasks, a continuación, encontrarás el codelab del módulo 8. Además de eso, hay migraciones adicionales que se deben considerar, como Cloud Datastore, Cloud Memorystore, Cloud Storage o Cloud Pub/Sub (listas de extracción). También hay migraciones de productos cruzados a Cloud Run y Cloud Functions. Se puede acceder a todo el contenido de Serverless Migration Station (codelabs, videos, código fuente [si está disponible]) a través de su repositorio de código abierto.
7. Migración a Python 3
En otoño de 2021, el equipo de App Engine amplió la compatibilidad de muchos de los servicios en paquete a entornos de ejecución de 2a generación (que originalmente estaban disponibles solo en los entornos de ejecución de 1a generación), lo que significa que ya no es necesario migrar de servicios agrupados, como la lista de tareas en cola de App Engine, a Cloud independiente o a equivalentes de terceros, como Cloud Tasks, cuando migras tu app a Python 3. En otras palabras, puedes seguir usando la lista de tareas en cola en las aplicaciones de Python 3 de App Engine, siempre y cuando actualices el código para acceder a servicios en paquetes desde entornos de ejecución de nueva generación.
Puedes obtener más información para migrar el uso de servicios en paquetes a Python 3 en el codelab del módulo 17 y el video correspondiente. Si bien ese tema está fuera del alcance del módulo 7, en los vínculos que aparecen a continuación, encontrarás versiones de Python 3 de las apps del módulo 1 y 7 transferidas a Python 3, y aún usan App Engine NBS y Task Queue.
8. Recursos adicionales
A continuación, se incluyen recursos adicionales para los desarrolladores que exploran este módulo o uno relacionado, así como productos relacionados. Esto incluye lugares donde enviar comentarios sobre este contenido, vínculos al código y varios documentos que pueden resultarte útiles.
Problemas o comentarios sobre el codelab
Si encuentras algún problema con este Codelab, primero busca el problema antes de enviarlo. Vínculos para buscar y crear problemas nuevos:
Recursos de migración
En la siguiente tabla, encontrarás los vínculos a las carpetas de repositorio del Módulo 2 (COMENZAR) y Módulo 7 (FINALIZAR).
Codelab | Python 2 | Python 3 |
code (no se incluye en este instructivo) | ||
Módulo 7 (este codelab) | code (no se incluye en este instructivo) |
Recursos en línea
A continuación, hay recursos en línea que pueden ser relevantes para este tutorial:
Lista de tareas en cola de App Engine
- Descripción general de la lista de tareas en cola de App Engine
- Descripción general de las listas de aplicaciones en cola de la lista de tareas en cola de App Engine
- Crea listas de aplicaciones en cola de listas de tareas en cola
- Referencia de
queue.yaml
queue.yaml
vs. Cloud Tasks- Guía de migración de listas de aplicaciones en cola a Cloud Tasks
- Ejemplo de documentación de las listas de aplicaciones en cola de la lista de tareas en cola de App Engine en Cloud Tasks
Plataforma de App Engine
- Documentación de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 2
- Usa las bibliotecas integradas de App Engine en Python 2 de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 3
- Diferencias entre Python 2 y 3 entornos de ejecución de App Engine (entorno estándar)
- Guía de migración de Python 2 a 3 de App Engine (entorno estándar)
- Información de precios y cuotas de App Engine
- Lanzamiento de la plataforma de App Engine de segunda generación (2018)
- Comparación primero y plataformas de segunda generación
- Asistencia a largo plazo para entornos de ejecución heredados
- Ejemplos de migración de documentación
- Ejemplos de migración aportados por la comunidad
Otra información de Cloud
- Python en Google Cloud Platform
- Bibliotecas cliente de Python de Google Cloud
- Google Cloud “Siempre gratuito” nivel
- SDK de Google Cloud (herramienta de línea de comandos de
gcloud
) - Toda la documentación de Google Cloud
Videos
- Estación de migración sin servidores
- Expediciones sin servidores
- Suscríbete a Google Cloud Tech
- Suscríbete a Google Developers.
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.