Миграция из App Engine Blobstore в облачное хранилище (модуль 16)

1. Обзор

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

В этой лаборатории кода вы узнаете, как перейти с App Engine Blobstore на Cloud Storage . Существуют также неявные миграции из:

Дополнительную пошаговую информацию см. в соответствующих модулях миграции.

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

  • Добавьте использование API/библиотеки App Engine Blobstore.
  • Храните пользовательские загрузки в службе Blobstore.
  • Подготовьтесь к следующему шагу по переходу на Cloud Storage

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

Опрос

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

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

Как бы вы оценили свой опыт работы с Python?

Новичок Средний Опытный

Как бы вы оценили свой опыт использования сервисов Google Cloud?

Новичок Средний Опытный

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

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

Эта миграция требует немного больше усилий по сравнению с другими миграциями из этой серии. Blobstore имеет зависимости от исходной платформы веб-приложений, поэтому в примере приложения используется платформа webapp2 вместо Flask. В этом руководстве рассказывается о миграции в Cloud Storage, Cloud NDB, Flask и Python 3.

Приложение по-прежнему регистрирует «посещения» конечных пользователей и отображает десять самых последних, но в предыдущей кодовой лаборатории (Модуль 15) были добавлены новые функции для использования в Blobstore: приложение предлагает конечным пользователям загрузить артефакт (файл), соответствующий их «посещение». Пользователи могут сделать это или выбрать «пропустить», чтобы отказаться. Независимо от решения пользователя, следующая страница отображает тот же результат, что и предыдущие версии этого приложения, отображая самые последние посещения. Еще одна особенность заключается в том, что посещения с соответствующими артефактами содержат ссылку «Просмотр» для отображения артефакта посещения. Эта лаборатория кода реализует упомянутые ранее миграции, сохраняя при этом описанную функциональность.

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

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

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

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

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

Одним из обязательных условий для этой лаборатории кода является наличие рабочего примера приложения Модуля 15. Если у вас его нет, вы можете получить его из папки «СТАРТ» Модуля 15 (ссылка ниже). Эта лаборатория кода проведет вас через каждый шаг, завершая кодом, похожим на тот, что находится в папке «FINISH» модуля 16.

Каталог файлов запуска модуля 15 должен выглядеть следующим образом:

$ ls
README.md       app.yaml        main-gcs.py     main.py         templates

Файл main-gcs.py — это альтернативная версия main.py из модуля 15, позволяющая выбрать сегмент облачного хранилища, отличный от URL-адреса, назначенного приложению по умолчанию на основе идентификатора проекта: PROJECT_ID .appspot.com . Этот файл не играет никакой роли в этой кодовой лаборатории (Модуль 16), за исключением того, что при желании к этому файлу можно применить аналогичные методы миграции.

3. (Повторное) развертывание базового приложения.

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

  1. Повторно ознакомьтесь с инструментом командной строки gcloud
  2. Повторно разверните пример приложения с помощью gcloud app deploy
  3. Убедитесь, что приложение работает на App Engine без проблем.

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

f5b5f9f19d8ae978.png

Как только пользователи загружают файл или пропускают его, приложение отображает знакомую страницу «последние посещения»:

f5ac6b98ee8a34cb.png

Посещения с артефактом будут иметь ссылку «Просмотр» справа от отметки времени посещения для отображения (или загрузки) артефакта. Как только вы подтвердите функциональность приложения, вы будете готовы перейти от устаревших сервисов App Engine (webapp2, NDB, Blobstore) к современным альтернативам (Flask, Cloud NDB, Cloud Storage).

4. Обновите файлы конфигурации.

Для обновленной версии нашего приложения вступают в действие три файла конфигурации. Обязательными задачами являются:

  1. Обновите необходимые встроенные сторонние библиотеки в app.yaml , а также оставьте возможность перехода на Python 3.
  2. Добавьте requirements.txt , в котором указаны все необходимые библиотеки, которые не являются встроенными.
  3. Добавьте appengine_config.py , чтобы приложение поддерживало как встроенные, так и невстроенные сторонние библиотеки.

app.yaml

Отредактируйте файл app.yaml , обновив раздел libraries . Удалите jinja2 и добавьте grpcio , setuptools и ssl . Выберите последнюю версию, доступную для всех трех библиотек. Также добавьте директиву runtime Python 3, но закомментируйте. Когда вы закончите, это должно выглядеть так (если вы выбрали Python 3.9):

ДО:

runtime: python27
threadsafe: yes
api_version: 1

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

libraries:
- name: jinja2
  version: latest

ПОСЛЕ:

#runtime: python39
runtime: python27
threadsafe: yes
api_version: 1

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

libraries:
- name: grpcio
  version: latest
- name: setuptools
  version: latest
- name: ssl
  version: latest

Изменения в основном касаются встроенных библиотек Python 2, доступных на серверах App Engine (поэтому вам не придется собирать их самостоятельно). Мы удалили Jinja2, поскольку он поставляется с Flask, который мы собираемся добавить в reqs.txt. Всякий раз, когда используются клиентские библиотеки Google Cloud, например библиотеки для Cloud NDB и Cloud Storage, необходимы grpcio и setuptools. Наконец, самому Cloud Storage требуется библиотека SSL. Закомментированная директива времени выполнения вверху предназначена для случаев, когда вы готовы перенести это приложение на Python 3. Мы рассмотрим эту тему в конце этого руководства.

требования.txt

Добавьте файл requirements.txt , для которого требуется платформа Flask, а также клиентские библиотеки Cloud NDB и Cloud Storage, ни одна из которых не является встроенной. Создайте файл с таким содержимым:

flask
google-cloud-ndb
google-cloud-storage

Среда выполнения Python 2 App Engine требует самостоятельной сборки невстроенных сторонних библиотек, поэтому выполните следующую команду, чтобы установить эти библиотеки в папку lib:

pip install -t lib -r requirements.txt

Если на вашей машине разработки установлены Python 2 и 3, возможно, вам придется использовать команду pip2, чтобы обеспечить получение версий этих библиотек для Python 2. После обновления до Python 3 вам больше не потребуется выполнять сборку самостоятельно.

appengine_config.py

Добавьте файл appengine_config.py поддерживающий встроенные и невстроенные сторонние библиотеки. Создайте файл с таким содержимым:

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)

Только что выполненные шаги должны быть аналогичны или идентичны шагам, перечисленным в разделе «Установка библиотек для приложений Python 2» документации App Engine, а точнее, содержимое файла appengine_config.py должно соответствовать тому, что указано в шаге 5.

Работа над конфигурационными файлами завершена, перейдем к приложению.

5. Измените файлы приложения.

Импорт

Первый набор изменений для main.py включает в себя замену всего заменяемого материала. Вот что меняется:

  1. webapp2 заменяется Flask
  2. Вместо использования Jinja2 из webapp2_extras используйте Jinja2, поставляемый с Flask.
  3. App Engine Blobstore и NDB заменяются Cloud NDB и Cloud Storage.
  4. Обработчики Blobstore в webapp заменены комбинацией модуля стандартной библиотеки io , утилит Flask и werkzeug
  5. По умолчанию Blobstore записывает данные в корзину Cloud Storage, имя которой соответствует URL-адресу вашего приложения ( PROJECT_ID.appspot.com ). Поскольку мы переносим в клиентскую библиотеку Cloud Storage, google.auth используется для получения идентификатора проекта и указания точно такого же имени корзины. (Вы можете изменить имя корзины, поскольку оно больше не запрограммировано жестко.)

ДО:

import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers

Внесите изменения в приведенном выше списке, заменив текущий раздел импорта в main.py приведенным ниже фрагментом кода.

ПОСЛЕ:

import io

from flask import (Flask, abort, redirect, render_template,
        request, send_file, url_for)
from werkzeug.utils import secure_filename

import google.auth
from google.cloud import exceptions, ndb, storage

Инициализация и ненужная поддержка Jinja2

Следующий блок кода, который нужно заменить, — это BaseHandler , определяющий использование Jinja2 из webapp2_extras . В этом нет необходимости, поскольку Jinja2 поставляется с Flask и является его шаблонизатором по умолчанию, поэтому удалите его.

На стороне Модуля 16 создайте экземпляры объектов, которых у нас не было в старом приложении. Это включает в себя инициализацию приложения Flask и создание клиентов API для Cloud NDB и Cloud Storage. Наконец, мы собираем имя сегмента Cloud Storage, как описано выше в разделе импорта. Вот до и после внедрения этих обновлений:

ДО:

class BaseHandler(webapp2.RequestHandler):
    'Derived request handler mixing-in Jinja2 support'
    @webapp2.cached_property
    def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

    def render_response(self, _template, **context):
        self.response.write(self.jinja2.render_template(_template, **context))

ПОСЛЕ:

app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID

Обновить доступ к хранилищу данных

Cloud NDB в основном совместим с App Engine NDB. Одно из уже рассмотренных отличий — это необходимость в клиенте API. Другой вариант заключается в том, что последний требует, чтобы доступ к хранилищу данных контролировался диспетчером контекста Python клиента API. По сути, это означает, что все вызовы доступа к хранилищу данных с использованием клиентской библиотеки Cloud NDB могут выполняться только внутри Python with блоками.

Это одно изменение; во-вторых, Blobstore и его объекты, например BlobKey , не поддерживаются Cloud Storage, поэтому вместо этого измените file_blob на ndb.StringProperty . Ниже приведен класс модели данных и обновленные функции store_visit() и fetch_visits() , отражающие эти изменения:

ДО:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)
    file_blob = ndb.BlobKeyProperty()

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

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

ПОСЛЕ:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)
    file_blob = ndb.StringProperty()

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

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

Вот графическое представление изменений, которые были внесены на данный момент:

a8f74ca392275822.png

Обновление обработчиков

Обработчик загрузки

Обработчики в webapp2 — это классы, а в Flask — функции. Вместо метода HTTP-глагола Flask использует глагол для украшения функции. Blobstore и его обработчики webapp заменены функциями Cloud Storage, а также Flask и его утилит:

ДО:

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    'Upload blob (POST) handler'
    def post(self):
        uploads = self.get_uploads()
        blob_id = uploads[0].key() if uploads else None
        store_visit(self.request.remote_addr, self.request.user_agent, blob_id)
        self.redirect('/', code=307)

ПОСЛЕ:

@app.route('/upload', methods=['POST'])
def upload():
    'Upload blob (POST) handler'
    fname = None
    upload = request.files.get('file', None)
    if upload:
        fname = secure_filename(upload.filename)
        blob = gcs_client.bucket(BUCKET).blob(fname)
        blob.upload_from_file(upload, content_type=upload.content_type)
    store_visit(request.remote_addr, request.user_agent, fname)
    return redirect(url_for('root'), code=307)

Некоторые примечания относительно этого обновления:

  • Вместо blob_id файловые артефакты теперь идентифицируются по имени файла ( fname ), если оно присутствует, и None в противном случае (пользователь отказался от загрузки файла).
  • Обработчики Blobstore отделяют процесс загрузки от пользователей, а Cloud Storage этого не делает, поэтому вы можете увидеть недавно добавленный код, который устанавливает объект BLOB-объекта и местоположение файла (корзину), а также вызов, выполняющий фактическую загрузку. ( upload_from_file() ).
  • webapp2 использует таблицу маршрутизации в нижней части файла приложения, а маршруты Flask находятся в каждом декорированном обработчике.
  • Оба обработчика завершают свою функциональность путем перенаправления на дом ( / ), сохраняя при этом запрос POST с кодом возврата HTTP 307.

Обработчик загрузки

Обновление обработчика загрузки происходит по той же схеме, что и обработчик загрузки, только здесь гораздо меньше кода, на который нужно смотреть. Замените функциональность Blobstore и webapp эквивалентами Cloud Storage и Flask:

ДО:

class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler):
    'view uploaded blob (GET) handler'
    def get(self, blob_key):
        self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404)

ПОСЛЕ:

@app.route('/view/<path:fname>')
def view(fname):
    'view uploaded blob (GET) handler'
    blob = gcs_client.bucket(BUCKET).blob(fname)
    try:
        media = blob.download_as_bytes()
    except exceptions.NotFound:
        abort(404)
    return send_file(io.BytesIO(media), mimetype=blob.content_type)

Примечания к этому обновлению:

  • Опять же, Flask украшает функции-обработчики своим маршрутом, в то время как webapp делает это в таблице маршрутизации внизу, поэтому распознайте синтаксис сопоставления шаблонов последнего ('/view/([^/]+)?' ) и Flask ( '/view/<path:fname>' ).
  • Как и в случае с обработчиком загрузки, на стороне облачного хранилища требуется немного больше работы для функциональности, абстрагируемой обработчиками Blobstore, а именно идентификация рассматриваемого файла (BLOB-объекта) и явная загрузка двоичного файла по сравнению с единственным методом send_blob() обработчика Blobstore. вызов.
  • В обоих случаях пользователю возвращается ошибка HTTP 404, если артефакт не найден.

Главный обработчик

Окончательные изменения основного приложения происходят в главном обработчике. Методы HTTP-глагола webapp2 заменяются одной функцией, объединяющей их функциональность. Замените класс MainHandler функцией root() и удалите таблицу маршрутизации webapp2 , как показано ниже:

ДО:

class MainHandler(BaseHandler):
    'main application (GET/POST) handler'
    def get(self):
        self.render_response('index.html',
                upload_url=blobstore.create_upload_url('/upload'))

    def post(self):
        visits = fetch_visits(10)
        self.render_response('index.html', visits=visits)

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/upload', UploadHandler),
    ('/view/([^/]+)?', ViewBlobHandler),
], debug=True)

ПОСЛЕ:

@app.route('/', methods=['GET', 'POST'])
def root():
    'main application (GET/POST) handler'
    context = {}
    if request.method == 'GET':
        context['upload_url'] = url_for('upload')
    else:
        context['visits'] = fetch_visits(10)
    return render_template('index.html', **context)

Вместо отдельных методов get() и post() они, по сути, представляют собой оператор if-else в root() . Кроме того, поскольку root() — это одна функция, существует только один вызов для визуализации шаблона как для GET , так и POST , тогда как в webapp2 это практически невозможно.

Вот графическое представление второго и последнего набора изменений в main.py :

5ec38818c32fec2.png

(опционально) «Улучшение» обратной совместимости

Таким образом, решение, созданное выше, работает отлично... но только если вы начинаете с нуля и у вас нет файлов, созданных Blobstore. Поскольку мы обновили приложение, чтобы оно идентифицировало файлы по имени файла вместо BlobKey , готовое приложение Модуля 16 в исходном виде не сможет просматривать файлы Blobstore. Другими словами, при выполнении этой миграции мы внесли обратно несовместимое изменение. Теперь мы представляем альтернативную версию main.py под названием main-migrate.py (находится в репозитории), которая пытается устранить этот пробел.

Первым «расширением» для поддержки файлов, созданных в Blobstore, является модель данных, имеющая свойство BlobKeyProperty (в дополнение к StringProperty для файлов, созданных в Cloud Storage):

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)
    file_blob = ndb.BlobKeyProperty()  # backwards-compatibility
    file_gcs  = ndb.StringProperty()

Свойство file_blob будет использоваться для идентификации файлов, созданных в Blobstore, а свойство file_gcs — для файлов облачного хранилища. Теперь при создании новых посещений явно сохраняйте значение в file_gcs вместо file_blob , поэтому store_visit выглядит немного иначе:

ДО:

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

ПОСЛЕ:

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

При получении последних посещений «нормализуйте» данные перед отправкой их в шаблон:

ДО:

@app.route('/', methods=['GET', 'POST'])
def root():
    'main application (GET/POST) handler'
    context = {}
    if request.method == 'GET':
        context['upload_url'] = url_for('upload')
    else:
        context['visits'] = fetch_visits(10)
    return render_template('index.html', **context)

ПОСЛЕ:

@app.route('/', methods=['GET', 'POST'])
def root():
    'main application (GET/POST) handler'
    context = {}
    if request.method == 'GET':
        context['upload_url'] = url_for('upload')
    else:
        context['visits'] = etl_visits(fetch_visits(10))
    return render_template('index.html', **context)

Затем подтвердите существование file_blob или file_gcs (или ни того, ни другого). Если файл доступен, выберите тот, который существует, и используйте этот идентификатор ( BlobKey для файлов, созданных в Blobstore, или имя файла для файлов, созданных в Cloud Storage). Когда мы говорим «файлы, созданные в Cloud Storage», мы имеем в виду файлы, созданные с использованием клиентской библиотеки Cloud Storage. Blobstore также записывает данные в Cloud Storage, но в данном случае это будут файлы, созданные Blobstore.

Теперь, что более важно, что это за функция etl_visits() , которая используется для нормализации или ETL (извлечения, преобразования и загрузки) данных для конечного пользователя? Это выглядит так:

def etl_visits(visits):
    return [{
            'visitor': v.visitor,
            'timestamp': v.timestamp,
            'file_blob': v.file_gcs if hasattr(v, 'file_gcs') \
                    and v.file_gcs else v.file_blob
            } for v in visits]

Вероятно, это выглядит так, как вы ожидали: код проходит через все посещения и для каждого посещения дословно принимает данные о посетителе и метке времени, затем проверяет, существует ли file_gcs или file_blob , и если да, выбирает один из них (или None , если ни того, ни другого не существует).

Вот иллюстрация различий между main.py и main-migrate.py :

718b05b2adadb2e1.png

Если вы начинаете с нуля без файлов, созданных в Blobstore, используйте main.py , но если вы переходите и хотите поддерживать файлы, созданные как в Blobstore , так и в Cloud Storage, ознакомьтесь с main-migrate.py как примером того, как действовать. со сценарием, который поможет вам спланировать миграцию для ваших собственных приложений. При выполнении сложных миграций, вероятно, возникнут особые случаи, поэтому этот пример призван показать большую близость к модернизации реальных приложений с реальными данными.

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

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

Развертывание и проверка приложения

Перед повторным развертыванием приложения обязательно запустите pip install -t lib -r requirements.txt чтобы получить эти самоустанавливающиеся сторонние библиотеки в папке lib. Если вы хотите запустить обратно совместимое решение, сначала переименуйте main-migrate.py в main.py Теперь запустите gcloud app deploy и убедитесь, что приложение работает идентично приложению Модуля 15. Экран формы выглядит следующим образом:

f5b5f9f19d8ae978.png

Страница последних посещений выглядит следующим образом:

f5ac6b98ee8a34cb.png

Поздравляем с завершением этой лабораторной работы по замене App Engine Blobstore на Cloud Storage, App Engine NDB на Cloud NDB и webapp2 на Flask. Теперь ваш код должен соответствовать тому, что находится в папке FINISH (Модуль 16) . Альтернативный main-migrate.py также присутствует в этой папке.

Python 3 «миграция»

Закомментированная директива runtime Python 3 в верхней части app.yaml — это все, что нужно для переноса этого приложения на Python 3. Сам исходный код уже совместим с Python 3, поэтому никаких изменений в нем не требуется. Чтобы развернуть это как приложение Python 3, выполните следующие шаги:

  1. Раскомментируйте директиву runtime Python 3 в верхней части файла app.yaml .
  2. Удалите все остальные строки в app.yaml .
  3. Удалите файл appengine_config.py . (не используется во время выполнения Python 3)
  4. Удалите папку lib , если она существует. (необязательно для среды выполнения Python 3)

Очистить

Общий

Если вы закончили, мы рекомендуем вам отключить приложение App Engine , чтобы избежать выставления счетов. Однако, если вы хотите протестировать или поэкспериментировать еще, на платформе App Engine предусмотрена бесплатная квота , поэтому, пока вы не превысите этот уровень использования, с вас не будет взиматься плата. Это касается вычислений, но за соответствующие службы App Engine также может взиматься плата, поэтому для получения дополнительной информации посетите страницу с ценами . Если эта миграция включает в себя другие облачные службы, они оплачиваются отдельно. В любом случае, если применимо, см. раздел «Специально для этой кодовой лаборатории» ниже.

Для полной информации: развертывание на бессерверной вычислительной платформе Google Cloud, такой как App Engine, требует незначительных затрат на сборку и хранение . Cloud Build имеет собственную бесплатную квоту, как и 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 », если ваше приложение размещено в США.

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

Специально для этой кодовой лаборатории

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

Обратите внимание: если вы перешли с модуля 15 на модуль 16, ваши данные по-прежнему будут храниться в Blobstore, поэтому мы включили информацию о ценах выше.

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

Помимо этого руководства, следует рассмотреть и другие модули миграции, направленные на отказ от устаревших комплексных услуг:

  • Модуль 2. Переход с App Engine ndb на Cloud NDB.
  • Модули 7–9 : переход от push-задач из очереди задач App Engine в облачные задачи.
  • Модули 12–13 : миграция с App Engine Memcache на Cloud Memorystore.
  • Модули 18–19 : переход из очереди задач App Engine (задачи по запросу) в Cloud Pub/Sub.

App Engine больше не является единственной бессерверной платформой в Google Cloud. Если у вас есть небольшое приложение App Engine или приложение с ограниченной функциональностью, и вы хотите превратить его в автономный микросервис, или вы хотите разбить монолитное приложение на несколько повторно используемых компонентов, это веские причины рассмотреть возможность перехода на облачные функции . Если контейнеризация стала частью вашего рабочего процесса разработки приложений, особенно если он состоит из конвейера CI/CD (непрерывная интеграция/непрерывная доставка или развертывание), рассмотрите возможность перехода на Cloud Run . Эти сценарии рассматриваются в следующих модулях:

  • Миграция с App Engine на облачные функции: см. Модуль 11.
  • Миграция с App Engine на Cloud Run: см. Модуль 4 , чтобы контейнеризировать приложение с помощью Docker, или Модуль 5 , чтобы сделать это без контейнеров, знаний Docker или Dockerfile s.

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

Независимо от того, какой модуль миграции вы рассматриваете следующим, весь контент Serverless Migration Station (лаборатории кода, видео, исходный код [при наличии]) можно получить в его репозитории с открытым исходным кодом . README репозитория также содержит рекомендации о том, какие миграции следует учитывать, а также любой соответствующий «порядок» модулей миграции.

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

Проблемы с Codelab/отзывы

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

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

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

Кодлаб

Питон 2

Питон 3

Модуль 15

код

Н/Д

Модуль 16 (эта кодовая лаборатория)

код

(то же, что и Python 2)

Интернет-ресурсы

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

Магазин Blobstore App Engine и облачное хранилище

Платформа App Engine

Другая информация об облаке

Питон

Видео

Лицензия

Эта работа распространяется под лицензией Creative Commons Attribution 2.0 Generic License.