1. Omówienie
Seria ćwiczeń z programowania dla bezserwerowych stacji migracji (samouczek, samouczków) i podobnych filmów ma pomóc deweloperom bezserwerowych Google Cloud w modernizacji aplikacji przez przeprowadzenie co najmniej 1 migracji, w wyniku rezygnacji ze starszych usług. W ten sposób Twoje aplikacje stają się bardziej przenośne, mają więcej opcji i elastyczność, co pozwala na integrację z szerszą gamą usług Cloud i uzyskiwanie do nich dostępu, a także łatwiejsze przejście na nowsze wersje językowe. Choć początkowo koncentrowaliśmy się na pierwszych użytkownikach Cloud, głównie deweloperów korzystających ze środowiska App Engine (środowisko standardowe), ta seria jest na tyle szeroka, aby uwzględnić inne platformy bezserwerowe, takie jak Cloud Functions i Cloud Run, oraz inne, w stosownych przypadkach.
Dzięki temu ćwiczeniu w Codelabs dowiesz się, jak przejść z App Engine Blobstore do Cloud Storage. Możliwe są też niejawne migracje z:
- Z platformy internetowej
webapp2
do Flask (omówione w module 1) - Z App Engine NDB na Cloud NDB na potrzeby dostępu do Datastore (objęte modułem 2)
- Python 2–3 (przeniesiona aplikacja jest zgodna zarówno z Pythonem 2, jak i 3)
Szczegółowe informacje znajdziesz w powiązanych modułach migracji.
Dowiesz się, jak:
- Dodaj sposób korzystania z interfejsu API/biblioteki App Engine Blobstore
- Przechowywanie treści przesłanych przez użytkowników do usługi Blobstore
- Przygotowanie do następnego kroku migracji do Cloud Storage
Czego potrzebujesz
- projekt Google Cloud Platform z aktywnym kontem rozliczeniowym GCP;
- Podstawowe umiejętności w języku Python
- praktyczna znajomość typowych poleceń w Linuksie
- Podstawowa wiedza o tworzeniu i wdrażaniu aplikacji App Engine.
- działającą aplikację App Engine w module 15: wykonaj ćwiczenie z programowania w module 15 (zalecane) lub skopiuj aplikację modułu 15 z repozytorium;
Ankieta
Jak wykorzystasz ten samouczek?
Jak oceniasz swoje doświadczenia z językiem Python?
Jak oceniasz korzystanie z usług Google Cloud?
2. Tło
To ćwiczenie w Codelabs rozpoczyna się od przykładowej aplikacji z modułu 15 i pokazuje, jak przejść z Blobstore (i NDB) do Cloud Storage (i Cloud NDB). Proces migracji obejmuje zastąpienie zależności od starszych pakietów usług App Engine, co pozwoli Ci w razie potrzeby przenieść aplikacje na inną bezserwerową platformę Cloud lub inną platformę hostingową.
Ta migracja wymaga nieco więcej wysiłku niż inne migracje w tej serii. Blobstore jest zależny od pierwotnej platformy aplikacji internetowej, dlatego przykładowa aplikacja korzysta z platformy Webapp2, a nie Flask. W tym samouczku omawiamy migracje do Cloud Storage, Cloud NDB, Flask i Pythona 3.
Aplikacja nadal rejestruje „wizyty” użytkowników i wyświetla 10 najnowszych, ale w poprzednim (Moduł 15) dodano nową funkcję, aby dostosować do zastosowania Blobstore: aplikacja zachęca użytkowników do przesłania artefaktu (pliku) odpowiadającego ich „wizycie”. Użytkownicy mogą to zrobić lub wybrać opcję „pomiń”. rezygnować. Niezależnie od decyzji użytkownika następna strona renderuje te same dane co w poprzednich wersjach tej aplikacji – zawiera informacje o ostatnich wizytach. Dodatkowy problem polega na tym, że wizyty z odpowiadającymi im artefaktami wiążą się z „widokiem”. który służy do wyświetlania artefaktu wizyty. To ćwiczenie w Codelabs wykorzystuje wymienione wcześniej migracje, zachowując opisane funkcje.
3. Konfiguracja/praca
Zanim przejdziemy do głównej części samouczka, skonfigurujmy projekt, pobierz kod, a potem wdróż aplikację bazową. W ten sposób wiemy, że zaczynamy od działającego kodu.
1. Konfigurowanie projektu
Jeśli aplikacja modułu 15 została już wdrożona, zalecamy ponowne wykorzystanie tego samego projektu (i kodu). Możesz też utworzyć nowy projekt lub wykorzystać inny istniejący projekt. Sprawdź, czy projekt ma aktywne konto rozliczeniowe i jest włączona usługa App Engine.
2. Pobierz przykładową aplikację bazową
Jednym z warunków wstępnych tego ćwiczenia z programowania jest posiadanie działającej przykładowej aplikacji w module 15. Jeśli go nie masz, możesz go pobrać w module 15 „START” (link poniżej). To ćwiczenie w Codelabs przeprowadzi Cię przez poszczególne kroki, kończąc kodem przypominającym to, co znajduje się w module 16 „FINISH”. folderu Dysku.
- START: folder modułu 15 (Python 2)
- ZAKOŃCZ: folder modułu 16 (Python 2)
- Całe repozytorium (aby sklonować lub pobrać plik ZIP)
Katalog plików START z modułem 15 powinien wyglądać tak:
$ ls README.md app.yaml main-gcs.py main.py templates
Plik main-gcs.py
to alternatywna wersja main.py
z modułu 15, która pozwala wybrać zasobnik Cloud Storage różniący się od domyślnego adresu URL przypisanego do aplikacji na podstawie identyfikatora projektu: PROJECT_ID
.appspot.com
. Ten plik nie odgrywa żadnej roli w ramach tego ćwiczenia z programowania (Moduł 16), w razie potrzeby można do niego zastosować inne techniki migracji.
3. (Ponowne) wdrażanie aplikacji podstawowej
Pozostałe kroki do wykonania:
- Ponownie zapoznaj się z narzędziem wiersza poleceń
gcloud
- Wdróż ponownie przykładową aplikację za pomocą
gcloud app deploy
- Sprawdź, czy aplikacja działa w App Engine bez problemów
Po wykonaniu tych czynności i potwierdzeniu działania aplikacji z modułu 15. Strona początkowa zawiera formularz z prośbą o przesłanie pliku artefaktu wizyty i opcją „pominięcia” , aby zrezygnować:
Gdy użytkownik prześle plik lub pominie go, aplikacja renderuje znajome „ostatnie wizyty” strona:
Wizyty zawierające artefakt będą miały „wyświetlenie” po prawej stronie sygnatury czasowej wizyty, by wyświetlić (lub pobrać) artefakt. Po potwierdzeniu działania aplikacji możesz przejść ze starszych wersji usług App Engine (webapp2, NDB, Blobstore) na nowoczesne alternatywy (Flask, Cloud NDB, Cloud Storage).
4. Aktualizowanie plików konfiguracji
W zaktualizowanej wersji aplikacji pojawiają się 3 pliki konfiguracji. Wymagane zadania to:
- Zaktualizuj wymagane wbudowane biblioteki zewnętrzne w
app.yaml
i pozostaw otwarte narzędzie do migracji z języka Python 3. - Dodaj atrybut
requirements.txt
, który określa wszystkie wymagane biblioteki, które nie są wbudowane - Dodaj
appengine_config.py
, aby aplikacja obsługiwała zarówno wbudowane, jak i niewbudowane biblioteki innych firm
app.yaml
Aby edytować plik app.yaml
, zaktualizuj sekcję libraries
. Usuń kategorię jinja2
i dodaj użytkowników grpcio
, setuptools
oraz ssl
. Wybierz najnowszą dostępną wersję dla wszystkich 3 bibliotek. Dodaj też dyrektywę runtime
w języku Python 3, ale z komentarzem. Gdy skończysz, kod powinien wyglądać podobnie do tego (w przypadku wyboru Pythona 3.9):
PRZED:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
PO:
#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
Wprowadzone zmiany dotyczą głównie wbudowanych bibliotek Pythona 2 dostępnych na serwerach App Engine (nie trzeba więc ich grupować samodzielnie). Usunęliśmy kod Jinja2, ponieważ zawiera on platformę Flask, którą dodamy do pliku reqs.txt. Jeśli używane są biblioteki klienta Google Cloud, takie jak Cloud NDB czy Cloud Storage, potrzebne są narzędzia grpcio i setuptools. Pamiętaj też, że Cloud Storage wymaga biblioteki ssl. Dyrektywa środowiska wykonawczego z komentarzem u góry służy do przenoszenia tej aplikacji do Pythona 3. Omówimy ten temat na końcu samouczka.
requirements.txt
Dodaj plik requirements.txt
, wymagając platformy Flask oraz bibliotek klienta Cloud NDB i Cloud Storage – żadne z nich nie są wbudowane. Utwórz plik z taką zawartością:
flask
google-cloud-ndb
google-cloud-storage
Środowisko wykonawcze App Engine w języku Python 2 wymaga samodzielnego grupowania niewbudowanych bibliotek zewnętrznych, więc uruchom to polecenie, aby zainstalować te biblioteki w folderze lib:
pip install -t lib -r requirements.txt
Jeśli na komputerze do programowania masz zarówno język Python 2, jak i 3, musisz użyć polecenia pip2, aby mieć pewność, że otrzymasz te biblioteki w języku Python 2. Po przejściu na Pythona 3 nie musisz już grupować samodzielnie.
appengine_config.py
Dodaj plik appengine_config.py
obsługujący wbudowane i niewbudowane biblioteki innych firm. Utwórz plik z taką zawartością:
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)
Wykonane właśnie czynności powinny być podobne lub takie same jak te wymienione w sekcji Instalowanie bibliotek do aplikacji w języku Python 2 w dokumentacji App Engine, a konkretniej zawartość pliku appengine_config.py
powinna być zgodna z tym, co jest w kroku 5.
Prace nad plikami konfiguracji zostały zakończone, więc przejdźmy do aplikacji.
5. Modyfikowanie plików aplikacji
Importy
Pierwszy zestaw zmian w usłudze main.py
obejmuje zastąpienie wszystkich elementów. Co się zmienia:
- Tabela
webapp2
została zastąpiona przez Flask - Zamiast Jinja2 z
webapp2_extras
użyj Jinja2, który jest dołączony do Flask. - Zastąpienie App Engine Blobstore i NDB przez Cloud NDB i Cloud Storage
- Moduły obsługi Blobstore w
webapp
zostały zastąpione kombinacją modułu standardowej bibliotekiio
, narzędzia Flask i narzędziwerkzeug
. - Domyślnie Blobstore zapisuje w zasobniku Cloud Storage o nazwie odpowiadającej adresowi URL Twojej aplikacji (
PROJECT_ID.appspot.com
). Przenosimy ją do biblioteki klienta Cloud Storage, dlategogoogle.auth
jest używany do uzyskania identyfikatora projektu, który pozwala określić dokładnie taką samą nazwę zasobnika. Możesz zmienić nazwę zasobnika, bo nie jest już ona zakodowana na stałe.
PRZED:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
Wprowadź zmiany z powyższej listy, zastępując bieżącą sekcję importowania w interfejsie main.py
poniższym fragmentem kodu.
PO:
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
Inicjowanie i niepotrzebna obsługa Jinja2
Następny blok kodu do zastąpienia to BaseHandler
określający użycie Jinja2 z webapp2_extras
. Jest to niepotrzebne, bo Jinja2 jest dołączony do platformy Flask, która jest domyślnym silnikiem do tworzenia szablonów. Usuń ją.
Po stronie Moduł 16 utwórz instancje obiektów, których nie było w starszej aplikacji. Obejmuje to inicjowanie aplikacji Flask oraz tworzenie klientów API dla Cloud NDB i Cloud Storage. Na koniec utworzyliśmy nazwę zasobnika Cloud Storage zgodnie z opisem powyżej w sekcji dotyczącej importowania. Oto, co można zrobić przed wdrożeniem tych zmian i po nim:
PRZED:
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))
PO:
app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID
Zaktualizuj dostęp do Datastore
Usługa Cloud NDB jest głównie zgodna z App Engine NDB. Jedną z różnic jest konieczność posiadania klienta interfejsu API. Drugie rozwiązanie wymaga, aby dostęp do Datastore był kontrolowany przez menedżera kontekstu klienta API w języku Python. Oznacza to, że wszystkie wywołania dostępu do Datastore korzystające z biblioteki klienta Cloud NDB mogą występować tylko w blokach Pythona with
.
To jedna zmiana. a drugie to Blobstore i jego obiekty, np. Obiekty BlobKey
nie są obsługiwane przez Cloud Storage, dlatego zmień file_blob
na ndb.StringProperty
. Poniżej znajdziesz klasę modelu danych oraz zaktualizowane funkcje store_visit()
i fetch_visits()
, które odzwierciedlają te zmiany:
PRZED:
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)
PO:
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)
Oto obrazowe przedstawienie wprowadzonych do tej pory zmian:
Aktualizowanie modułów obsługi
Moduł obsługi przesyłania
Moduły obsługi w webapp2
są klasami, gdy działają w narzędziu Flask. Zamiast metody z czasownikami HTTP do dekorowania funkcji Flask używa czasownika. Blobstore i jego moduły obsługi webapp
są zastępowane funkcjonalnością z Cloud Storage, a także usługą Flask i jej narzędziami:
PRZED:
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)
PO:
@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)
Kilka uwag na temat tej aktualizacji:
- Artefakty pliku zamiast
blob_id
są teraz identyfikowane na podstawie nazwy pliku (fname
), jeśli istnieje. W przeciwnym razieNone
(użytkownik zrezygnował z przesłania pliku). - Moduły obsługi Blobstore odebrały proces przesyłania od użytkowników, ale Cloud Storage go nie obsługuje. W związku z tym możesz zobaczyć nowo dodany kod, który ustawia obiekt blob i lokalizację (zasobnik) pliku, a także wywołanie, które wykonuje faktyczne przesyłanie. (
upload_from_file()
). webapp2
używa tabeli routingu na dole pliku aplikacji, a trasy Flask znajdują się w każdym udekorowanym module obsługi.- Oba moduły obsługi zakończą swoje funkcje, przekierowując je na stronę główną (
/
), zachowując jednocześnie żądaniePOST
z zwróconym kodem HTTP 307.
Moduł obsługi pobierania
Aktualizowanie modułu obsługi pobierania odbywa się zgodnie z wzorcem podobnym do modułu przesyłania, ale ilość kodu jest znacznie mniejsza. Zastąp funkcje Blobstore i webapp
ich odpowiednikami w Cloud Storage i Flask:
PRZED:
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)
PO:
@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)
Uwagi na temat tej aktualizacji:
- Znowu Flask dekoruje funkcje obsługi za pomocą trasy, a
webapp
robi to w tabeli routingu na dole, więc rozpoznasz składnię dopasowania wzorca('/view/([^/]+)?'
) zamiast składni Flask ('/view/<path:fname>'
). - Podobnie jak w przypadku modułu obsługi przesyłania, po stronie Cloud Storage wymagane jest nieco więcej pracy ze względu na funkcje pobrane przez moduły obsługi Blobstore, czyli identyfikowanie pliku (blob) i jednoznaczne pobranie pliku binarnego lub pojedynczego wywołania metody
send_blob()
modułu obsługi Blobstore. - W obu przypadkach, jeśli nie znaleziono artefaktu, użytkownikowi jest zwracany błąd HTTP 404.
Główny moduł obsługi
Ostateczne zmiany w głównej aplikacji są dokonywane w głównym module obsługi. Metody czasowników HTTP webapp2
zostały zastąpione przez jedną funkcję łączącą ich funkcje. Zastąp klasę MainHandler
funkcją root()
i usuń tabelę routingu webapp2
w następujący sposób:
PRZED:
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)
PO:
@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)
Zamiast osobnych metod get()
i post()
są to instrukcja if-else
w root()
. Poza tym root()
jest pojedynczą funkcją, więc dla GET
i POST
wystarczy jedno wywołanie, ale w webapp2
jest to niemożliwe.
Oto obrazowe przedstawienie tego drugiego i ostatniego zestawu zmian w elemencie main.py
:
(opcjonalnie) „Ulepszanie” zgodności wstecznej
Rozwiązanie utworzone powyżej działa idealnie, ale tylko wtedy, gdy zaczynasz od zera i nie masz plików utworzonych przez Blobstore. Zaktualizowaliśmy aplikację tak, aby rozpoznawała pliki według nazwy pliku, a nie BlobKey
, dlatego aplikacja w stanie, w której ukończono Moduł 16, nie będzie mogła wyświetlać plików Blobstore. Innymi słowy, podczas tej migracji wprowadziliśmy zmianę niekompatybilną wstecznie. Prezentujemy alternatywną wersję zasobu main.py
o nazwie main-migrate.py
(znajdującą się w repozytorium), która ma na celu wypełnienie tej luki.
Pierwsze „rozszerzenie” do obsługi plików utworzonych w Blobstore jest model danych, który ma atrybut BlobKeyProperty
(oprócz StringProperty
dla plików utworzonych w 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()
Właściwość file_blob
będzie używana do identyfikowania plików utworzonych w Blobstore, a file_gcs
do plików z Cloud Storage. Teraz podczas tworzenia nowych wizyt zapisz wartość bezpośrednio w file_gcs
, a nie w file_blob
, więc store_visit wygląda trochę inaczej:
PRZED:
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()
PO:
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()
Podczas pobierania ostatnich wizyt „znormalizuj” dane przed wysłaniem do szablonu:
PRZED:
@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)
PO:
@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)
Następnie potwierdź, że istnieje file_blob
lub file_gcs
(albo żaden z tych elementów). Jeśli jest dostępny plik, wybierz go i użyj tego identyfikatora (BlobKey
w przypadku plików utworzonych w Blobstore lub nazwy pliku w przypadku plików utworzonych w Cloud Storage). Kiedy mówimy „Pliki utworzone w Cloud Storage”, mamy na myśli pliki utworzone
za pomocą biblioteki klienta Cloud Storage. Blobstore zapisuje również dane w Cloud Storage, ale w tym przypadku będą to pliki utworzone przez Blobstore.
Jeszcze ważniejsze jest to, jaka jest funkcja etl_visits()
wykorzystywana do normalizacji lub ETL (wyodrębniania, przekształcania i wczytywania danych) dla użytkownika? Wygląda on następująco:
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]
Prawdopodobnie wygląda to tak, jak tego oczekiwano: kod zapętla wszystkie wizyty i w przypadku każdej wizyty dosłownie sprawdza dane o użytkownikach i sygnaturach czasowych, a następnie sprawdza, czy istnieje element file_gcs
lub file_blob
, a jeśli tak, wybiera jedną z nich (lub None
, jeśli nie istnieją).
Różnice między main.py
a main-migrate.py
:
Jeśli zaczynasz od zera bez plików utworzonych w Blobstore, użyj main.py
. Jeśli jednak przenosisz pliki i chcesz korzystać z nich zarówno w Blobstore, jak i Cloud Storage, zapoznaj się z przykładem main-migrate.py
, który pomoże Ci zaplanować migrację do własnych aplikacji. W przypadku złożonych migracji mogą wystąpić szczególne przypadki. Ten przykład ma pokazać większe zainteresowanie modernizacją prawdziwych aplikacji przy użyciu prawdziwych danych.
6. Podsumowanie/Czyszczenie
W tej sekcji znajdziesz podsumowanie tego ćwiczenia w programie przez wdrożenie aplikacji oraz sprawdzenie, czy działa ona zgodnie z oczekiwaniami i we wszystkich uwzględnionych danych wyjściowych. Po sprawdzeniu aplikacji wykonaj czynności związane z czyszczeniem i zastanów się nad dalszymi czynnościami.
Wdróż i zweryfikuj aplikację
Przed ponownym wdrożeniem aplikacji uruchom pip install -t lib -r requirements.txt
, aby umieścić te dołączone do siebie biblioteki innych firm w folderze lib. Jeśli chcesz uruchomić rozwiązanie zgodne wstecznie, najpierw zmień nazwę main-migrate.py
na main.py
. Teraz uruchom gcloud app deploy
i sprawdź, czy aplikacja działa tak samo jak aplikacja Moduł 15. Ekran formularza wygląda tak:
Strona ostatnich wizyt wygląda tak:
Gratulujemy ukończenia tego ćwiczenia z programowania. Zastępujesz App Engine Blobstore usługą Cloud Storage, App Engine NDB usługą Cloud NDB oraz webapp2
za pomocą Flask. Twój kod powinien być teraz zgodny z plikiem w folderze FINISH (Module 16). W tym folderze znajduje się również alternatywna wersja main-migrate.py
.
„Migracja” Pythona 3
Do przeniesienia tej aplikacji do Pythona 3 wystarczy skomentowana dyrektywa runtime
w języku Python 3 na górze kodu app.yaml
. Kod źródłowy jest już zgodny z językiem Python 3, więc nie musisz w nim wprowadzać żadnych zmian. Aby wdrożyć to jako aplikację w Pythonie 3, wykonaj te czynności:
- Usuń znacznik komentarza z dyrektywy
runtime
w języku Python 3 na górzeapp.yaml
. - Usuń wszystkie pozostałe wiersze w wierszu
app.yaml
. - Usuń plik
appengine_config.py
. (nieużywane w środowisku wykonawczym Pythona 3) - Usuń folder
lib
, jeśli istnieje. (nie jest potrzebne w środowisku wykonawczym Pythona 3)
Czyszczenie danych
Ogólne
Jeśli na razie wszystko jest gotowe, wyłącz aplikację App Engine, aby uniknąć naliczania opłat. Jeśli jednak chcesz jeszcze bardziej przetestować lub poeksperymentować, platforma App Engine ma bezpłatny limit. Dopóki nie przekroczysz tego limitu, nie pobierzemy żadnych opłat. Oznacza to obliczenia, ale mogą być też naliczane opłaty za odpowiednie usługi App Engine. Więcej informacji znajdziesz na stronie z cennikiem. Jeśli ta migracja obejmuje inne usługi Cloud, są one rozliczane osobno. W obu przypadkach zapoznaj się z sekcją „Zapoznaj się z tymi ćwiczeniami”. sekcji poniżej.
Aby w pełni wyjaśnić wszystkie kwestie, wdrożenie na bezserwerowej platformie obliczeniowej Google Cloud, takiej jak App Engine, wiąże się z niewielkimi kosztami kompilacji i przechowywania danych. Cloud Build ma własny bezpłatny limit, podobnie jak Cloud Storage. Przechowywanie tego obrazu wykorzystuje część tego limitu. Możesz jednak mieszkać w regionie, w którym nie ma takiego poziomu bezpłatnego. Dlatego pamiętaj o wykorzystaniu miejsca na dane, aby zminimalizować potencjalne koszty. Określone „foldery” Cloud Storage należy sprawdzić m.in.:
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
- Powyższe linki do miejsca na dane zależą od Twoich danych
PROJECT_ID
oraz *LOC
*, np. „us
” jeśli aplikacja jest hostowana w Stanach Zjednoczonych.
Jeśli natomiast nie zamierzasz dalej korzystać z tej aplikacji lub innych powiązanych z nią ćwiczeń w Codelabs i chcesz całkowicie usunąć wszystko, zamknij projekt.
Powiązane z tym ćwiczeniam z programowania
Wymienione poniżej usługi są dostępne tylko w ramach tego ćwiczenia z programowania. Więcej informacji znajdziesz w dokumentacji poszczególnych usług:
- Usługa App Engine Blobstore podlega limitom i limitom przechowywanych danych, więc zapoznaj się z nimi oraz stroną z cennikiem starszych pakietów usług.
- Cloud Storage ma poziom bezpłatny dla poszczególnych regionów. Więcej informacji znajdziesz też na stronie z ogólnymi cenami.
- Usługa App Engine Datastore jest świadczona przez Cloud Datastore (Cloud Firestore w trybie Datastore), który również ma poziom bezpłatny. więcej informacji znajdziesz na stronie z cennikiem”.
Pamiętaj, że po przejściu z modułów 15 na 16 nadal będziesz mieć dane w Blobstore, dlatego umieściliśmy powyżej informacje o cenach.
Dalsze kroki
Oprócz tego samouczka dostępne są też inne moduły migracji koncentrujące się na odejściu od starszych pakietów usług, które warto rozważyć:
- Moduł 2. Migracja z App Engine
ndb
do Cloud NDB - Moduły 7–9. Migracja z kolejki zadań App Engine w trybie push do Cloud Tasks
- Moduły 12–13: migracja z App Engine Memcache do Cloud Memorystore
- Moduły 18–19: migracja z kolejki zadań App Engine (pobierania zadań) do Cloud Pub/Sub
App Engine nie jest już jedyną bezserwerową platformą w Google Cloud. Jeśli masz małą aplikację App Engine lub taką, która ma ograniczoną funkcjonalność i chcesz przekształcić ją w samodzielny mikroserwis, albo chcesz podzielić aplikację monolityczną na kilka komponentów wielokrotnego użytku, rozważ przejście na Cloud Functions. Jeśli konteneryzacja stała się częścią przepływu pracy przy tworzeniu aplikacji, zwłaszcza jeśli składa się z potoku CI/CD (ciągła integracja/ciągłe dostarczanie lub wdrażanie), rozważ migrację do Cloud Run. Te scenariusze są opisane w tych modułach:
- Migracja z App Engine do Cloud Functions: patrz Moduł 11.
- Migracja z App Engine do Cloud Run: zapoznaj się z Modułem 4, aby skonteneryzować aplikację za pomocą Dockera, lub Moduł 5, aby zrobić to bez kontenerów, Dockera lub
Dockerfile
.
Przejście na inną bezserwerową platformę jest opcjonalne. Zalecamy, aby przed wprowadzeniem jakichkolwiek zmian wybrać najlepsze opcje dla swoich aplikacji i przypadków użycia.
Niezależnie od tego, który moduł migracji wykorzystasz w następnej kolejności, wszystkie materiały z serwerowej platformy migracji (laboratorium, filmy, kod źródłowy [jeśli jest dostępne]) są dostępne w repozytorium open source. README
repozytorium zawiera też wskazówki dotyczące migracji, które warto wziąć pod uwagę, i wszelkich odpowiednich „zamówień” modułów migracji.
7. Dodatkowe materiały
Problemy z ćwiczeniami w Codelabs/opinie
Jeśli podczas korzystania z tych ćwiczeń z programowania zauważysz jakiekolwiek problemy, najpierw je wyszukaj. Linki do wyszukiwania i tworzenia nowych problemów:
Zasoby migracji
Linki do folderów repozytorium w modułach 15 (START) i modułach 16 (FINISH) znajdziesz w tabeli poniżej. Dostęp do nich możesz też uzyskać z repozytorium wszystkich migracji z ćwiczeń z programowania App Engine, które możesz sklonować lub pobrać w postaci pliku ZIP.
Codelab | Python 2 | Python 3 |
Część 15 | Nie dotyczy | |
Moduł 16 (to ćwiczenia z programowania) | (tak samo jak w Pythonie 2) |
Zasoby online
Poniżej znajdują się zasoby online, które mogą być pomocne w przypadku tego samouczka:
Blobstore i Cloud Storage App Engine
- Usługa Blobstore App Engine
- Migracja do biblioteki klienta Cloud Storage
- Strona główna Cloud Storage
- Dokumentacja Cloud Storage
Platforma App Engine
- Dokumentacja App Engine
- Środowisko wykonawcze App Engine (środowisko standardowe) Pythona 2
- Korzystanie z wbudowanych bibliotek App Engine w Python 2 App Engine
- Środowisko wykonawcze App Engine w Pythonie 3 (środowisko standardowe)
- Różnice między Pythonem 2 a Pythonem 2 3 środowiska wykonawcze App Engine (w środowisku standardowym)
- Przewodnik po migracji do App Engine (w środowisku standardowym) w języku Python 2 do 3
- Informacje o cenach i limitach App Engine
- Wprowadzenie na rynek platformy App Engine drugiej generacji (2018)
- Porównanie pierwszych i platformy drugiej generacji
- Długoterminowa obsługa starszych środowisk wykonawczych
- Repozytorium z przykładami migracji dokumentacji
- Repozytorium z przykładami migracji dostarczonych przez społeczność
Inne informacje o Google Cloud
- Python w Google Cloud Platform
- Biblioteki klienta Google Cloud Python
- Zawsze bezpłatne usługi Google Cloud typ
- Google Cloud SDK (narzędzie wiersza poleceń
gcloud
) - Cała dokumentacja Google Cloud
Python
- Systemy szablonów Django i Jinja2
- Platforma internetowa
webapp2
- Dokumentacja
webapp2
- Połączenia z
webapp2_extras
- Dokumentacja
webapp2_extras
Jinja2 - Flask Web Framework
Filmy
- Stacja migracji bezserwerowej
- Ekspedycje bezserwerowe
- Zasubskrybuj Google Cloud Tech.
- Subskrybuj Google Developers.
Licencja
To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.