1. Обзор
Серия обучающих материалов Serverless Migration Station (самостоятельные практические уроки) и сопутствующих видеороликов призвана помочь разработчикам бессерверных приложений Google Cloud модернизировать свои приложения, проведя их через одну или несколько миграций, в первую очередь, через отказ от устаревших сервисов. Это делает ваши приложения более портативными, предоставляет больше возможностей и гибкости, позволяя интегрироваться с более широким спектром облачных продуктов и получать к ним доступ, а также упрощает обновление до более новых версий языков программирования. Хотя изначально серия ориентирована на самых первых пользователей облачных сервисов, в первую очередь разработчиков App Engine (стандартная среда), она достаточно широка, чтобы охватить и другие бессерверные платформы, такие как Cloud Functions и Cloud Run , или другие, если это применимо.
В этом практическом занятии вы узнаете, как использовать задачи с функцией push в очереди задач App Engine в примере приложения из практического занятия по модулю 1. Статья в блоге и видеоматериалы модуля 7 дополняют это руководство, предоставляя краткий обзор его содержания.
В этом модуле мы добавим использование задач с отправкой (push tasks), затем перенесем это использование в Cloud Tasks в модуле 8, а позже — в Python 3 и Cloud Datastore в модуле 9. Те, кто использует очереди задач (Task Queues) для задач с получением данных ( pull tasks), должны перейти на Cloud Pub/Sub и обратиться к модулям 18-19.
Вы узнаете, как
- Используйте API/встроенный сервис очереди задач App Engine.
- Добавьте использование push-уведомлений в базовое приложение Python 2 Flask App Engine NDB.
Что вам понадобится
- Проект Google Cloud с активным платежным аккаунтом GCP.
- Базовые навыки работы с Python.
- Практические навыки работы с распространенными командами Linux.
- Базовые знания разработки и развертывания приложений на платформе App Engine.
- Рабочее приложение App Engine из модуля 1 (пройдите соответствующий практический урок [рекомендуется] или скопируйте приложение из репозитория).
Опрос
Как вы будете использовать этот учебный материал?
Как бы вы оценили свой опыт работы с Python?
Как бы вы оценили свой опыт использования сервисов Google Cloud?
2. Предыстория
Очередь задач App Engine поддерживает как задачи с отправкой (push), так и задачи с получением (pull). Для повышения переносимости приложений команда Google Cloud рекомендует перейти с устаревших встроенных сервисов, таких как очередь задач, на другие автономные облачные сервисы или аналогичные сервисы сторонних разработчиков.
- Пользователям, использующим функцию отправки задач в очередь, следует перейти на Cloud Tasks .
- Пользователям, использующим функцию извлечения задач из очереди, следует перейти на Cloud Pub/Sub .
Миграция задач с помощью pull рассматривается в модулях миграции 18-19, а модули 7-9 посвящены миграции задач с помощью push-запросов. Для миграции с задач с push-запросами очереди задач App Engine добавьте их использование в существующее приложение Flask и App Engine NDB, созданное в результате выполнения практического задания в модуле 1. В этом приложении новая страница регистрации посещений отображает пользователю самые последние посещения. Поскольку более старые посещения больше никогда не отображаются и занимают место в Datastore, мы создадим задачу с push-запросом для автоматического удаления самых старых посещений. Далее в модуле 8 мы перенесем это приложение с очереди задач на облачные задачи.
В этом руководстве описаны следующие шаги:
- Подготовка/Настройка
- Обновить конфигурацию
- Измените код приложения
3. Подготовка/Предварительные работы
В этом разделе объясняется, как:
- Настройте свой облачный проект
- Получите базовый образец приложения
- (Повторное) развертывание и проверка базового приложения.
Эти шаги гарантируют, что вы начнете работу с работоспособным кодом.
1. Настройка проекта
Если вы завершили практическое занятие по модулю 1 , мы рекомендуем использовать тот же проект (и код). В качестве альтернативы вы можете создать совершенно новый проект или использовать другой существующий проект. Убедитесь, что у проекта есть активный платежный аккаунт и включен App Engine.
2. Получите базовый образец приложения.
Одно из предварительных условий для этого практического занятия — наличие работающего приложения App Engine из Модуля 1: выполните практическое занятие по Модулю 1 (рекомендуется) или скопируйте приложение Модуля 1 из репозитория. Независимо от того, используете ли вы свой или наш код, мы начнём именно с кода Модуля 1. Это практическое занятие шаг за шагом проведёт вас через каждый этап, завершившись кодом, похожим на тот, что находится в папке «FINISH» репозитория Модуля 7.
- НАЧАЛО: Папка «Модуль 1» (Python 2)
- ЗАВЕРШЕНИЕ: Папка модуля 7 (Python 2)
- Весь репозиторий (для клонирования или загрузки ZIP-файла )
Независимо от того, какое приложение из Модуля 1 вы используете, папка должна выглядеть примерно так, как показано ниже, возможно, с дополнительной папкой lib :
$ ls README.md main.py templates app.yaml requirements.txt
3. (Повторное) развертывание базового приложения
Выполните следующие шаги для (повторного) развертывания приложения Модуля 1:
- Удалите папку
lib, если она есть, и выполните команду:pip install -t lib -r requirements.txt, чтобы заново заполнитьlib. Возможно, вам потребуется использовать командуpip2, если у вас установлены Python 2 и 3. - Убедитесь, что вы установили и инициализировали инструмент командной строки
gcloudи ознакомились с его использованием. - Укажите свой облачный проект с помощью
gcloud config set projectPROJECT_ID, если вы не хотите вводить свойPROJECT_IDпри каждой командеgcloud. - Разверните демонстрационное приложение с помощью
gcloud app deploy - Убедитесь, что приложение «Модуль 1» работает должным образом и без проблем отображает последние посещения (иллюстрация ниже).

4. Обновите конфигурацию
Никаких изменений в стандартных конфигурационных файлах App Engine ( app.yaml , requirements.txt , appengine_config.py ) не требуется.
5. Измените файлы приложения.
Основной файл приложения — main.py , и все обновления в этом разделе относятся именно к этому файлу. Также внесены незначительные изменения в веб-шаблон, templates/index.html . Вот изменения, которые необходимо внести в этом разделе:
- Обновить импорты
- Добавить задачу push
- Добавить обработчик задач
- Обновить веб-шаблон
1. Обновите импорт.
Импорт google.appengine.api.taskqueue обеспечивает функциональность очереди задач. Также требуются некоторые пакеты стандартной библиотеки Python:
- Поскольку мы добавляем задачу по удалению самых старых посещений, приложению потребуется работать с временными метками, то есть использовать форматы
timeиdatetime. - Для регистрации полезной информации о выполнении задач нам необходима
logging.
После добавления всех этих импортов ваш код будет выглядеть до и после внесения изменений:
ДО:
from flask import Flask, render_template, request
from google.appengine.ext import ndb
ПОСЛЕ:
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. Добавить задачу с отправкой (собрать данные для задачи, поставить новую задачу в очередь).
В документации по очередям отправки указано: «Для обработки задачи необходимо добавить ее в очередь отправки. App Engine предоставляет очередь отправки по умолчанию, которая называется default и настроена и готова к использованию со стандартными параметрами. При желании вы можете просто добавить все свои задачи в очередь default, не создавая и не настраивая другие очереди». В этом практическом занятии для краткости используется очередь default . Чтобы узнать больше о создании собственных очередей отправки с теми же или различными характеристиками, см. документацию по созданию очередей отправки .
Основная цель этого практического занятия — добавить задачу (в очередь push-уведомлений default ), задача которой — удалять из Datastore старые посещения, которые больше не отображаются. Базовое приложение регистрирует каждое посещение ( GET запрос к / ) путем создания новой сущности Visit , затем получает и отображает самые последние посещения. Ни одно из самых старых посещений больше никогда не будет отображаться или использоваться, поэтому задача push-уведомлений удаляет все посещения старше самого старого отображаемого . Для этого необходимо немного изменить поведение приложения:
- При запросе информации о последних посещениях, вместо немедленного возврата данных о них, измените приложение так, чтобы оно сохраняло метку времени последнего
Visit, самую старую из отображаемых — все посещения старше этой даты можно безопасно удалить. - Создайте задачу отправки с этой меткой времени в качестве полезной нагрузки и направьте её обработчику задач, доступному через HTTP
POSTпо адресу/trim. В частности, используйте стандартные утилиты Python для преобразования метки времени из хранилища данных и отправки её (в виде числа с плавающей запятой) в задачу, а также для записи её в лог (в виде строки) и возврата этой строки в качестве значения-индикатора для отображения пользователю.
Всё это происходит в функции fetch_visits() , и вот как это выглядит до и после внесения этих изменений:
ДО:
def fetch_visits(limit):
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch(limit))
ПОСЛЕ:
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. Добавьте обработчик задач (код, вызываемый при выполнении задачи).
Хотя удаление старых посещений можно было бы легко осуществить в fetch_visits() , следует понимать, что эта функциональность мало связана с конечным пользователем. Это вспомогательная функция, и её хорошо обрабатывать асинхронно вне стандартных запросов приложения. Конечный пользователь получит выгоду от более быстрых запросов, поскольку в Datastore будет меньше информации. Создайте новую функцию trim() , вызываемую через POST запрос очереди задач к /trim , которая выполняет следующее:
- Извлекает временную метку "самого старого посещения".
- Выполняет запрос к хранилищу данных для поиска всех объектов старше указанной временной метки.
- Выбирает более быстрый запрос "только по ключам", поскольку фактические данные пользователя не требуются.
- Регистрирует количество удаляемых объектов (включая ноль).
- Вызывает
ndb.delete_multi()для удаления всех сущностей (пропускается, если их нет). - Возвращает пустую строку (вместе с неявным кодом возврата HTTP 200).
Всю эту информацию вы можете увидеть в trim() ниже. Добавьте её в main.py сразу после 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. Обновите веб-шаблон.
Обновите веб-шаблон, templates/index.html , добавив следующее условие Jinja2, чтобы отображалась самая старая метка времени, если такая переменная существует:
{% if oldest is defined %}
<b>Deleting visits older than:</b> {{ oldest }}</p>
{% endif %}
Добавьте этот фрагмент кода после отображаемого списка посещений, но перед закрытием тела сообщения, чтобы ваш шаблон выглядел следующим образом:
<!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. Подведение итогов/Завершение
В этом разделе завершается выполнение данного практического задания путем развертывания приложения, проверки его корректной работы и корректности выходных данных. После проверки приложения выполните очистку и определите дальнейшие шаги.
Разверните и проверьте приложение.
Разверните приложение с помощью gcloud app deploy . Результат должен быть идентичен результату развертывания приложения из Модуля 1, за исключением новой строки внизу, указывающей, какие посещения будут удалены:

Поздравляем с завершением практического задания! Ваш код теперь должен соответствовать содержимому папки репозитория модуля 7. Теперь он готов к миграции в облачные задачи модуля 8 .
Уборка
Общий
Если на этом пока всё, мы рекомендуем отключить ваше приложение App Engine, чтобы избежать дополнительных расходов. Однако, если вы хотите продолжить тестирование или эксперименты, платформа App Engine предоставляет бесплатную квоту , поэтому, пока вы не превысите этот лимит, с вас не должны взиматься дополнительные платежи. Это касается вычислительных ресурсов, но за соответствующие услуги App Engine также может взиматься плата, поэтому проверьте страницу с ценами для получения более подробной информации. Если эта миграция включает другие облачные сервисы, они оплачиваются отдельно. В любом случае, если применимо, см. раздел «Информация, относящаяся к этому практическому занятию» ниже.
Для полной ясности, развертывание на бессерверной вычислительной платформе Google Cloud, такой как App Engine, влечет за собой незначительные затраты на сборку и хранение . Cloud Build и Cloud Storage имеют собственную бесплатную квоту. Хранение образа использует часть этой квоты. Однако вы можете проживать в регионе, где нет такого бесплатного уровня, поэтому следите за использованием хранилища, чтобы минимизировать потенциальные затраты. К числу конкретных «папок» Cloud Storage, которые следует проверить, относятся:
-
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 - Приведенные выше ссылки на хранилища зависят от вашего
PROJECT_IDи *LOC*, например, "us", если ваше приложение размещено в США.
С другой стороны, если вы не собираетесь продолжать работу над этим приложением или другими связанными с миграцией кодовыми руководствами и хотите полностью удалить все, закройте свой проект .
Это относится именно к данному практическому занятию.
Перечисленные ниже услуги являются уникальными для данной учебной лаборатории. Для получения более подробной информации обратитесь к документации по каждому продукту:
- Сервис App Engine Task Queue не влечет за собой дополнительных расходов, как указано на странице с ценами для устаревших пакетных сервисов, таких как Task Queue.
- Сервис App Engine Datastore предоставляется компанией Cloud Datastore (Cloud Firestore в режиме Datastore), которая также предлагает бесплатный тариф; подробную информацию можно найти на странице с ценами .
Следующие шаги
В ходе этой «миграции» вы добавили использование очереди задач (Task Queue) в пример приложения Модуля 1, добавив поддержку отслеживания посетителей, в результате чего появилось приложение Модуля 7. Следующая миграция научит вас, как перейти с задач App Engine на задачи Cloud Tasks, если вы решите это сделать. Начиная с осени 2021 года, пользователям больше не нужно переходить на Cloud Tasks при обновлении до Python 3. Подробнее об этом читайте в следующем разделе.
Если вы хотите перейти на Cloud Tasks, следующим шагом будет практическое занятие по модулю 8. Помимо этого, следует рассмотреть дополнительные варианты миграции, такие как Cloud Datastore, Cloud Memorystore, Cloud Storage или Cloud Pub/Sub (очереди запросов). Также доступны миграции между продуктами Cloud Run и Cloud Functions. Весь контент Serverless Migration Station (практические занятия, видео, исходный код [при наличии]) доступен в его репозитории с открытым исходным кодом .
7. Переход на Python 3
Осенью 2021 года команда App Engine расширила поддержку многих встроенных сервисов для сред выполнения второго поколения (изначально доступных только в средах выполнения первого поколения), а это значит, что вам больше не нужно переходить от встроенных сервисов, таких как App Engine Task Queue, к автономным облачным сервисам или сторонним аналогам, таким как Cloud Tasks, при портировании вашего приложения на Python 3. Другими словами, вы можете продолжать использовать Task Queue в приложениях App Engine на Python 3, если адаптируете код для доступа к встроенным сервисам из сред выполнения следующего поколения .
Подробнее о том, как перенести использование встроенных сервисов на Python 3, вы можете узнать в практическом задании по модулю 17 и соответствующем видео. Хотя эта тема выходит за рамки модуля 7, ниже приведены ссылки на версии приложений из модулей 1 и 7, портированные на Python 3 и по-прежнему использующие App Engine NDB и Task Queue.
8. Дополнительные ресурсы
Ниже перечислены дополнительные ресурсы для разработчиков, желающих подробнее изучить этот или связанный с ним модуль миграции, а также сопутствующие продукты. Сюда входят места для оставления отзывов о данном контенте, ссылки на код и различные документы, которые могут оказаться полезными.
Вопросы/отзывы по Codelab
Если вы обнаружите какие-либо проблемы в этом практическом задании, пожалуйста, сначала найдите свою проблему, прежде чем сообщать о ней. Ссылки для поиска и создания новых проблем:
Миграционные ресурсы
Ссылки на папки репозитория для Модуля 2 (НАЧАЛО) и Модуля 7 (ЗАВЕРШЕНИЕ) можно найти в таблице ниже.
Кодлаб | Python 2 | Python 3 |
код (не представлен в этом уроке) | ||
Модуль 7 (данная практическая работа) | код (не представлен в этом уроке) |
Онлайн-ресурсы
Ниже приведены онлайн-ресурсы, которые могут быть полезны для данного урока:
Очередь задач App Engine
- Обзор очереди задач App Engine
- Обзор очередей задач App Engine и очередей отправки
- Создание очередей задач с отправкой данных
- ссылка на файл
queue.yaml -
queue.yamlпротив облачных задач - Руководство по миграции очередей задач в облако
- Пример документации по функции отправки очередей задач App Engine в облачные задачи.
платформа App Engine
- Документация App Engine
- Среда выполнения Python 2 App Engine (стандартная среда)
- Использование встроенных библиотек App Engine в Python 2 App Engine
- Среда выполнения Python 3 App Engine (стандартная среда)
- Различия между средами выполнения Python 2 и 3 App Engine (стандартная среда)
- Руководство по миграции с Python 2 на Python 3 App Engine (стандартная среда)
- Информация о ценах и квотах App Engine
- Запуск платформы App Engine второго поколения (2018)
- Сравнение платформ первого и второго поколений
- Долгосрочная поддержка устаревших сред выполнения.
- Образцы миграции документации
- Образцы миграции, предоставленные сообществом
Прочая информация об облачных сервисах
- Python на платформе Google Cloud
- Клиентские библиотеки Python от Google Cloud
- Уровень Google Cloud «Всегда бесплатно»
- Google Cloud SDK (инструмент командной строки
gcloud) - Вся документация Google Cloud
Видео
- Станция миграции бессерверных приложений
- Бессерверные экспедиции
- Подпишитесь на Google Cloud Tech
- Подпишитесь на Google Developers
Лицензия
Данная работа распространяется под лицензией Creative Commons Attribution 2.0 Generic.