1. Обзор
Эта серия учебных пособий (практических руководств для самостоятельного обучения) призвана помочь разработчикам Google App Engine (стандартной версии) модернизировать свои приложения, проведя их через серию миграций. Наиболее важным шагом является отказ от исходных комплексных служб среды выполнения, поскольку среды выполнения следующего поколения более гибкие и предоставляют пользователям более широкий выбор вариантов обслуживания. Переход на среду выполнения нового поколения позволяет упростить интеграцию с продуктами Google Cloud, использовать более широкий спектр поддерживаемых сервисов и поддерживать текущие языковые версии.
В этом первоначальном руководстве показаны первые шаги миграции для модернизации веб-платформы в приложениях App Engine: переход с webapp2
на Flask . В своем приложении вы можете использовать любую веб-инфраструктуру, поддерживающую маршрутизацию, но в этом руководстве мы используем Flask, поскольку он широко используется сообществом.
Вы узнаете, как
- Используйте сторонние библиотеки (встроенные или другие)
- Обновить файлы конфигурации
- Перенос простого приложения из
webapp2
в Flask
Что вам понадобится
- Проект Google Cloud Platform с:
- Базовые навыки Python
- Знание основных команд Linux
- Базовые знания разработки и развертывания приложений App Engine.
Опрос
Как вы будете использовать эту кодовую лабораторию?
2. Предыстория
Платформа webapp
была включена в комплект, когда App Engine впервые был запущен на Python 2.5 в 2008 году. Спустя годы она была заменена преемником webapp2
, когда в 2013 году среда выполнения 2.7 объявила устаревшей версию 2.5 .
Хотя webapp2
(см. документацию ) все еще существует и может использоваться вне App Engine в качестве веб-платформы, совместимой с WSGI, он не выполняет собственную маршрутизацию пользовательских запросов к соответствующему коду в приложении. Вместо этого он полагается на App Engine, файлы конфигурации и разработчика для выполнения маршрутизации веб-трафика к соответствующим «обработчикам». Более того, основные преимущества webapp2
неразрывно связаны со встроенными службами App Engine, что фактически делает его устаревшим, даже несмотря на то , что он работает на Python 3 (см. также связанную проблему ).
Этот модуль дает специалистам практический опыт переноса простого приложения webapp2
на Flask, платформу, поддерживаемую App Engine, и многие другие сервисы за пределами Google Cloud, что делает приложения намного более переносимыми. Если Flask не является желаемой платформой для перемещения вашего приложения, вы можете выбрать другую, при условии, что она выполняет собственную маршрутизацию. В этой лаборатории кода показаны лица, принимающие решения в области информационных технологий (ITDM), и разработчики, каковы этапы миграции, поэтому вы можете ознакомиться с этим процессом независимо от того, на какую платформу вы фактически переходите.
Вот основные шаги для этой миграции:
- Настройка/Предварительная работа
- Добавить стороннюю библиотеку Flask
- Обновить файлы приложения
- Обновить файл HTML-шаблона
3. Настройка/Предварительная работа
Прежде чем мы приступим к основной части руководства, давайте настроим наш проект, получим код, затем (повторно) познакомим вас с командой gcloud
и развернем базовое приложение, чтобы мы знали, что начали с рабочего кода.
1. Проект установки
Как существующему разработчику, ваша панель App Engine , скорее всего, уже показывает, какие сервисы у вас запущены. Для целей этого руководства мы рекомендуем вам создать новый проект или повторно использовать существующий для этого руководства. Убедитесь, что у проекта есть активный платежный аккаунт и включен App Engine (приложение).
2. Загрузите базовый образец приложения.
Репозиторий миграции GAE содержит весь необходимый вам код. Клонируйте его или загрузите ZIP-файл. Работа с этим руководством вы начнете с кода в папке «Модуль 0» (START), а по завершении обучения ваш код должен соответствовать папке «Модуль 1» (FINISH). Если нет, проверьте различия, чтобы перейти к следующей лабораторной работе.
- СТАРТ: код модуля 0
- ОТДЕЛКА: Код модуля 1
- Весь репозиторий (для клонирования или загрузки ZIP)
В папке «Модуль 0» должны быть файлы, которые выглядят следующим образом, как показано с помощью команды POSIX ls
:
$ ls
app.yaml index.html main.py
3. (Повторно) Ознакомьтесь с командами gcloud
Если на вашем компьютере еще нет команды gcloud
, установите Google Cloud SDK и убедитесь, что gcloud
доступен как часть вашего пути выполнения, а также ознакомьтесь со следующими командами gcloud
:
-
gcloud components update
— обновите Google Cloud SDK -
gcloud auth login
— войдите в свою учетную запись -
gcloud config list
— список настроек конфигурации проекта GCP. -
gcloud config set project PROJECT_ID
— установить идентификатор проекта GCP -
gcloud app deploy
— разверните приложение App Engine.
Если вы в последнее время не занимались разработкой App Engine с помощью gcloud
, вам следует выполнить первые четыре команды (#1–#4), чтобы настроиться, прежде чем переходить к следующим шагам. Давайте сделаем краткий обзор этих команд.
Во-первых, gcloud components update
гарантирует, что у вас установлена последняя версия Cloud SDK. Запуск этой команды должен дать результат, подобный следующему:
$ gcloud components update Your current Cloud SDK version is: 317.0.0 You will be upgraded to version: 318.0.0 ┌──────────────────────────────────────────────────┐ │ These components will be updated. │ ├──────────────────────────┬────────────┬──────────┤ │ Name │ Version │ Size │ ├──────────────────────────┼────────────┼──────────┤ │ Cloud SDK Core Libraries │ 2020.11.06 │ 15.5 MiB │ │ gcloud cli dependencies │ 2020.11.06 │ 10.6 MiB │ └──────────────────────────┴────────────┴──────────┘ The following release notes are new in this upgrade. Please read carefully for information about new features, breaking changes, and bugs fixed. The latest full release notes can be viewed at: https://cloud.google.com/sdk/release_notes 318.0.0 (2020-11-10) . . . (release notes) . . . Subscribe to these release notes at https://groups.google.com/forum/#!forum/google-cloud-sdk-announce. Do you want to continue (Y/n)? ╔════════════════════════════════════════════════════════════╗ ╠═ Creating update staging area ═╣ ╠════════════════════════════════════════════════════════════╣ ╠═ Uninstalling: Cloud SDK Core Libraries ═╣ ╠════════════════════════════════════════════════════════════╣ ╠═ Uninstalling: gcloud cli dependencies ═╣ ╠════════════════════════════════════════════════════════════╣ ╠═ Installing: Cloud SDK Core Libraries ═╣ ╠════════════════════════════════════════════════════════════╣ ╠═ Installing: gcloud cli dependencies ═╣ ╠════════════════════════════════════════════════════════════╣ ╠═ Creating backup and activating new installation ═╣ ╚════════════════════════════════════════════════════════════╝ Performing post processing steps...done. Update done! To revert your SDK to the previously installed version, you may run: $ gcloud components update --version 317.0.0
Затем используйте gcloud auth login
для аутентификации для команд gcloud
, которые вы будете выполнять в дальнейшем:
$ gcloud auth login Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id= . . . You are now logged in as [YOUR_EMAIL]. Your current project is [PROJECT_ID]. You can change this setting by running: $ gcloud config set project PROJECT_ID
Используйте gcloud config list
, чтобы увидеть текущие настройки вашего проекта:
$ gcloud config list [core] account = YOUR_EMAIL disable_usage_reporting = False project = PROJECT_ID Your active configuration is: [default]
Приведенная выше команда поможет вам создать новый проект или выбрать существующий. Если выходные данные gcloud config list
не соответствуют выбранному проекту, который вы собираетесь использовать для этого руководства, запустите gcloud config set project PROJECT_ID
чтобы установить идентификатор проекта. Затем убедитесь, что установлен правильный идентификатор проекта, снова запустив gcloud config list
.
$ gcloud config set project PROJECT_ID Updated property [core/project].
Если вместо этого вы предпочитаете использовать Cloud Console , вы можете воспользоваться пользовательским интерфейсом, чтобы создать новый проект, если хотите, или использовать любой уже существующий проект. На панели управления вашего проекта вы должны увидеть информационную карточку проекта, на которой указан его идентификатор (наряду с именем и номером проекта):
Последняя команда (#5), gcloud app deploy
, предназначена для развертывания вашего приложения в App Engine. Поскольку мы только начинаем, запускать его сейчас необязательно, но мы, конечно, не препятствуем развертыванию кода Модуля 0, чтобы убедиться, что он работает. После выполнения выберите географический регион, в котором вы хотите, чтобы приложение работало (обычно там, где вы находитесь). Однако его нельзя изменить после установки. Затем просмотрите остальную информацию о развертывании. По завершении вы получите уведомление об URL-адресе, по которому будет обслуживаться ваше приложение. Вот сокращенная версия того, что вы можете увидеть:
$ gcloud app deploy Services to deploy: descriptor: [/private/tmp/mod0-baseline/app.yaml] source: [/private/tmp/mod0-baseline] target project: [PROJECT_ID] target service: [default] target version: [20201116t220827] target url: [https://PROJECT_ID.REG_ABBR.r.appspot.com] Do you want to continue (Y/n)? Beginning deployment of service [default]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 1 file to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ File upload done. Updating service [default]...done. Setting traffic split for service [default]...done. Deployed service [default] to [https://PROJECT_ID.REG_ABBR.r.appspot.com] You can stream logs from the command line by running: $ gcloud app logs tail -s default To view your application in the web browser run: $ gcloud app browse
Если вы давно не использовали App Engine, вы можете заметить, что исходная команда appcfg.py update
была заменена командой gcloud app deploy
. Чтобы узнать больше о gcloud app deploy
, посетите его страницу документации .
Еще одним недавним изменением является URL-адрес развернутых приложений: он изменен с http://PROJECT_ID.appspot.com
на http://PROJECT_ID.REG_ABBR.r.appspot.com
. Большинство приложений со временем будут преобразованы в новый формат. Подробнее о формате URL в документации по запросам и маршрутизации .
После развертывания приложения обновите браузер (возможно, несколько раз), чтобы увидеть последние посещения:
Если ваше приложение новое, вы увидите только одно или несколько посещений.
4. Добавьте стороннюю библиотеку Flask.
Среда выполнения Python 2 App Engine предоставляет набор «встроенных» сторонних библиотек, все что вам нужно сделать — это указать их в файле app.yaml
для использования. Хотя эта миграция не требует их использования, они будут в следующем руководстве по миграции (для Модуля 2).
Сторонние библиотеки, которые не являются встроенными, необходимо указать в файле с именем requirements.txt
и установить локально в папке lib
в том же каталоге, что и код приложения, куда все загружается в App Engine. Дополнительную информацию можно найти в документации по объединению сторонних библиотек .
Скопированные библиотеки, такие как Flask, требуют, чтобы вы указали App Engine, чтобы они искали их в папке lib
с помощью файла конфигурации appengine_config.py
. Файл конфигурации appengine_config.py
размещается в той же папке приложения верхнего уровня, что и requirements.txt
и lib
. В этой части урока вы:
- Создайте
requirements.txt
(укажите скопированные [невстроенные] сторонние библиотеки) - Создайте
appengine_config.py
(распознавание сторонних библиотек) - Установите (сторонние) пакеты и зависимости
1. Создайте requirements.txt
Создайте файл requirements.txt
, чтобы указать свои пакеты. В нашем случае Flask — это необходимая сторонняя библиотека. На момент написания этой статьи последней версией была 1.1.2, поэтому создайте requirements.txt
включив в него одну строку:
Flask==1.1.2
Обратитесь к документации requirements.txt
, чтобы узнать больше о поддерживаемых форматах.
2. Создайте appengine_config.py
Следующий шаг — заставить App Engine распознавать внешние сторонние библиотеки. Создайте файл appengine_config.py
со следующим содержимым:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Этот код делает именно то, что мы указали ранее, а именно указывает App Engine на папку lib
для скопированных библиотек.
3. Установите пакет(ы) и зависимости.
Теперь запустите команду pip install
, чтобы создать папку lib
и установить туда Flask и его зависимости:
$ pip install -t lib -r requirements.txt
Независимо от того, использовали ли вы pip
или pip2
, после завершения установки пакета у вас должна быть папка lib
, содержимое которой будет похоже на:
$ ls lib bin/ click/ click-7.1.2.dist-info/ flask/ Flask-1.1.2.dist-info/ itsdangerous/ itsdangerous-1.1.0.dist-info/ jinja2/ Jinja2-2.11.2.dist-info/ markupsafe/ MarkupSafe-1.1.1.dist-info/ werkzeug/ Werkzeug-1.0.1.dist-info/
5. Обновите файлы приложения.
Теперь давайте обновим файл приложения main.py
1. Импорт
Импорт идет первым, как и во всех файлах Python. За импортом платформы webapp2
следует библиотека Datastore ndb
и, наконец, расширение App Engine, которое обрабатывает шаблоны с поддержкой Django. Вы должны увидеть следующее:
- ДО:
import webapp2
from google.appengine.ext import ndb
from google.appengine.ext.webapp import template
При переходе на Flask вы одновременно импортируете как Flask, так и части средства рендеринга шаблона. Удалите пару импортов, связанных с webapp2
и замените их следующим образом (оставьте импорт ndb
как есть):
- ПОСЛЕ:
from flask import Flask, render_template, request
from google.appengine.ext import ndb
2. Запуск
Приложениям, использующим webapp2
требуется один массив (список Python), в котором перечислены все маршруты и обработчики в любом файле Python (могут быть и другие):
- ДО:
app = webapp2.WSGIApplication([
('/', MainHandler),
], debug=True)
Имейте в виду, что app.yaml
выполняет маршрутизацию более высокого уровня и может вызывать разные обработчики. Пример приложения достаточно прост: все маршруты передаются обработчику main.py
Flask не использует подобные таблицы маршрутизации, поэтому удалите эти строки в main.py
Flask также требует инициализации, поэтому добавьте следующую строку вверху main.py
сразу под импортом:
- ПОСЛЕ:
app = Flask(__name__)
В Flask вы инициализируете фреймворк, а затем используете декораторы для определения маршрутов. Кроме того, маршруты связаны с функциями, а не с классами или методами.
Включение руководства по Flask в эту лабораторию кода выходит за рамки, поэтому потратьте некоторое время на изучение руководства по Flask и просмотрите документацию по Flask, чтобы более комфортно работать с платформой.
3. Модель данных
Здесь нет никаких изменений. Datastore будет в центре внимания следующей лаборатории кода.
4. Обработчики
Приложение, независимо от того, какой фреймворк вы используете ( webapp2
или Flask), выполняет 3 вещи:
- Обработка корневого пути (
/
) GET-запросов - Зарегистрируйте веб-страницу «посещение» (создайте/сохраните объект
Visit
) - Отобразить 10 самых последних посещений (с помощью заранее определенного шаблона
index.html
).
Платформа webapp2
использует модель выполнения на основе классов, в которой для каждого поддерживаемого метода HTTP создаются обработчики. В нашем простом случае у нас есть только GET
, поэтому определен метод get()
:
- ДО:
class MainHandler(webapp2.RequestHandler):
def get(self):
store_visit(self.request.remote_addr, self.request.user_agent)
visits = fetch_visits(10) or () # empty sequence if None
tmpl = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(tmpl, {'visits': visits}))
Как упоминалось выше, Flask выполняет собственную маршрутизацию. Вместо класса-обработчика вы пишете функции и украшаете их маршрутом, по которому они должны быть вызваны. Пользователи могут указать методы HTTP, обрабатываемые в вызове декоратора, например @app.route('/app/', methods=['GET', 'POST'])
. Поскольку по умолчанию используется только GET
(и неявно HEAD
), его можно оставить.
При переходе на Flask замените класс MainHandler
и его метод get()
следующей функцией маршрутизации Flask:
- ПОСЛЕ:
@app.route('/')
def root():
store_visit(request.remote_addr, request.user_agent)
visits = fetch_visits(10) or () # empty sequence if None
return render_template('index.html', visits=visits)
Конечно, это не типично для вашего приложения, которое, безусловно, будет более сложным, чем этот образец. Одна из основных целей этих руководств — помочь вам начать работу, нарастить «мышечную память» и понять, где вносить изменения в код, специфичный для App Engine. Чтобы убедиться, что вы внесли это изменение правильно, сравните свое изменение с файлом main.py
из Модуля 1 .
5. Вспомогательные файлы
В файле .gcloudignore
нет никаких изменений. Его цель — указать файлы, которые не нужно развертывать в App Engine, которые не нужны для развертывания и выполнения приложения, включая, помимо прочего, вспомогательные файлы Python, систему контроля версий, шаблон репозитория и другие файлы. Наш .gcloudignore
выглядит так (для краткости комментарии удалены):
.gcloudignore
.git
.gitignore
.hgignore
.hg/
*.pyc
*.pyo
__pycache__/
/setup.cfg
README.md
6. Обновите файл HTML-шаблона.
1. Переместить файл шаблона
В папке базового репозитория (модуль 0) файл шаблона index.html
находится в той же папке, что и файлы приложения. Поскольку Flask требует, чтобы HTML-файлы находились в папке templates
, вам необходимо создать эту папку ( mkdir templates
) и переместить туда index.html
. В POSIX-совместимой системе, такой как Linux или Mac OS X, команды будут такими:
mkdir templates
mv index.html templates
2. Обновить файл шаблона.
После того как вы переместили index.html
в templates
, пришло время внести небольшие, но необходимые изменения. Давайте посмотрим на исходный файл шаблона целиком:
<!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>
</body>
</html>
В то время как webapp2
использует шаблоны Django, которые выполняют вызовы, такие как visit.timestamp.ctime
без круглых скобок ( )
, Jinja2 требует их явно. Хотя это звучит как незначительная настройка, шаблоны Jinja являются более мощными «из коробки», поскольку вы можете передавать аргументы в вызовах.
В Django вам нужно либо создать «тег шаблона», либо написать фильтр. Учитывая это, обновите index.html
, добавив пару круглых скобок к вызову visit.timestamp.ctime
:
- ДО:
<li>{{ visit.timestamp.ctime }} from {{ visit.visitor }}</li>
- ПОСЛЕ:
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
Это единственное необходимое изменение; никаких дополнительных изменений в index.html
для всех остальных кодовых лабораторий миграции не требуется.
7. Подведение итогов/очистка
Развернуть приложение
Когда вы внесете все изменения в этом руководстве, файлы в папке вашего приложения должны быть идентичны (или почти идентичны) файлу в папке репозитория Модуля 1 . Теперь разверните и убедитесь, что ваше приложение Flask модуля 1 работает идентично версии webapp2
модуля 0.
Используйте команду gcloud app deploy
, как мы делали ранее при развертывании исходного кода Модуля 0. Доступ к приложению по адресу PROJECT_ID.appspot.com
через веб-браузер или команду curl
или wget
, чтобы убедиться, что оно работает должным образом.
Если вы получаете какую-то ошибку сервера, это обычно означает какую-то опечатку в вашем коде Python. Просмотрите журналы приложений для расследования. Также сравните ваши файлы с файлами в репозитории Модуля 1 (ссылка чуть выше).
Дополнительно: очистка
А как насчет очистки, чтобы избежать выставления счетов до тех пор, пока вы не будете готовы перейти к следующей лаборатории кода миграции? Как существующие разработчики, вы, вероятно, уже в курсе ценовой информации App Engine .
Необязательно: отключить приложение
Если вы еще не готовы перейти к следующему руководству, отключите приложение , чтобы избежать дополнительных расходов. Когда вы будете готовы перейти к следующей лаборатории кода, вы можете снова включить ее. Пока ваше приложение отключено, оно не будет получать трафик, за который взимается плата, однако вам может быть выставлен счет еще за одну вещь, за которую вы можете получить счет за использование хранилища данных , если оно превышает бесплатную квоту , поэтому удалите достаточно трафика, чтобы попасть под этот лимит.
С другой стороны, если вы не собираетесь продолжать миграцию и хотите полностью удалить все, вы можете закрыть свой проект .
Следующие шаги
Существует два модуля миграции, которые НАЧИНАЮТСЯ с завершенного кода Модуля 1, Модулей 2 и 7:
- Модуль 2 (требуется, если вы используете хранилище данных)
- Миграция с App Engine
ndb
на Cloud NDB - После перехода на Cloud NDB становится доступно множество других опций.
- Контейнеризация вашего приложения для запуска в Cloud Run
- Дальнейший перенос вашего приложения в клиентскую библиотеку Cloud Datastore.
- Перенос вашего приложения в Cloud Firestore для доступа к функциям Firebase.
- Миграция с App Engine
- Модуль 7 (требуется, если вы используете очереди задач [push])
- Добавление использования
taskqueue
App Engine (push) - Подготавливает приложение Модуля 1 к миграции в облачные задачи Модуля 8.
- Добавление использования
8. Дополнительные ресурсы
Проблемы и отзывы о модулях миграции App Engine
Если вы обнаружите какие-либо проблемы с этой кодовой лабораторией, сначала найдите свою проблему, прежде чем подавать заявку. Ссылки для поиска и создания новых задач:
Миграционные ресурсы
Ссылки на папки репозитория для Модуля 0 (НАЧАЛО) и Модуля 1 (ФИНИШ) можно найти в таблице ниже. Доступ к ним также можно получить из репозитория для всех миграций App Engine , которые можно клонировать или загрузить в виде ZIP-файла.
Кодлаб | Питон 2 | Питон 3 |
Модуль 0 | (н/д) | |
Модуль 1 | (н/д) |
Ресурсы App Engine
Ниже приведены дополнительные ресурсы, касающиеся этой конкретной миграции:
- Микровеб-фреймворки Python
- (СТАРОЕ) Переход с Python 2.5 на 2.7 и
webapp
наwebapp2
- Переход на Python 3 и среду выполнения нового поколения GAE
- Общий