1. Przegląd
Ta seria ćwiczeń z programowania (samodzielnych samouczków praktycznych) ma pomóc deweloperom Google App Engine (Standard) w modernizacji aplikacji poprzez przeprowadzenie ich przez serię migracji. Najważniejszym krokiem jest odejście od usług dołączonych do oryginalnego środowiska wykonawczego, ponieważ środowiska wykonawcze nowej generacji są bardziej elastyczne i zapewniają użytkownikom większy wybór opcji usług. Przejście na środowisko wykonawcze nowszej generacji ułatwia integrację z usługami Google Cloud, korzystanie z szerszego zakresu obsługiwanych usług i obsługę bieżących wersji językowych.
Z tego samouczka dowiesz się, jak przeprowadzić migrację z wbudowanej w App Engine biblioteki klienta ndb (Next Database) na bibliotekę klienta Cloud NDB.
Dowiesz się, jak:
- Użyj biblioteki
ndbApp Engine (jeśli jej nie znasz). - Migracja z
ndbdo Cloud NDB - Dalsze przenoszenie aplikacji do Pythona 3
Czego potrzebujesz
- Projekt Google Cloud Platform z tymi elementami:
- podstawowe umiejętności w zakresie Pythona,
- Praktyczna znajomość typowych poleceń systemu Linux
- Podstawowa wiedza na temat tworzenia i wdrażania aplikacji App Engine
- działająca aplikacja App Engine z modułu 1;
Ankieta
Jak zamierzasz wykorzystać to ćwiczenie?
2. Tło
W module 1 przeprowadziliśmy migrację platform internetowych z wbudowanego środowiska webapp2 App Engine do Flask. W tym ćwiczeniu z programowania nadal odchodzimy od wbudowanych usług App Engine, przechodząc z biblioteki ndb App Engine na Cloud NDB od Google.
Po zakończeniu migracji możesz:
- Przejście na Pythona 3 i środowisko wykonawcze App Engine nowej generacji
- Migracja do Cloud Datastore (biblioteka klienta dla aplikacji innych niż App Engine)
- Skonteneryzuj aplikację w języku Python 2 (lub 3) i przenieś ją do Cloud Run.
- Dodaj korzystanie z kolejek zadań App Engine (push), a następnie przenieś je do Cloud Tasks.
Ale jeszcze do tego nie doszliśmy. Zanim przejdziesz do kolejnych kroków, dokończ ten codelab. Migracja opisana w tym samouczku obejmuje te główne kroki:
- Konfiguracja/przygotowanie
- Dodawanie biblioteki Cloud NDB
- Aktualizowanie plików aplikacji
3. Konfiguracja/przygotowanie
Zanim przejdziemy do głównej części samouczka, skonfigurujmy projekt, pobierzmy kod i wdrożymy aplikację podstawową, aby mieć pewność, że zaczynamy od działającego kodu.
1. Konfigurowanie projektu
Jeśli masz za sobą ćwiczenie z programowania w module 1, zalecamy ponowne użycie tego samego projektu (i kodu). Możesz też utworzyć zupełnie nowy projekt lub ponownie wykorzystać inny istniejący projekt. Sprawdź, czy projekt ma aktywne konto rozliczeniowe i czy usługa App Engine jest włączona.
2. Pobieranie przykładowej aplikacji podstawowej
Jednym z wymagań wstępnych jest działająca przykładowa aplikacja z modułu 1. Jeśli udało Ci się ukończyć ten samouczek, użyj swojego rozwiązania. Możesz to zrobić teraz (link powyżej) lub, jeśli chcesz pominąć ten krok, skopiuj repozytorium modułu 1 (link poniżej).
Niezależnie od tego, czy używasz własnego kodu, czy naszego, zaczniemy od kodu modułu 1. W tym module 2 znajdziesz szczegółowe instrukcje. Po jego ukończeniu kod powinien wyglądać jak kod w punkcie FINISH (w tym opcjonalny port „bonusowy” z Pythona 2 na Pythona 3):
- START: Kod modułu 1
- FINISH: Moduł 2 Kod w Pythonie 2 (DODATKOWO: kod w Pythonie 3)
- Całe repozytorium (do sklonowania lub pobrania pliku ZIP)
Folder z kodem modułu STARTing 1 powinien zawierać te elementy:
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
Jeśli wykonasz samouczek z modułu 1, będziesz mieć też folder lib z Flaskiem i jego zależnościami. Jeśli nie masz folderu lib, utwórz go za pomocą polecenia pip install -t lib -r requirements.txt, abyśmy mogli w następnym kroku wdrożyć tę podstawową aplikację. Jeśli masz zainstalowane obie wersje Pythona, zalecamy używanie polecenia pip2 zamiast pip, aby uniknąć pomyłki z Pythonem 3.
3. (Ponowne) wdrażanie aplikacji z modułu 1
Pozostałe czynności przygotowawcze, które musisz teraz wykonać:
- Przypomnij sobie, jak korzystać z narzędzia wiersza poleceń
gcloud(w razie potrzeby). - (Ponowne) wdrożenie kodu modułu 1 w App Engine (w razie potrzeby)
Po pomyślnym wykonaniu tych czynności i potwierdzeniu, że wszystko działa, przejdziemy do dalszej części tego samouczka, zaczynając od plików konfiguracyjnych.
4. Aktualizowanie plików konfiguracyjnych (dodawanie biblioteki Cloud NDB)
Wiele oryginalnych wbudowanych usług App Engine przekształciło się w osobne produkty, a Datastore jest jednym z nich. Obecnie aplikacje inne niż App Engine mogą korzystać z Cloud Datastore. Dla użytkowników, którzy od dawna korzystają z ndb, zespół Google Cloud stworzył bibliotekę klienta Cloud NDB do komunikacji z Cloud Datastore. Jest on dostępny w wersji dla Pythona 2 i 3.
Zaktualizujmy pliki potwierdzenia, aby zastąpić App Engine ndb Cloud NDB, a następnie zmodyfikujmy aplikację.
1. Zaktualizuj: requirements.txt
W module 1 jedyną zewnętrzną zależnością naszej aplikacji był Flask. Teraz dodamy Cloud NDB. Oto jak wyglądał plik requirements.txt na końcu modułu 1:
- PRZED:
Flask==1.1.2
Migracja z App Engine ndb wymaga biblioteki Cloud NDB (google-cloud-ndb), więc dodaj jej pakiet do requirements.txt.
- PO:
Flask==1.1.2
google-cloud-ndb==1.7.1
W momencie pisania tego samouczka najnowszą zalecaną wersją była 1.7.1, ale w repozytorium requirements.txt może być dostępna nowsza wersja. Zalecamy korzystanie z najnowszych wersji każdej biblioteki, ale jeśli nie działają, możesz wycofać zmiany do starszej wersji.
Usuń folder lib, jeśli go masz i nie został on utworzony w poprzednim kroku. Teraz (ponownie) zainstaluj zaktualizowane biblioteki za pomocą polecenia pip install -t lib -r requirements.txt, w razie potrzeby używając pip2 zamiast pip.
2. Zaktualizuj: app.yaml
Dodanie bibliotek klienta Google Cloud, takich jak google-cloud-ndb, wiąże się z kilkoma wymaganiami, które dotyczą włączenia „wbudowanych” bibliotek, czyli pakietów innych firm dostępnych już na serwerach Google. Nie wymieniasz ich w requirements.txt ani nie kopiujesz za pomocą pip install. Wymagania:
- Określanie wbudowanych bibliotek w
app.yaml - Wskaż im skopiowane biblioteki zewnętrzne, z którymi mogą pracować (w
lib).
Oto początkowy app.yaml z modułu 1:
- PRZED:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Teraz dodaj te wiersze do app.yaml, aby odwołać się do pary pakietów zewnętrznych: grpcio i setuptools w nowej sekcji libraries:
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
Dlaczego warto używać tych wbudowanych bibliotek? gRPC to otwarty framework RPC używany przez wszystkie biblioteki klienta Google Cloud, w tym google-cloud-ndb. Biblioteka grpcio to adapter gRPC w Pythonie, dlatego jest wymagana. Wyjaśnienie, dlaczego uwzględniamy symbol setuptools, znajdziesz poniżej.
- PO:
Po wprowadzeniu powyższych zmian zaktualizowany plik app.yaml powinien wyglądać tak:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
3. Zaktualizuj: appengine_config.py
Narzędzie pkg_resources, które jest częścią biblioteki setuptools, umożliwia wbudowanym bibliotekom innych firm dostęp do bibliotek dołączonych. Zaktualizuj appengine_config.py, aby używać pkg_resources i wskazywać dołączone biblioteki w lib. Po wprowadzeniu tej zmiany cały plik powinien wyglądać tak:
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
5. Aktualizowanie plików aplikacji
Po dopełnieniu formalności związanych z plikiem konfiguracyjnym możesz przeprowadzić migrację z ndb do Cloud NDB. Aby dokończyć migrację, zaktualizuj importowane biblioteki i dodaj użycie zarządzania kontekstem w main.py.
1. Importy
W pliku main.py zamień import na ten:
- PRZED
from google.appengine.ext import ndb
- PO:
from google.cloud import ndb
Zmiana biblioteki App Engine na bibliotekę Google Cloud może być czasami tak subtelna jak w tym przypadku. W przypadku wbudowanych usług, które stały się pełnymi produktami Google Cloud, atrybuty będziesz importować z google.cloud zamiast z google.appengine.
2. Dostęp do Datastore
Aby móc korzystać z biblioteki Cloud NDB, aplikacja musi używać menedżerów kontekstu Pythona. Ich celem jest „ograniczanie” dostępu do zasobów w taki sposób, aby można było z nich korzystać dopiero po ich uzyskaniu. Menedżerowie kontekstu opierają się na technice sterowania w informatyce znanej jako alokacja zasobów to inicjalizacja (Resource Allocation Is Initialization, RAII). Menedżery kontekstu są używane w przypadku plików Pythona (które muszą być otwarte, zanim będzie można uzyskać do nich dostęp) i równoczesności. Przed wykonaniem kodu w „sekcji krytycznej” należy uzyskać „blokady spinlock”.
Podobnie Cloud NDB wymaga uzyskania kontekstu klienta do komunikacji z Datastore, zanim będzie można wykonać jakiekolwiek polecenia Datastore. Najpierw utwórz klienta (ndb.Client()), dodając ds_client = ndb.Client() w main.py bezpośrednio po zainicjowaniu Flaska:
app = Flask(__name__)
ds_client = ndb.Client()
Polecenie Pythonwith służy wyłącznie do uzyskiwania kontekstu obiektu. Obejmij wszystkie bloki kodu, które uzyskują dostęp do Datastore, instrukcjami with.
Poniżej znajdziesz te same funkcje z modułu 1, które służą do zapisywania nowego obiektu w Datastore i odczytywania ostatnio dodanych obiektów w celu ich wyświetlenia:
- PRZED:
Oto oryginalny kod bez zarządzania kontekstem:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch(limit))
- PO:
Teraz dodaj with ds_client.context(): i przenieś kod dostępu do Datastore do bloku with:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch(limit))
Główna aplikacja sterownika pozostaje taka sama jak w module 1, ponieważ nie ma w niej kodu ndb (ani Cloud NDB):
@app.route('/')
def root():
'main application (GET) handler'
store_visit(request.remote_addr, request.user_agent)
visits = fetch_visits(10)
return render_template('index.html', visits=visits)
Sprawdzoną metodą jest zapewnienie wyraźnego rozróżnienia między kodem aplikacji a dostępem do danych. Dzięki temu główny kod aplikacji nie zmienia się, gdy zmieniamy podstawowy mechanizm przechowywania danych, tak jak w przypadku tej migracji.
6. Podsumowanie i czyszczenie
Wdróż aplikację
Ponownie wdróż aplikację za pomocą gcloud app deploy i sprawdź, czy działa. Twój kod powinien teraz być zgodny z kodem w repozytorium modułu 2.
Jeśli zaczniesz od tego artykułu, nie wykonując żadnych poprzednich ćwiczeń z programowania, aplikacja się nie zmieni. Będzie rejestrować wszystkie wizyty na głównej stronie internetowej (/) i po wystarczającej liczbie wizyt będzie wyglądać tak:

Gratulujemy ukończenia ćwiczenia z modułu 2. To już ostatnia z zdecydowanie zalecanych migracji z tej serii dotyczących Datastore.
Opcjonalnie: zwalnianie miejsca
A co z wyczyszczeniem danych, aby uniknąć opłat do czasu, aż będziesz gotowy(-a) na kolejny etap migracji? Jako obecni deweloperzy prawdopodobnie znasz już informacje o cenach App Engine.
Opcjonalnie: wyłączanie aplikacji
Jeśli nie chcesz jeszcze przechodzić do następnego samouczka, wyłącz aplikację, aby uniknąć naliczania opłat. Gdy zechcesz przejść do kolejnych ćwiczeń, możesz ponownie włączyć tę funkcję. Gdy aplikacja jest wyłączona, nie generuje ruchu, a tym samym nie powoduje naliczania opłat. Możesz jednak ponosić koszty związane z korzystaniem z Datastore, jeśli przekroczysz bezpłatny limit. W takim przypadku usuń wystarczającą ilość danych, aby zmieścić się w limicie.
Jeśli nie chcesz kontynuować migracji i chcesz wszystko całkowicie usunąć, możesz zamknąć projekt.
Dalsze kroki
Dalsze kroki zależą od Ciebie. Wybierz jedną z tych opcji:
- Moduł 2 (dodatkowy): przejdź do dodatkowej części tego samouczka, aby dowiedzieć się więcej o przenoszeniu aplikacji do Pythona 3 i środowiska wykonawczego App Engine nowej generacji.
- Moduł 7: kolejki zadań push App Engine (wymagane, jeśli używasz kolejek zadań [push])
- Dodaje zadania push App Engine
taskqueuedo aplikacji Moduł 1 - Przygotowuje użytkowników do migracji do Cloud Tasks w module 8.
- Dodaje zadania push App Engine
- Moduł 4. Migracja do Cloud Run za pomocą Dockera
- Konteneryzowanie aplikacji do uruchamiania w Cloud Run za pomocą Dockera
- Umożliwia pozostanie przy Pythonie 2
- Moduł 5. Migracja do Cloud Run za pomocą Cloud Buildpacks
- Konteneryzowanie aplikacji do uruchamiania w Cloud Run za pomocą pakietów kompilacji Cloud Build
- Nie musisz nic wiedzieć o Dockerze, kontenerach ani
Dockerfiles. - Wymaga przeniesienia aplikacji do Pythona 3.
- Moduł 3:
- Modernizacja dostępu do Datastore z Cloud NDB do Cloud Datastore
- Jest to biblioteka używana w przypadku aplikacji App Engine w Pythonie 3 i aplikacji spoza App Engine.
7. BONUS: Migracja do Pythona 3
Aby mieć dostęp do najnowszego środowiska wykonawczego i funkcji App Engine, zalecamy migrację do Pythona 3. W naszej przykładowej aplikacji Datastore była jedyną wbudowaną usługą, z której korzystaliśmy. Po przejściu z ndb na Cloud NDB możemy teraz przenieść aplikację do środowiska wykonawczego Pythona 3 w App Engine.
Przegląd
Przenoszenie kodu do języka Python 3 nie jest tematem samouczka Google Cloud, ale ta część laboratorium daje programistom wyobrażenie o tym, czym różni się środowisko wykonawcze App Engine w Pythonie 3. Jedną z najważniejszych funkcji środowiska wykonawczego nowej generacji jest uproszczony dostęp do pakietów innych firm. Nie musisz określać wbudowanych pakietów w app.yaml ani kopiować ani przesyłać bibliotek niewbudowanych. Są one instalowane niejawnie na podstawie informacji w requirements.txt.
Ponieważ nasz przykład jest bardzo prosty i Cloud NDB jest zgodny z Pythonem 2 i 3, nie trzeba przenosić kodu aplikacji do wersji 3.x. Aplikacja działa w wersjach 2.x i 3.x bez zmian, co oznacza, że w tym przypadku jedyne wymagane zmiany dotyczą konfiguracji:
- Uprość
app.yaml, aby odwoływać się do Pythona 3 i usunąć biblioteki innych firm. - Usuń
appengine_config.pyi folderlib, ponieważ nie są już potrzebne.
Oprócz pliku main.py pliki requirements.txt i templates/index.html pozostają bez zmian.
Uprość app.yaml
PRZED:
Jedyną prawdziwą zmianą w tej przykładowej aplikacji jest znaczne skrócenie app.yaml. Przypominamy, co mieliśmy w app.yaml na koniec Modułu 2:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
PO:
W Pythonie 3 dyrektywy threadsafe, api_version i libraries są przestarzałe. Zakłada się, że wszystkie aplikacje są bezpieczne dla wątków, a dyrektywa api_version nie jest używana w Pythonie 3. W usługach App Engine nie ma już wstępnie zainstalowanych pakietów innych firm, więc libraries też jest wycofany. Więcej informacji o tych zmianach znajdziesz w dokumentacji dotyczącej zmian w app.yaml. W związku z tym usuń wszystkie 3 wersje z app.yaml i zaktualizuj je do obsługiwanej wersji Pythona 3 (patrz poniżej).
Opcjonalnie: użycie dyrektywy handlers
Poza tym wycofana została dyrektywa handlers, która kieruje ruch do aplikacji App Engine. Środowisko wykonawcze nowej generacji oczekuje, że frameworki internetowe będą zarządzać routingiem aplikacji, dlatego wszystkie „skrypty obsługi” muszą zostać zmienione na „auto”. Łącząc powyższe zmiany, otrzymasz ten kod: app.yaml.
runtime: python38
handlers:
- url: /.*
script: auto
Dowiedz się więcej o script: auto na stronie dokumentacji.
Usuwanie dyrektywy handlers
Ponieważ element handlers jest wycofany, możesz też usunąć całą sekcję, pozostawiając jedno wierszowy element app.yaml:
runtime: python38
Domyślnie uruchomi to serwer WWW Gunicorn WSGI, który jest dostępny dla wszystkich aplikacji. Jeśli znasz gunicorn, to jest polecenie wykonywane, gdy jest ono uruchamiane domyślnie z najprostszym app.yaml:
gunicorn main:app --workers 2 -c /config/gunicorn.py
Opcjonalnie: użycie dyrektywy entrypoint
Jeśli jednak aplikacja wymaga określonego polecenia uruchamiania, można je określić za pomocą dyrektywy entrypoint, w której app.yaml wyglądałoby tak:
runtime: python38
entrypoint: python main.py
W tym przykładzie wyraźnie żądamy użycia serwera deweloperskiego Flask zamiast gunicorn. Do aplikacji należy też dodać kod, który uruchamia serwer deweloperski na interfejsie 0.0.0.0 na porcie 8080. W tym celu dodaj ten mały fragment na końcu pliku main.py:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Więcej informacji o entrypoint znajdziesz na stronie dokumentacji. Więcej przykładów i sprawdzonych metod znajdziesz w dokumentacji dotyczącej uruchamiania standardowego środowiska App Engine oraz w dokumentacji dotyczącej uruchamiania elastycznego środowiska App Engine.
Usuń: appengine_config.py i lib
Usuń plik appengine_config.py i folder lib. Podczas migracji do Pythona 3 App Engine pobiera i instaluje pakiety wymienione w requirements.txt.
Plik konfiguracyjny appengine_config.py służy do rozpoznawania bibliotek i pakietów innych firm, niezależnie od tego, czy zostały skopiowane przez Ciebie, czy są już dostępne na serwerach App Engine (wbudowane). Podczas przechodzenia na język Python 3 najważniejsze zmiany to:
- Brak pakietów skopiowanych bibliotek innych firm (wymienionych w
requirements.txt) - Brak
pip installw folderzelib, co oznacza, że nie ma folderulib. - Brak wbudowanych bibliotek zewnętrznych w
app.yaml - Nie trzeba odwoływać się do aplikacji w bibliotekach innych firm, więc nie ma pliku
appengine_config.py.
Wystarczy wymienić wszystkie wymagane biblioteki innych firm w requirements.txt.
Wdróż aplikację
Ponownie wdróż aplikację, aby mieć pewność, że działa. Możesz też sprawdzić, jak blisko Twoje rozwiązanie jest przykładowego kodu w Pythonie 3 z modułu 2. Aby zobaczyć różnice w Pythonie 2, porównaj kod z jego wersją w Pythonie 2.
Gratulujemy ukończenia kroku dodatkowego w module 2. Zapoznaj się z dokumentacją dotyczącą przygotowywania plików konfiguracyjnych dla środowiska wykonawczego Python 3. Na koniec zapoznaj się ze stroną Podsumowanie/Czyszczenie (wcześniejszą), aby poznać kolejne kroki i wykonać czyszczenie.
Przygotowywanie Twojej aplikacji
Gdy nadejdzie czas na migrację aplikacji, musisz przenieść pliki main.py i inne pliki aplikacji do wersji 3.x. Dlatego warto zadbać o to, aby aplikacja w wersji 2.x była jak najbardziej „kompatybilna z przyszłymi wersjami”.
W sieci znajdziesz wiele materiałów, które Ci w tym pomogą. Oto kilka najważniejszych wskazówek:
- Upewnij się, że wszystkie zależności aplikacji są w pełni zgodne z wersją 3.x.
- Upewnij się, że aplikacja działa w wersji co najmniej 2.6 (najlepiej 2.7).
- Upewnij się, że aplikacja przechodzi cały zestaw testów (i ma co najmniej 80% pokrycia).
- Korzystaj z bibliotek zgodności, takich jak
six, Future lub Modernize. - Poznaj najważniejsze różnice między wersjami 2.x i 3.x, które nie są ze sobą zgodne
- Każda operacja wejścia-wyjścia prawdopodobnie spowoduje niezgodności między ciągami Unicode a ciągami bajtów.
Aplikacja przykładowa została zaprojektowana z uwzględnieniem tych kwestii, dlatego działa od razu w wersjach 2.x i 3.x. Dzięki temu możemy skupić się na pokazaniu Ci, co należy zmienić, aby korzystać z platformy nowej generacji.
8. Dodatkowe materiały
Problemy i opinie dotyczące ćwiczeń z programowania modułu migracji App Engine
Jeśli zauważysz jakieś problemy z tym kursem, najpierw poszukaj rozwiązania, a dopiero potem zgłoś problem. Linki do wyszukiwania i tworzenia nowych problemów:
Materiały dotyczące migracji
Linki do folderów repozytorium dla modułu 1 (START) i modułu 2 (FINISH) znajdziesz w tabeli poniżej. Możesz też uzyskać do nich dostęp w repozytorium wszystkich migracji codelabów App Engine, które możesz sklonować lub pobrać jako plik ZIP.
Ćwiczenia z programowania | Python 2 | Python 3 |
(n/a) | ||
Moduł 2 |
Zasoby App Engine
Poniżej znajdziesz dodatkowe materiały dotyczące tej konkretnej migracji:
- Dokumentacja Python NDB
- (OLD) Migracja z Pythona 2.5 i
webappdo wersji 2.7 iwebapp2 - Przenoszenie do języka Python 3 i środowiska wykonawczego GAE nowej generacji
- Ogólne