Модуль 2. Миграция с App Engine ndb на Cloud NDB

1. Обзор

Эта серия учебных пособий (практических руководств для самостоятельного обучения) призвана помочь разработчикам Google App Engine (стандартной версии) модернизировать свои приложения, проведя их через серию миграций. Наиболее важным шагом является отказ от исходных комплексных служб среды выполнения, поскольку среды выполнения следующего поколения более гибкие и предоставляют пользователям более широкий выбор вариантов обслуживания. Переход на среду выполнения нового поколения позволяет упростить интеграцию с продуктами Google Cloud, использовать более широкий спектр поддерживаемых сервисов и поддерживать текущие языковые версии.

Из этого руководства вы узнаете, как выполнить миграцию со встроенной клиентской библиотеки ndb (Next Database) App Engine в клиентскую библиотеку Cloud NDB .

Вы узнаете, как

  • Используйте библиотеку App Engine ndb (если вы с ней не знакомы)
  • Миграция с ndb на Cloud NDB
  • Дальнейший перенос вашего приложения на Python 3.

Что вам понадобится

Опрос

Как вы будете использовать эту кодовую лабораторию?

Только прочитай это Прочитайте его и выполните упражнения.

2. Предыстория

В модуле 1 мы перенесли веб-фреймворки из встроенного в App Engine webapp2 в Flask . В этой лаборатории кода мы продолжаем отходить от встроенных сервисов App Engine, переключаясь с библиотеки App Engine ndb на Google Cloud NDB .

Завершив эту миграцию, вы сможете:

  1. Переход на Python 3 и среду выполнения App Engine следующего поколения.
  2. Миграция в Cloud Datastore (клиентская библиотека для приложений, не принадлежащих App Engine)
  3. Контейнеризируйте свое приложение Python 2 (или 3) и перенесите его в Cloud Run.
  4. Добавьте использование очередей задач App Engine (push), а затем перейдите на Cloud Tasks.

Но мы еще не там. Завершите эту лабораторную работу, прежде чем рассматривать следующие шаги. Миграция в этом руководстве включает в себя следующие основные шаги:

  1. Настройка/Предварительная работа
  2. Добавить библиотеку Cloud NDB
  3. Обновить файлы приложения

3. Настройка/Предварительная работа

Прежде чем мы приступим к основной части руководства, давайте настроим наш проект, получим код, а затем развернем базовое приложение, чтобы мы знали, что начали с рабочего кода.

1. Проект установки

Если вы завершили лабораторную работу по Модулю 1 , мы рекомендуем повторно использовать тот же проект (и код). Альтернативно вы можете создать новый проект или повторно использовать другой существующий проект. Убедитесь, что у проекта есть активный платежный аккаунт и включен App Engine.

2. Получите базовый образец приложения.

Одним из обязательных условий является наличие работающего примера приложения Модуля 1. Используйте свое решение, если вы прошли это руководство. Вы можете завершить его сейчас (ссылка выше) или, если хотите пропустить его, скопировать репозиторий Модуля 1 (ссылка ниже).

Независимо от того, используете ли вы свой или наш, мы НАЧНЕМ с кода Модуля 1. Эта лаборатория кода Модуля 2 проведет вас через каждый шаг, и по завершении она должна напоминать код в точке ФИНИШ (включая дополнительный «бонусный» порт из Python 2 в 3):

Ваша папка с кодом STARTing Module 1 должна иметь следующее содержимое:

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

Если вы прошли обучение по Модулю 1, у вас также будет папка lib с Flask и его зависимостями. Если у вас нет папки lib , создайте ее с помощью команды pip install -t lib -r requirements.txt чтобы мы могли развернуть это базовое приложение на следующем шаге. Если у вас установлены как Python 2, так и Python 3, мы рекомендуем использовать pip2 вместо pip , чтобы избежать путаницы с Python 3.

3. (Повторно) разверните приложение Модуля 1.

Оставшиеся подготовительные шаги, которые необходимо выполнить сейчас:

  1. Повторно ознакомьтесь с инструментом командной строки gcloud (если необходимо).
  2. (Повторно) разверните код Модуля 1 в App Engine (если необходимо).

После того как вы успешно выполнили эти шаги и подтвердили его работоспособность, мы продолжим работу с этим руководством, начиная с файлов конфигурации.

4. Обновите файлы конфигурации (добавьте библиотеку Cloud NDB).

Многие оригинальные встроенные сервисы App Engine превратились в собственные продукты, и Datastore — один из них. Сегодня приложения, не относящиеся к App Engine, могут использовать Cloud Datastore . Для давних пользователей ndb команда Google Cloud создала клиентскую библиотеку Cloud NDB для взаимодействия с Cloud Datastore. Он доступен как для Python 2, так и для 3.

Давайте обновим файлы подтверждения, заменив App Engine ndb на Cloud NDB, а затем изменим наше приложение.

1. Обновите requirements.txt

В модуле 1 единственной внешней зависимостью нашего приложения был Flask. Теперь добавим Cloud NDB. Вот как выглядел ваш файл requirements.txt в конце модуля 1:

  • ДО:
Flask==1.1.2

Для перехода с App Engine ndb требуется библиотека Cloud NDB ( google-cloud-ndb ), поэтому добавьте ее пакет в requirements.txt .

  • ПОСЛЕ:
Flask==1.1.2
google-cloud-ndb==1.7.1

На момент написания этой кодовой лаборатории последняя рекомендуемая версия — 1.7.1, но requirements.txt в репозитории может иметь более новую версию. Мы рекомендуем последние версии каждой библиотеки, но если они не работают, вы можете вернуться к более старой версии.

Удалите папку lib , если она у вас есть и вы не создали ее выше. Теперь (пере) установите обновленные библиотеки с помощью команды pip install -t lib -r requirements.txt , используя при необходимости pip2 вместо pip .

2. Обновите app.yaml

Добавление клиентских библиотек Google Cloud, таких как google-cloud-ndb имеет несколько требований, все они связаны с включением «встроенных» библиотек — сторонних пакетов, уже доступных на серверах Google. Вы не указываете их в requirements.txt и не копируете их с помощью pip install . Единственные требования:

  1. Укажите встроенные библиотеки в app.yaml
  2. Укажите им скопированные сторонние библиотеки, с которыми они могут работать (в lib ).

Вот НАЧАЛЬНЫЙ app.yaml из модуля 1:

  • ДО:
runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

Теперь добавьте следующие строки в app.yaml для ссылки на пару сторонних пакетов: grpcio и setuptools в новом разделе libraries :

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

Зачем использовать эти встроенные библиотеки? gRPC — это открытая платформа RPC, используемая всеми клиентскими библиотеками Google Cloud , включая google-cloud-ndb . Библиотека grpcio является адаптером Python gRPC и поэтому необходима. Обоснование включения setuptools скоро появится.

  • ПОСЛЕ:

Благодаря внесенным выше изменениям ваш обновленный app.yaml теперь должен выглядеть следующим образом:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

3. Обновите appengine_config.py

Инструмент pkg_resources , входящий в состав библиотеки setuptools , используется для предоставления встроенным сторонним библиотекам доступа к встроенным библиотекам. Обновите appengine_config.py , чтобы использовать pkg_resources , чтобы указать им связанные библиотеки в lib . Когда вы внесете это изменение, весь файл должен выглядеть так:

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)

5. Обновите файлы приложения.

Уладив формальности с файлом конфигурации, теперь вы можете перейти с ndb на Cloud NDB. Чтобы завершить миграцию, обновите импортированные библиотеки и добавьте использование управления контекстом в main.py

1. Импорт

Сделайте следующую замену импорта в main.py :

  • ДО
from google.appengine.ext import ndb
  • ПОСЛЕ:
from google.cloud import ndb

Переход от библиотеки App Engine к библиотеке Google Cloud иногда столь же незаметен, как в этом случае. Для встроенных сервисов, которые стали полноценными продуктами Google Cloud, вы будете импортировать атрибуты из google.cloud вместо google.appengine .

2. Доступ к хранилищу данных

Чтобы иметь возможность использовать библиотеку Cloud NDB, ваше приложение должно использовать менеджеры контекста Python . Их цель — «закрыть» доступ к ресурсам, чтобы их необходимо было получить, прежде чем их можно будет использовать. Менеджеры контекста основаны на методе управления информатикой, известном как инициализация распределения ресурсов (или RAII) . Менеджеры контекста используются с файлами Python (которые необходимо открыть, прежде чем к ним можно будет получить доступ) и параллелизмом, « спин-блокировки » должны быть получены до того, как код в « критическом разделе » может быть выполнен.

Аналогичным образом, Cloud NDB требует, чтобы вы получили контекст клиента для связи с хранилищем данных, прежде чем какие-либо команды хранилища данных смогут выполняться. Сначала создайте клиент ( ndb.Client() ), добавив ds_client = ndb.Client() в main.py сразу после инициализации Flask :

app = Flask(__name__)
ds_client = ndb.Client()

Команда Python with используется исключительно для получения контекста объекта. Оберните любые блоки кода, обращающиеся к хранилищу данных, операторами with .

Ниже приведены те же функции из модуля 1 для записи нового объекта в хранилище данных и чтения для отображения последних добавленных объектов:

  • ДО:

Вот исходный код без управления контекстом:

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    'get most recent visits'
    return (v.to_dict() for v in Visit.query().order(
            -Visit.timestamp).fetch(limit))
  • ПОСЛЕ:

Теперь добавьте with ds_client.context(): и переместите код доступа к хранилищу данных в блок with :

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    'get most recent visits'
    with ds_client.context():
        return (v.to_dict() for v in Visit.query().order(
                -Visit.timestamp).fetch(limit))

Основное приложение драйвера остается таким же, как и в модуле 1, поскольку здесь нет кода ndb (ни Cloud NDB):

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

Лучшей практикой является обеспечение четкого различия между кодом приложения и доступом к данным. Таким образом, ваш основной код приложения не изменится при изменении базового механизма хранения данных, как мы это сделали при этой миграции.

6. Подведение итогов/очистка

Развернуть приложение

Повторно разверните приложение с помощью gcloud app deploy и убедитесь, что приложение работает. Теперь ваш код должен соответствовать тому, что находится в репозитории Модуля 2 .

Если вы приступили к этой серии, не пройдя ни одной из предыдущих работ по коду, само приложение не изменится; он регистрирует все посещения главной веб-страницы ( / ) и выглядит так, если вы посетили сайт достаточное количество раз:

приложение Visitme

Поздравляем с завершением этой лабораторной работы по Модулю 2. Вы только что пересекли финишную черту, поскольку это последняя из настоятельно рекомендуемых миграций в этой серии в отношении Datastore.

Дополнительно: очистка

А как насчет очистки, чтобы избежать выставления счетов до тех пор, пока вы не будете готовы перейти к следующей лаборатории кода миграции? Как существующие разработчики, вы, вероятно, уже в курсе ценовой информации App Engine .

Необязательно: отключить приложение

Если вы еще не готовы перейти к следующему руководству, отключите приложение , чтобы избежать расходов. Когда вы будете готовы перейти к следующей лаборатории кода, вы можете снова включить ее. Пока ваше приложение отключено, оно не будет получать трафик, за который будет взиматься плата, однако вам может быть выставлен счет еще за одну вещь, за которую вы можете получить счет за использование хранилища данных, если оно превышает бесплатную квоту , поэтому удалите достаточно трафика, чтобы попасть под этот лимит.

С другой стороны, если вы не собираетесь продолжать миграцию и хотите полностью удалить все, вы можете закрыть свой проект .

Следующие шаги

Отсюда появляется гибкость в отношении вашего следующего шага. Выберите любой из этих вариантов:

  • Бонус модуля 2. Перейдите к бонусной части этого руководства, чтобы изучить перенос на Python 3 и среду выполнения App Engine следующего поколения.
  • Модуль 7. Очереди задач App Engine Push (требуется, если вы используете очереди задач [push])
    • Добавляет taskqueue задач App Engine в приложение модуля 1.
    • Готовит пользователей к переходу на облачные задачи в модуле 8.
  • Модуль 4. Переход на Cloud Run с помощью Docker
    • Контейнеризируйте свое приложение для работы в облаке. Работайте с Docker.
    • Позволяет вам оставаться на Python 2
  • Модуль 5. Переход на Cloud Run с помощью Cloud Buildpacks
    • Контейнеризируйте свое приложение для работы в облаке. Запускайте с помощью Cloud Buildpacks.
    • Вам не нужно ничего знать о Docker, контейнерах или Dockerfile .
    • Требуется, чтобы вы уже перенесли свое приложение на Python 3.
  • Модуль 3:
    • Модернизация доступа к хранилищу данных с Cloud NDB на Cloud Datastore
    • Это библиотека, используемая для приложений Python 3 App Engine и приложений, не принадлежащих App Engine.

7. БОНУС: переход на Python 3.

Чтобы получить доступ к новейшей среде выполнения и функциям App Engine, мы рекомендуем вам перейти на Python 3. В нашем примере приложения Datastore был единственной встроенной службой, которую мы использовали, и поскольку мы перешли с ndb на Cloud NDB, теперь мы можем порт в среду выполнения App Engine Python 3.

Обзор

Хотя портирование на Python 3 не входит в рамки руководства по Google Cloud, эта часть лаборатории кода дает разработчикам представление о том, чем отличается среда выполнения Python 3 App Engine. Одной из выдающихся особенностей среды выполнения следующего поколения является упрощенный доступ к сторонним пакетам; нет необходимости указывать встроенные пакеты в app.yaml а также не требуется копировать или загружать невстроенные библиотеки; они устанавливаются неявно из списка в requirements.txt .

Поскольку наш образец настолько прост , а Cloud NDB совместим с Python 2–3, код приложения не требуется явно портировать на 3.x; приложение работает на версиях 2.x и 3.x без изменений, то есть в данном случае необходимы только изменения в конфигурации:

  1. Упростите app.yaml , чтобы он ссылался на Python 3, и удалите сторонние библиотеки.
  2. Удалите appengine_config.py и папку lib , поскольку они больше не нужны.

Помимо main.py , файлы requirements.txt и templates/index.html остаются неизменными.

Упростите app.yaml

ДО:

Единственное реальное изменение в этом примере приложения — существенное сокращение app.yaml . Напомним, вот что у нас было в app.yaml по завершении Модуля 2 :

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

ПОСЛЕ:

В Python 3 все директивы threadsafe , api_version libraries устарели; все приложения считаются потокобезопасными, а api_version не используется в Python 3. В службах App Engine больше не предустановлены встроенные сторонние пакеты, поэтому libraries также устарели. Дополнительную информацию об этих изменениях можно найти в документации по изменениям в app.yaml . В результате вам следует удалить все три из app.yaml и обновиться до поддерживаемой версии Python 3 (см. ниже).

Необязательно: использование директивы handlers .

Кроме того, директива handlers , которая направляет трафик в приложения App Engine, также устарела. Поскольку среда выполнения следующего поколения ожидает, что веб-платформы будут управлять маршрутизацией приложений, все «скрипты-обработчики» необходимо изменить на « auto ». Объединив изменения, описанные выше, вы получите такой app.yaml :

runtime: python38

handlers:
- url: /.*
  script: auto

Узнайте больше о script: auto на странице его документации .

Удаление директивы handlers

Поскольку handlers устарели, вы также можете удалить весь раздел, оставив app.yaml в одну строку:

runtime: python38

По умолчанию будет запущен веб-сервер Gunicorn WSGI , доступный для всех приложений. Если вы знакомы с gunicorn , эта команда выполняется при запуске по умолчанию с помощью базового app.yaml :

gunicorn main:app --workers 2 -c /config/gunicorn.py

Необязательно: использование директивы entrypoint

Однако если вашему приложению требуется определенная команда запуска, ее можно указать с помощью директивы entrypoint , где ваш app.yaml будет выглядеть следующим образом:

runtime: python38
entrypoint: python main.py

В этом примере специально требуется использовать сервер разработки Flask вместо gunicorn . Код, запускающий сервер разработки, также необходимо добавить в ваше приложение для запуска на интерфейсе 0.0.0.0 через порт 8080, добавив этот небольшой раздел в конец файла main.py :

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

Узнайте больше о entrypoint на странице документации . Дополнительные примеры и рекомендации можно найти в стандартной документации по запуску App Engine , а также в документации по запуску App Engine Flexible .

Удалите appengine_config.py и lib

Удалите файл appengine_config.py и папку lib . При переходе на Python 3 App Engine получает и устанавливает пакеты, перечисленные в requirements.txt .

Файл конфигурации appengine_config.py используется для распознавания сторонних библиотек/пакетов, независимо от того, скопировали ли вы их самостоятельно или используете уже доступные на серверах App Engine (встроенные). При переходе на Python 3 краткое изложение больших изменений:

  1. Нет объединения скопированных сторонних библиотек (перечисленных в requirements.txt ).
  2. Нет pip install в папку lib , что означает отсутствие периода в папке lib
  3. В app.yaml нет списка встроенных сторонних библиотек.
  4. Нет необходимости ссылаться на приложение на сторонние библиотеки, поэтому файл appengine_config.py отсутствует.

Все, что нужно, — это перечислить все необходимые сторонние библиотеки в requirements.txt .

Развернуть приложение

Повторно разверните приложение, чтобы убедиться, что оно работает. Вы также можете подтвердить, насколько ваше решение близко к примеру кода Python 3 из Модуля 2 . Чтобы визуализировать различия с Python 2, сравните код с его версией Python 2 .

Поздравляем с завершением бонусного этапа Модуля 2! Посетите документацию по подготовке файлов конфигурации для среды выполнения Python 3 . Наконец, просмотрите (более раннюю) страницу «Сводка/Очистка», чтобы узнать о дальнейших действиях и очистке.

Подготовка вашего приложения

Когда придет время перенести ваше приложение, вам придется перенести файл main.py и другие файлы приложения в версию 3.x, поэтому рекомендуется приложить все усилия, чтобы сделать ваше приложение 2.x максимально «совместимым с предыдущими версиями», как возможный.

Есть множество онлайн-ресурсов, которые помогут вам в этом, но вот некоторые ключевые советы:

  1. Убедитесь, что все зависимости приложения полностью совместимы с 3.x.
  2. Убедитесь, что ваше приложение работает как минимум на версии 2.6 (предпочтительно 2.7).
  3. Убедитесь, что приложение прошло весь набор тестов (и покрытие минимум 80%).
  4. Используйте библиотеки совместимости, такие как six , Future и/или Modernize.
  5. Узнайте о ключевых различиях между версиями 2.x и 3.x, несовместимыми с предыдущими версиями.
  6. Любой ввод-вывод, скорее всего, приведет к несовместимости Unicode и байтовых строк.

Пример приложения был разработан с учетом всего этого, поэтому приложение работает на версиях 2.x и 3.x прямо из коробки, чтобы мы могли сосредоточиться на том, чтобы показать вам, что необходимо изменить, чтобы использовать платформу следующего поколения. .

8. Дополнительные ресурсы

Проблемы и отзывы о модулях миграции App Engine

Если вы обнаружите какие-либо проблемы с этой кодовой лабораторией, сначала найдите свою проблему, прежде чем подавать заявку. Ссылки для поиска и создания новых задач:

Миграционные ресурсы

Ссылки на папки репозитория для Модуля 1 (НАЧАЛО) и Модуля 2 (ФИНИШ) можно найти в таблице ниже. Доступ к ним также можно получить из репозитория для всех миграций лабораторий кода App Engine , которые можно клонировать или загрузить в виде ZIP-файла.

Кодлаб

Питон 2

Питон 3

Модуль 1

код

(н/д)

Модуль 2

код

код

Ресурсы App Engine

Ниже приведены дополнительные ресурсы, касающиеся этой конкретной миграции: