1. Übersicht
Die Codelab-Reihe „Serverless Migration Station“ (praktische Anleitungen im eigenen Tempo) und die zugehörigen Videos sollen Entwicklern von serverlosen Google Cloud-Anwendungen helfen, ihre Anwendungen zu modernisieren. Dazu werden sie durch eine oder mehrere Migrationen geführt, bei denen sie sich hauptsächlich von Legacy-Diensten verabschieden. Dadurch werden Ihre Anwendungen portabler und Sie erhalten mehr Optionen und Flexibilität. So können Sie eine größere Auswahl an Cloud-Produkten einbinden und darauf zugreifen und einfacher auf neuere Sprachversionen upgraden. Diese Reihe richtet sich zwar an die ersten Cloud-Nutzer, hauptsächlich Entwickler der App Engine (Standardumgebung), ist aber breit genug gefächert, um auch andere serverlose Plattformen wie Cloud Functions und Cloud Run oder andere Plattformen abzudecken.
In diesem Codelab zu Modul 15 wird erläutert, wie Sie die App Engine-blobstore-Nutzung zur Beispiel-App aus Modul 0 hinzufügen. Anschließend können Sie in Modul 16 diese Nutzung zu Cloud Storage migrieren.
Lerninhalte:
- Verwendung der App Engine Blobstore API/Bibliothek hinzufügen
- Nutzer-Uploads im Dienst
blobstorespeichern - Nächsten Schritt zur Migration zu Cloud Storage vorbereiten
Voraussetzungen
- Ein Google Cloud Platform-Projekt mit einem aktiven GCP-Rechnungskonto
- Grundlegende Python-Kenntnisse
- Kenntnisse gängiger Linux-Befehle
- Grundkenntnisse zur Entwicklung und Bereitstellung von App Engine-Anwendungen
- Eine funktionierende App Engine-Anwendung aus Modul 0 (aus dem Repository abrufen)
Umfrage
Wie möchten Sie diese Anleitung verwenden?
Wie würden Sie Ihre Erfahrung mit Python bewerten?
Wie würden Sie Ihre Erfahrungen mit Google Cloud-Diensten bewerten?
2. Hintergrund
Wenn Sie von der App Engine Blobstore API migrieren möchten, fügen Sie die Verwendung der API der vorhandenen App Engine-Referenzanwendung ndb aus Modul 0 hinzu. In der Beispiel-App werden die zehn letzten Besuche des Nutzers angezeigt. Wir ändern die App so, dass der Endnutzer aufgefordert wird, ein Artefakt (eine Datei) hochzuladen, das seinem „Besuch“ entspricht. Wenn der Nutzer dies nicht möchte, kann er die Option „Überspringen“ auswählen. Unabhängig von der Entscheidung des Nutzers wird auf der nächsten Seite dieselbe Ausgabe wie in der Anwendung aus Modul 0 (und vielen anderen Modulen in dieser Reihe) gerendert. Nachdem diese App Engine-blobstore-Integration implementiert wurde, können wir sie im nächsten Codelab (Modul 16) zu Cloud Storage migrieren.
App Engine bietet Zugriff auf die Vorlagensysteme Django und Jinja2. Ein Unterschied dieses Beispiels (neben dem Hinzufügen des Blobstore-Zugriffs) besteht darin, dass hier in Modul 15 von Django in Modul 0 zu Jinja2 gewechselt wird. Ein wichtiger Schritt bei der Modernisierung von App Engine-Anwendungen ist die Migration von Web-Frameworks von webapp2 zu Flask. Letzteres verwendet Jinja2 als Standardvorlagensystem. Wir beginnen also mit der Implementierung von Jinja2, bleiben aber für den Blobstore-Zugriff bei webapp2. Da Flask standardmäßig Jinja2 verwendet, sind in Modul 16 keine Änderungen an der Vorlage erforderlich.
3. Einrichtung/Vorbereitung
Bevor wir zum Hauptteil der Anleitung kommen, richten Sie Ihr Projekt ein, rufen Sie den Code ab und stellen Sie die Baseline-Anwendung bereit, um mit funktionierendem Code zu beginnen.
1. Projekt einrichten
Wenn Sie die Anwendung aus Modul 0 bereits bereitgestellt haben, empfehlen wir, dasselbe Projekt (und denselben Code) wiederzuverwenden. Alternativ können Sie ein neues Projekt erstellen oder ein anderes vorhandenes Projekt verwenden. Achten Sie darauf, dass das Projekt ein aktives Rechnungskonto hat und App Engine aktiviert ist.
2. Beispiel-App für die Baseline abrufen
Eine der Voraussetzungen für dieses Codelab ist eine funktionierende Beispiel-App aus Modul 0. Wenn Sie diese nicht haben, können Sie sie aus dem Ordner „START“ von Modul 0 herunterladen (Link unten). In diesem Codelab werden Sie durch die einzelnen Schritte geführt. Am Ende erhalten Sie Code, der dem im Ordner „FINISH“ von Modul 15 ähnelt.
- START: Ordner „Modul 0“ (Python 2)
- FERTIG: Ordner für Modul 15 (Python 2)
- Gesamtes Repository (zum Klonen oder Herunterladen der ZIP-Datei)
Das Verzeichnis der START-Dateien von Modul 0 sollte so aussehen:
$ ls README.md index.html app.yaml main.py
3. Baseline-Anwendung (neu) bereitstellen
Die verbleibenden Vorbereitungsschritte, die Sie jetzt ausführen müssen:
- Machen Sie sich noch einmal mit dem
gcloud-Befehlszeilentool vertraut. - Beispiel-App mit
gcloud app deploynoch einmal bereitstellen - Prüfen, ob die Anwendung ohne Probleme in App Engine ausgeführt wird
Wenn Sie diese Schritte erfolgreich ausgeführt haben und Ihre Webanwendung funktioniert (mit einer Ausgabe ähnlich der unten stehenden), können Sie Ihrer Anwendung Caching hinzufügen.

4. Konfigurationsdateien aktualisieren
app.yaml
Es gibt keine wesentlichen Änderungen an der Anwendungskonfiguration. Wie bereits erwähnt, wechseln wir jedoch von Django-Vorlagen (Standard) zu Jinja2. Um zu wechseln, sollten Nutzer die aktuelle Version von Jinja2 angeben, die auf App Engine-Servern verfügbar ist. Dazu fügen Sie sie dem Abschnitt für integrierte Drittanbieterbibliotheken von app.yaml hinzu.
VORHER:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Bearbeiten Sie die Datei app.yaml, indem Sie einen neuen libraries-Abschnitt hinzufügen, wie hier gezeigt:
DANACH:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
Es müssen keine weiteren Konfigurationsdateien aktualisiert werden. Kommen wir also zu den Anwendungsdateien.
5. Anwendungsdateien ändern
Importe und Jinja2-Unterstützung
Die ersten Änderungen für main.py umfassen die Verwendung der Blobstore API und das Ersetzen von Django-Vorlagen durch Jinja2. Folgendes wird sich ändern:
- Das Modul
osdient dazu, einen Dateipfadnamen zu einer Django-Vorlage zu erstellen. Da wir zu Jinja2 wechseln, wo dies erledigt wird, sind die Verwendung vonossowie der Django-Vorlagen-Renderergoogle.appengine.ext.webapp.templatenicht mehr erforderlich und werden daher entfernt. - Importieren Sie die Blobstore API:
google.appengine.ext.blobstore - Importieren Sie die Blobstore-Handler aus dem ursprünglichen
webapp-Framework. Sie sind inwebapp2nicht verfügbar:google.appengine.ext.webapp.blobstore_handlers - Importieren Sie die Jinja2-Unterstützung aus dem Paket
webapp2_extras.
VORHER:
import os
import webapp2
from google.appengine.ext import ndb
from google.appengine.ext.webapp import template
Implementieren Sie die Änderungen in der obigen Liste, indem Sie den aktuellen Importabschnitt in main.py durch das folgende Code-Snippet ersetzen.
DANACH:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
Fügen Sie nach den Importen Boilerplate-Code hinzu, um die Verwendung von Jinja2 gemäß der webapp2_extras-Dokumentation zu unterstützen. Im folgenden Code-Snippet wird die Standard-Anfrage-Handler-Klasse von webapp2 mit Jinja2-Funktionen umschlossen. Fügen Sie diesen Codeblock also direkt nach den Importen in main.py ein:
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))
Blobstore-Unterstützung hinzufügen
Im Gegensatz zu anderen Migrationen in dieser Reihe, bei denen die Funktionalität oder Ausgabe der Beispiel-App ohne (große) Änderungen an der UX identisch (oder fast identisch) bleibt, weicht dieses Beispiel radikaler von der Norm ab. Anstatt sofort einen neuen Besuch zu registrieren und dann die letzten zehn anzuzeigen, aktualisieren wir die Anwendung so, dass der Nutzer nach einem Dateiartefakt gefragt wird, mit dem er seinen Besuch registrieren kann. Endnutzer können dann entweder eine entsprechende Datei hochladen oder „Überspringen“ auswählen, um nichts hochzuladen. Nach Abschluss dieses Schritts wird die Seite „Letzte Besuche“ angezeigt.
Durch diese Änderung kann unsere Anwendung den Blobstore-Dienst verwenden, um dieses Bild oder einen anderen Dateityp auf der Seite mit den letzten Besuchen zu speichern (und möglicherweise später zu rendern).
Datenmodell aktualisieren und seine Verwendung implementieren
Wir speichern mehr Daten, insbesondere aktualisieren wir das Datenmodell, um die ID (als „BlobKey“ bezeichnet) der in Blobstore hochgeladenen Datei zu speichern, und fügen einen Verweis hinzu, um sie in store_visit() zu speichern. Da diese zusätzlichen Daten zusammen mit allen anderen Daten bei der Abfrage zurückgegeben werden, bleibt fetch_visits() unverändert.
Hier ist ein Vorher-Nachher-Vergleich mit diesen Updates, die file_blob, ein ndb.BlobKeyProperty, enthalten:
VORHER:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
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 Visit.query().order(-Visit.timestamp).fetch(limit)
DANACH:
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)
Hier ist eine bildliche Darstellung der bisher vorgenommenen Änderungen:

Datei-Uploads unterstützen
Die wichtigste Änderung bei der Funktionalität ist die Unterstützung von Dateiuploads, unabhängig davon, ob der Nutzer aufgefordert wird, eine Datei hochzuladen, die Funktion „Überspringen“ unterstützt wird oder eine Datei gerendert wird, die einem Besuch entspricht. All das ist Teil des Bildes. Diese Änderungen sind erforderlich, um Dateiuploads zu unterstützen:
- Die Anfrage
GETdes Haupt-Handlers ruft nicht mehr die letzten Besuche zur Anzeige ab. Stattdessen wird der Nutzer aufgefordert, eine Datei hochzuladen. - Wenn ein Endnutzer eine Datei zum Hochladen einreicht oder diesen Vorgang überspringt, wird die Kontrolle über ein
POSTaus dem Formular an das neueUploadHandlerübergeben, das vongoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandlerabgeleitet ist. - Die Methode
POSTvonUploadHandlerführt den Upload durch, ruftstore_visit()auf, um den Besuch zu registrieren, und löst eine HTTP 307-Weiterleitung aus, um den Nutzer zurück zu „/“ zu leiten, wo… - Die Methode
POSTdes Haupthandlers fragt die letzten Besuche ab (überfetch_visits()) und zeigt sie an. Wenn der Nutzer „Überspringen“ auswählt, wird keine Datei hochgeladen, aber der Besuch wird trotzdem registriert, gefolgt von derselben Weiterleitung. - In der Anzeige der letzten Besuche gibt es ein neues Feld, das dem Nutzer angezeigt wird. Wenn eine Upload-Datei verfügbar ist, wird ein Hyperlink „Ansehen“ angezeigt, andernfalls „Keine“. Diese Änderungen werden in der HTML-Vorlage zusammen mit einem Uploadformular umgesetzt (weitere Informationen dazu folgen demnächst).
- Wenn ein Endnutzer auf den Link „Ansehen“ für einen Besuch mit einem hochgeladenen Video klickt, wird eine
GET-Anfrage an eine neueViewBlobHandlergesendet, die vongoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandlerabgeleitet ist. Wenn es sich um ein Bild handelt, wird die Datei gerendert (im Browser, falls unterstützt). Wenn nicht, wird der Nutzer zum Herunterladen aufgefordert. Wenn die Datei nicht gefunden wird, wird ein HTTP-404-Fehler zurückgegeben. - Zusätzlich zu den neuen Handler-Klassen und den neuen Routen, über die Traffic an sie gesendet wird, benötigt der Haupthandler eine neue
POST-Methode, um die oben beschriebene 307-Weiterleitung zu empfangen.
Vor diesen Updates hatte die App aus Modul 0 nur einen Haupthandler mit einer GET-Methode und einer einzelnen Route:
VORHER:
class MainHandler(webapp2.RequestHandler):
'main application (GET) handler'
def get(self):
store_visit(self.request.remote_addr, self.request.user_agent)
visits = fetch_visits(10)
tmpl = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(tmpl, {'visits': visits}))
app = webapp2.WSGIApplication([
('/', MainHandler),
], debug=True)
Nachdem diese Aktualisierungen implementiert wurden, gibt es jetzt drei Handler: 1) Upload-Handler mit einer POST-Methode, 2) Download-Handler „Blob ansehen“ mit einer GET-Methode und 3) Haupt-Handler mit GET- und POST-Methoden. Nehmen Sie diese Änderungen vor, damit der Rest Ihrer App jetzt wie unten dargestellt aussieht.
DANACH:
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)
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)
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)
Der soeben hinzugefügte Code enthält mehrere wichtige Aufrufe:
- In
MainHandler.getgibt es einen Aufruf vonblobstore.create_upload_url. Dieser Aufruf generiert die URL, an die das FormularPOSTwird. Dabei wird der Upload-Handler aufgerufen, um die Datei an Blobstore zu senden. - In
UploadHandler.postwirdblobstore_handlers.BlobstoreUploadHandler.get_uploadsaufgerufen. Dadurch wird die Datei in Blobstore abgelegt und eine eindeutige und persistente ID für diese Datei zurückgegeben, ihrBlobKey. - In
ViewBlobHandler.getführt der Aufruf vonblobstore_handlers.BlobstoreDownloadHandler.sendmit derBlobKeyeiner Datei dazu, dass die Datei abgerufen und an den Browser des Endnutzers weitergeleitet wird.
Diese Aufrufe machen den Großteil des Zugriffs auf die Funktionen aus, die der App hinzugefügt wurden. Hier ist eine bildliche Darstellung dieser zweiten und letzten Gruppe von Änderungen an main.py:

HTML-Vorlage aktualisieren
Einige der Aktualisierungen der Hauptanwendung wirken sich auf die Benutzeroberfläche der App aus. Daher sind entsprechende Änderungen in der Webvorlage erforderlich, und zwar zwei:
- Es ist ein Formular zum Hochladen von Dateien mit drei Eingabeelementen erforderlich: eine Datei und zwei Schaltflächen zum Senden, eine zum Hochladen der Datei und eine zum Überspringen.
- Aktualisieren Sie die Ausgabe der letzten Besuche, indem Sie einen Link „Ansehen“ für Besuche mit einem entsprechenden Dateiupload oder andernfalls „Keine“ hinzufügen.
VORHER:
<!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>
Implementieren Sie die Änderungen in der Liste oben, um die aktualisierte Vorlage zu erstellen:
DANACH:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
{% if upload_url %}
<h3>Welcome... upload a file? (optional)</h3>
<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
<input type="file" name="file"><p></p>
<input type="submit"> <input type="submit" value="Skip">
</form>
{% else %}
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }}
<i><code>
{% if visit.file_blob %}
(<a href="/view/{{ visit.file_blob }}" target="_blank">view</a>)
{% else %}
(none)
{% endif %}
</code></i>
from {{ visit.visitor }}
</li>
{% endfor %}
</ul>
{% endif %}
</body>
</html>
Diese Abbildung veranschaulicht die erforderlichen Aktualisierungen für index.html:

Eine letzte Änderung ist, dass Jinja2 seine Vorlagen in einem templates-Ordner bevorzugt. Erstellen Sie also diesen Ordner und verschieben Sie index.html dorthin. Mit diesem letzten Schritt haben Sie alle erforderlichen Änderungen vorgenommen, um die Verwendung von Blobstore in der Beispiel-App von Modul 0 zu ermöglichen.
(Optional) Cloud Storage-„Erweiterung“
Blobstore-Speicher wurde schließlich zu Cloud Storage. Das bedeutet, dass Blobstore-Uploads in der Cloud Console, insbesondere im Cloud Storage-Browser, sichtbar sind. Die Frage ist nur, wo. Die Antwort ist der standardmäßige Cloud Storage-Bucket Ihrer App Engine-Anwendung. Der Name ist der vollständige Domainname Ihrer App Engine-Anwendung, PROJECT_ID.appspot.com. Das ist sehr praktisch, da alle Projekt-IDs eindeutig sind.
Die Aktualisierungen der Beispielanwendung legen hochgeladene Dateien in diesem Bucket ab. Entwickler haben jedoch die Möglichkeit, einen spezifischeren Speicherort auszuwählen. Der Standard-Bucket ist programmatisch über google.appengine.api.app_identity.get_default_gcs_bucket_name() zugänglich. Wenn Sie auf diesen Wert zugreifen möchten, z. B. um ihn als Präfix für die Organisation hochgeladener Dateien zu verwenden, ist ein neuer Import erforderlich. Beispiel: Sortieren nach Dateityp:

Wenn Sie so etwas beispielsweise für Bilder implementieren möchten, benötigen Sie Code wie diesen sowie Code, der Dateitypen prüft, um den gewünschten Bucket-Namen auszuwählen:
ROOT_BUCKET = app_identity.get_default_gcs_bucket_name()
IMAGE_BUCKET = '%s/%s' % (ROOT_BUCKET, 'images')
Außerdem validieren Sie die hochgeladenen Bilder mit einem Tool wie dem imghdr-Modul der Python-Standardbibliothek, um den Bildtyp zu bestätigen. Schließlich sollten Sie die Größe von Uploads begrenzen, um sich vor böswilligen Akteuren zu schützen.
Nehmen wir an, das ist alles erledigt. Wie können wir unsere App so aktualisieren, dass der Speicherort für die hochgeladenen Dateien angegeben werden kann? Der Schlüssel besteht darin, den Aufruf von blobstore.create_upload_url in MainHandler.get anzupassen, um den gewünschten Speicherort in Cloud Storage für den Upload anzugeben. Fügen Sie dazu den Parameter gs_bucket_name so hinzu:
blobstore.create_upload_url('/upload', gs_bucket_name=IMAGE_BUCKET))
Da es sich hierbei um ein optionales Update handelt, mit dem Sie angeben können, wohin Uploads gesendet werden sollen, ist es nicht Teil der Datei main.py im Repository. Stattdessen ist im Repository eine Alternative namens main-gcs.py verfügbar, die Sie sich ansehen können. Anstatt einen separaten Bucket-„Ordner“ zu verwenden, speichert der Code in main-gcs.py Uploads im „Stamm“-Bucket (PROJECT_ID.appspot.com) wie main.py, bietet aber das Gerüst, das Sie benötigen, wenn Sie das Beispiel wie in diesem Abschnitt angedeutet weiterentwickeln möchten. Unten sehen Sie eine Abbildung der Unterschiede zwischen main.py und main-gcs.py.

6. Zusammenfassung/Bereinigung
In diesem Abschnitt wird das Codelab abgeschlossen. Dazu wird die Anwendung bereitgestellt und geprüft, ob sie wie vorgesehen funktioniert und die Ausgabe korrekt ist. Führen Sie nach der App-Validierung alle Bereinigungsschritte aus und überlegen Sie sich die nächsten Schritte.
Anwendung bereitstellen und prüfen
Stellen Sie Ihre Anwendung mit gcloud app deploy noch einmal bereit und prüfen Sie, ob sie wie beschrieben funktioniert. Die User Experience (UX) unterscheidet sich von der Anwendung in Modul 0. Es gibt jetzt zwei verschiedene Bildschirme in Ihrer Anwendung. Der erste ist die Aufforderung zum Hochladen des Formulars für den Besuch:
Anschließend können die Endnutzer entweder eine Datei hochladen und auf „Senden“ klicken oder auf „Überspringen“ klicken, um nichts hochzuladen. In beiden Fällen wird der Bildschirm des letzten Besuchs angezeigt, der jetzt mit „Ansehen“-Links oder „Keine“ zwischen den Zeitstempeln des Besuchs und den Besucherinformationen ergänzt wurde:

Glückwunsch! Sie haben dieses Codelab abgeschlossen und die Beispiel-App aus Modul 0 um die Verwendung von App Engine Blobstore erweitert. Ihr Code sollte jetzt mit dem Code im Ordner FINISH (Modul 15) übereinstimmen. Die alternative main-gcs.py ist ebenfalls in diesem Ordner vorhanden.
Bereinigen
Allgemein
Wenn Sie vorerst fertig sind, empfehlen wir Ihnen, Ihre App Engine-Anwendung zu deaktivieren, um Abrechnungskosten zu vermeiden. Wenn Sie jedoch weitere Tests oder Experimente durchführen möchten, bietet die App Engine-Plattform ein kostenloses Kontingent. Solange Sie diese Nutzungsstufe nicht überschreiten, fallen keine Kosten an. Das gilt für die Rechenleistung. Es können aber auch Gebühren für relevante App Engine-Dienste anfallen. Weitere Informationen finden Sie auf der Preisseite. Wenn diese Migration andere Cloud-Dienste umfasst, werden diese separat abgerechnet. In beiden Fällen finden Sie unten im Abschnitt „Spezifisch für dieses Codelab“ weitere Informationen.
Der Vollständigkeit halber sei erwähnt, dass bei der Bereitstellung auf einer serverlosen Google Cloud-Computing-Plattform wie App Engine geringe Build- und Speicherkosten anfallen. Cloud Build hat ein eigenes kostenloses Kontingent, ebenso wie Cloud Storage. Das Speichern dieses Bildes verbraucht einen Teil dieses Kontingents. Möglicherweise leben Sie jedoch in einer Region, in der es keine solche kostenlose Stufe gibt. Achten Sie daher auf Ihre Speichernutzung, um potenzielle Kosten zu minimieren. Zu den spezifischen Cloud Storage-„Ordnern“, die Sie sich ansehen sollten, gehören:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Die oben genannten Speicherlinks hängen von Ihrem
PROJECT_IDund *LOC*ab, z. B. „us“, wenn Ihre App in den USA gehostet wird.
Wenn Sie diese Anwendung oder andere zugehörige Migrations-Codelabs nicht fortsetzen und alles vollständig löschen möchten, beenden Sie Ihr Projekt.
Spezifisch für dieses Codelab
Die unten aufgeführten Dienste sind nur in diesem Codelab verfügbar. Weitere Informationen finden Sie in der Dokumentation zum jeweiligen Produkt:
- Der App Engine-Blobstore-Dienst unterliegt den Kontingenten und Limits für gespeicherte Daten. Lesen Sie sich diese sowie die Preisseite für gebündelte Legacy-Dienste durch.
- Der Dienst App Engine Datastore wird von Cloud Datastore (Cloud Firestore im Datastore-Modus) bereitgestellt, der ebenfalls eine kostenlose Stufe bietet. Weitere Informationen finden Sie auf der Preisseite.
Nächste Schritte
Die nächste logische Migration, die Sie in Betracht ziehen sollten, wird in Modul 16 behandelt. Dort wird Entwicklern gezeigt, wie sie vom App Engine Blobstore-Dienst zur Cloud Storage-Clientbibliothek migrieren. Zu den Vorteilen eines Upgrades gehören der Zugriff auf mehr Cloud Storage-Funktionen und die Möglichkeit, sich mit einer Clientbibliothek vertraut zu machen, die für Anwendungen außerhalb von App Engine funktioniert, sei es in Google Cloud, anderen Clouds oder sogar lokal. Wenn Sie nicht alle in Cloud Storage verfügbaren Funktionen benötigen oder sich Sorgen über die Auswirkungen auf die Kosten machen, können Sie bei App Engine Blobstore bleiben.
Nach Modul 16 gibt es eine ganze Reihe weiterer möglicher Migrationen, z. B. Cloud NDB und Cloud Datastore, Cloud Tasks oder Cloud Memorystore. Es gibt auch produktübergreifende Migrationen zu Cloud Run und Cloud Functions. Das Migrations-Repository enthält alle Codebeispiele, Links zu allen verfügbaren Codelabs und Videos sowie Anleitungen dazu, welche Migrationen in Betracht gezogen werden sollten und in welcher Reihenfolge sie durchgeführt werden sollten.
7. Zusätzliche Ressourcen
Probleme mit Codelab/Feedback zu Codelab
Wenn Sie Probleme mit diesem Codelab haben, suchen Sie zuerst nach Ihrem Problem, bevor Sie es melden. Links zum Suchen und Erstellen neuer Probleme:
Migrationsressourcen
Links zu den Repository-Ordnern für Modul 0 (START) und Modul 15 (FINISH) finden Sie in der Tabelle unten. Sie können auch über das Repository für alle App Engine-Codelab-Migrationen darauf zugreifen. Sie können das Repository klonen oder eine ZIP-Datei herunterladen.
Codelab | Python 2 | Python 3 |
Modul 0 | – | |
Modul 15 (dieses Codelab) | – |
Online-Ressourcen
Im Folgenden finden Sie Onlineressourcen, die für diese Anleitung relevant sein könnten:
App Engine
- App Engine Blobstore-Dienst
- Kontingente und Limits für gespeicherte App Engine-Daten
- App Engine-Dokumentation
- Python 2-App Engine-Laufzeit (Standardumgebung)
- Integrierte App Engine-Bibliotheken in Python 2 App Engine verwenden
- Informationen zu Preisen und Kontingenten für App Engine
- Einführung der App Engine-Plattform der zweiten Generation (2018)
- Plattformen der ersten und zweiten Generation im Vergleich
- Langzeitsupport für ältere Laufzeiten
- Repository mit Migrationsbeispielen für die Dokumentation
- Repository mit Migrationsbeispielen aus der Community
Google Cloud
- Python in der Google Cloud Platform
- Google Cloud Python-Clientbibliotheken
- Google Cloud-Stufe „Immer kostenlos“
- Google Cloud SDK (gcloud-Befehlszeilentool)
- Gesamte Google Cloud-Dokumentation
Python
- Vorlagensysteme Django und Jinja2
webapp2-Web-Frameworkwebapp2-Dokumentationwebapp2_extrasLinkswebapp2_extrasJinja2-Dokumentation
Videos
- Serverless Migration Station
- Serverless Expeditions
- Google Cloud Tech abonnieren
- Google Developers abonnieren
Lizenz
Dieses Werk unterliegt einer Creative-Commons-Lizenz „Namensnennung 2.0“.