Moduł 2. Migracja z App Engine ndb do Cloud NDB

1. Omówienie

Ta seria ćwiczeń z programowania (do samodzielnego ukończenia, praktycznych samouczków) ma pomóc deweloperom w modernizacji aplikacji korzystających z Google App Engine (wersja standardowa) przez przeprowadzenie serii migracji. Najważniejszym krokiem jest odejście od pierwotnych pakietów usług w ramach środowiska wykonawczego, ponieważ środowiska wykonawcze nowej generacji są bardziej elastyczne, co daje użytkownikom większą różnorodność opcji usług. Przejście na środowisko wykonawcze nowej generacji umożliwia łatwiejsze 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 biblioteki klienta ndb (Next Database) w App Engine do biblioteki klienta Cloud NDB.

Dowiesz się,

  • Użyj biblioteki ndb App Engine (jeśli jej nie znasz)
  • Migracja z usługi ndb do Cloud NDB
  • Przeprowadź migrację aplikacji do Pythona 3

Czego potrzebujesz

Ankieta

Jak będziesz używać tego ćwiczenia z programowania?

tylko do przeczytania. Przeczytaj go i wykonaj ćwiczenia
.

2. Tło

W części 1 przenieśliśmy platformy internetowe z wbudowanej platformy webapp2 App Engine do Flask. W ramach tego ćwiczenia w programie nadal odchodzimy od usług wbudowanych w App Engine, przechodząc z biblioteki ndb App Engine na Google Cloud NDB.

Podczas migracji możesz:

  1. Przejdź na Pythona 3 i środowisko wykonawcze App Engine nowej generacji
  2. Migracja do Cloud Datastore (biblioteka klienta dla aplikacji spoza App Engine)
  3. Umieść w kontenerze aplikację w języku Python 2 (lub 3) i przeprowadź migrację do Cloud Run.
  4. Dodaj informacje o kolejkach zadań App Engine (push) i przeprowadź migrację do Cloud Tasks

Ale jeszcze nie jesteśmy. Ukończ to ćwiczenie z programowania, zanim rozważysz kolejne kroki. W tym samouczku migracja obejmuje te główne kroki:

  1. Konfiguracja/praca
  2. Dodaj bibliotekę Cloud NDB
  3. Aktualizacja plików aplikacji

3. Konfiguracja/praca

Zanim przejdziemy do głównej części samouczka, skonfigurujmy nasz projekt, pobierz kod, a potem wdróż aplikację bazową. Dzięki temu będziemy wiedzieć, że zaczynamy od działającego kodu.

1. Konfigurowanie projektu

Jeśli masz już za sobą moduł 1 z programowania, 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 włączony jest App Engine.

2. Pobierz przykładową aplikację bazową

Jednym z warunków wstępnych jest posiadanie działającej przykładowej aplikacji w module 1. Użyj rozwiązania, jeśli udało Ci się ukończyć samouczek. Możesz to zrobić teraz (link powyżej), a jeśli chcesz je pominąć, skopiuj repozytorium modułu 1 (link poniżej).

Zacznijmy od kodu modułu 1 niezależnie od tego, czy używasz swojego czy naszego. To ćwiczenie w module 2 omówi każdy krok po kroku. Gdy proces zostanie ukończony, powinien przypominać kod w punkcie FINISH (zawierający opcjonalny port „bonus” z Pythona 2 do 3):

Folder z kodem modułu STARTing 1 powinien zawierać następującą zawartość:

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

Jeśli udało Ci się ukończyć samouczek modułu 1, będziesz też mieć folder lib z platformą Flask i jej 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 wdrożyć tę podstawową aplikację w następnym kroku. Jeśli masz zainstalowany język Python 2 i 3, zalecamy użycie pip2 zamiast pip, aby uniknąć nieporozumień z Pythonem 3.

3. Wdróż ponownie aplikację w module 1

Pozostałe kroki do wykonania:

  1. Ponownie zapoznaj się z narzędziem wiersza poleceń gcloud (w razie potrzeby)
  2. (Ponowne) wdrożenie kodu modułu 1 w App Engine (jeśli to konieczne)

Gdy wykonasz te czynności i potwierdzisz, że wszystko działa, przejdziemy do kolejnego samouczka, zaczynając od plików konfiguracji.

4. Zaktualizuj pliki konfiguracji (dodaj bibliotekę Cloud NDB)

Wiele oryginalnych usług wbudowanych w App Engine rozwinęło się we własnych usługach, a Datastore to jedna z nich. Obecnie aplikacje spoza App Engine mogą korzystać z Cloud Datastore. Dla wieloletnich użytkowników ndb zespół Google Cloud utworzył bibliotekę klienta Cloud NDB na potrzeby rozmów z Cloud Datastore. Jest dostępna w językach Python 2 i 3.

Zaktualizujmy pliki potwierdzenia, aby zastąpić App Engine ndb usługą Cloud NDB, a następnie zmodyfikować naszą aplikację.

1. Zaktualizuj: requirements.txt

W module 1 jedyną zależnością zewnętrzną w przypadku naszej aplikacji była Flask. Teraz dodamy Cloud NDB. Tak wyglądał Twój 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

Po napisaniu tego ćwiczenia w Codelabs najnowsza zalecana wersja to 1.7.1, ale requirements.txt w repozytorium może mieć nowszą wersję. Zalecamy najnowsze wersje każdej biblioteki, ale jeśli to nie zadziała, możesz przywrócić starszą wersję.

Usuń folder lib, jeśli masz taki folder, który nie został utworzony przez Ciebie powyżej. Teraz (ponownie) zainstaluj zaktualizowane biblioteki za pomocą polecenia pip install -t lib -r requirements.txt, używając w razie potrzeby pip2 zamiast pip.

2. Zaktualizuj: app.yaml

Dodanie bibliotek klienta Google Cloud, takich jak google-cloud-ndb, wiąże się z kilkoma wymaganiami. Wszystkie skupiają się wokół włączenia „wbudowanych” biblioteki, pakiety innych firm już dostępne na serwerach Google. Nie masz ich listy w języku: requirements.txt ani nie kopiujesz ich za pomocą usługi pip install. Jedyne wymagania:

  1. Określ wbudowane biblioteki w: app.yaml
  2. Wskaż im skopiowane biblioteki innych firm, z którymi mogą pracować (w lib)

Oto START app.yaml z Modułu 1:

  • PRZED:
runtime: python27
threadsafe: yes
api_version: 1

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

Teraz w nowej sekcji libraries dodaj do pliku app.yaml te wiersze: grpcio i setuptools:

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

Dlaczego warto korzystać z wbudowanych bibliotek? gRPC to otwarta platforma RPC używana przez wszystkie biblioteki klienta Google Cloud, w tym google-cloud-ndb. Biblioteka grpcio to adapter gRPC Pythona, więc jest niezbędna. Niedługo udostępnimy powód, dla którego warto uwzględnić setuptools.

  • PO:

Po wprowadzeniu powyższych zmian zaktualizowany 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 wchodzi w skład biblioteki setuptools, umożliwia udostępnianie wbudowanym bibliotekom innych firm w pakietach pakietów. Zaktualizuj plik appengine_config.py, aby używać zasady pkg_resources do wskazywania pakietów bibliotek w bibliotece lib. Po wprowadzeniu zmian 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. Aktualizacja plików aplikacji

Teraz nie musisz zajmować się formalnościami związanymi z plikami konfiguracji, więc możesz teraz przejść z ndb do Cloud NDB. Aby dokończyć migrację, zaktualizuj zaimportowane biblioteki i dodaj w main.py funkcję zarządzania kontekstem.

1. Importy

Zamień import w main.py:

  • PRZED
from google.appengine.ext import ndb
  • PO:
from google.cloud import ndb

Zmiana z biblioteki App Engine na bibliotekę Google Cloud jest czasami tak subtelna jak ta instancja. W przypadku usług wbudowanych, które stały się usługami Google Cloud, będziesz importować atrybuty z google.cloud, a nie z google.appengine.

2. Dostęp do Datastore

Aby można było korzystać z biblioteki Cloud NDB, aplikacja musi korzystać z menedżerów kontekstu Pythona. Ich celem jest „bramowanie” dostęp do zasobów, które trzeba nabyć, zanim będzie można z nich korzystać. Menedżerowie kontekstu działają w oparciu o technikę kontroli informatyczną zwaną Resource Allocation Is Zdarzenie inicjalizacji (inaczej RAII). Menedżerowie kontekstu są używane w przypadku plików w języku Python (które muszą być otwarte, aby można było uzyskać do nich dostęp) oraz równoczesności („blokad obrotowych”). należy pobrać przed kodem w „sekcji krytycznej” można wykonać.

Podobnie Cloud NDB wymaga pozyskania kontekstu klienta w celu komunikowania się z Datastore, zanim zostaną wykonane jakiekolwiek polecenia Datastore. Najpierw utwórz klienta (ndb.Client()), dodając ds_client = ndb.Client() w main.py bezpośrednio po zainicjowaniu Flask:

app = Flask(__name__)
ds_client = ndb.Client()

Polecenie Pythonwith służy wyłącznie do uzyskania kontekstu obiektu. Opakuj wszystkie bloki kodu uzyskujące dostęp do Datastore za pomocą instrukcji with.

Poniżej znajdziesz te same funkcje z modułu 1, które umożliwiają zapisywanie nowej encji w Datastore i wyświetlanie najnowszych dodanych encji:

  • 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 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 zawiera 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 ulegnie zmianie w wyniku zmiany bazowego mechanizmu przechowywania danych, tak jak w przypadku tej migracji.

6. Podsumowanie/Czyszczenie

Wdróż aplikację

Wdróż ponownie aplikację za pomocą narzędzia gcloud app deploy i sprawdź, czy działa. Twój kod powinien być teraz zgodny z informacjami w repozytorium modułu 2.

Jeśli dołączysz do tej serii bez wykonania żadnego z poprzednich ćwiczeń z programowania, aplikacja się nie zmieni. rejestruje wszystkie odwiedziny głównej strony internetowej (/) i wygląda tak po tym, jak kilka razy odwiedzisz witrynę:

aplikacja visitme

Gratulujemy ukończenia modułu 2 ćwiczenia z programowania. Właśnie przekraczasz metę, ponieważ jest to ostatnia z zdecydowanych migracji z tej serii, do której udało się dotrzeć w Datastore.

Opcjonalnie: wyczyść

A co z czyszczeniem, aby uniknąć opłat, dopóki nie wszystko będzie gotowe do przejścia do kolejnego ćwiczenia z programowania dotyczącego migracji? Jako obecni deweloperzy pewnie już znasz informacje o cenach w App Engine.

Opcjonalnie: wyłącz aplikację

Jeśli nie chcesz na razie przejść do następnego samouczka, wyłącz aplikację, aby uniknąć naliczania opłat. Gdy uznasz, że chcesz przejść do kolejnego ćwiczenia w programowaniu, możesz je ponownie włączyć. Gdy Twoja aplikacja jest wyłączona, nie generuje ona opłat za ruch, ale opłaty mogą być jednak naliczane za wykorzystanie magazynu danychw przypadku przekroczenia bezpłatnego limitu, więc usuń tyle miejsca, aby nie przekroczyć tego limitu.

Jeśli natomiast nie zamierzasz kontynuować migracji i chcesz całkowicie usunąć wszystko, możesz wyłączyć projekt.

Dalsze kroki

Teraz masz jeszcze swobodę wyboru, co możesz zrobić. Wybierz jedną z tych opcji:

  • Moduł 2 (Bonus). Przejdź do dodatkowej części tego samouczka, która dotyczy przenoszenia do Pythona 3 i środowiska wykonawczego App Engine nowej generacji.
  • Moduł 7. Kolejki zadań App Engine (wymagane, jeśli korzystasz z kolejek zadań [push])
    • Dodaje zadania push taskqueue w App Engine do aplikacji w module 1
    • Przygotowuje użytkowników do migracji do Cloud Tasks w module 8.
  • Moduł 4: Migracja do Cloud Run z wykorzystaniem Dockera
    • Konteneryzowanie aplikacji w celu uruchamiania jej w Cloud Run za pomocą Dockera
    • Pozwala na pozostanie w Pythonie 2
  • Moduł 5. Migracja do Cloud Run za pomocą pakietów Cloud Buildpacks
    • Konteneryzowanie aplikacji na potrzeby uruchamiania jej w Cloud Run za pomocą pakietów Cloud Buildpack
    • Nie musisz wiedzieć nic o Dockerze, kontenerach ani Dockerfile.
    • Wymaga wcześniejszej migracji aplikacji do Pythona 3
  • Część 3.
    • Modernizacja dostępu do Datastore z Cloud NDB na Cloud Datastore
    • To jest biblioteka używana na potrzeby aplikacji App Engine w Pythonie 3 i aplikacji innych niż App Engine

7. BONUS: przejdź na Pythona 3

Aby uzyskać dostęp do najnowszego środowiska wykonawczego i funkcji App Engine, zalecamy przejście na Pythona 3. W naszej przykładowej aplikacji Datastore był jedyną usługą wbudowaną, której użyliśmy, a ponieważ przeszliśmy z ndb na Cloud NDB, możemy teraz przenieść port do środowiska wykonawczego Pythona 3 App Engine.

Omówienie

Chociaż portowanie do Pythona 3 nie jest częścią samouczka Google Cloud, ta część ćwiczenia w Codelabs pozwala programistom poznać różnice między środowiskiem wykonawczym App Engine w języku Python 3. Wyjątkową cechą środowiska wykonawczego nowej generacji jest uproszczony dostęp do pakietów innych firm. nie trzeba określać pakietów wbudowanych w app.yaml ani kopiować ani przesyłać niewbudowanych bibliotek; są domyślnie instalowane z poziomu listy requirements.txt.

Nasz przykład jest tak podstawowy, a Cloud NDB jest zgodny z językiem Python 2–3, więc nie trzeba jawnie przenosić kodu aplikacji do wersji 3.x. aplikacja działa na platformach 2.x i 3.x bez modyfikacji, co oznacza, że w tym przypadku wymagane zmiany są tylko w konfiguracji:

  1. Uprość kod app.yaml, aby odwoływać się do Pythona 3 i usuwać biblioteki zewnętrzne.
  2. Usuń appengine_config.py i folder lib, ponieważ nie są już potrzebne.

Oprócz main.py pliki requirements.txt i templates/index.html pozostają niezmienione.

Uprość: app.yaml

PRZED:

Jedyną rzeczywistą zmianą w tej przykładowej aplikacji jest znaczne skrócenie wartości app.yaml. Przypominam, że omówiliśmy temat app.yaml na zakończenie 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 zostały wycofane. Wszystkie aplikacje są uznawane za bezpieczne wątkowo, a zasada api_version nie jest używana w Pythonie 3. W usługach App Engine nie ma już wbudowanych pakietów innych firm, dlatego pakiet libraries również został wycofany. Więcej informacji o tych zmianach znajdziesz w dokumentacji zmian w app.yaml. W związku z tym usuń wszystkie 3 elementy z app.yaml i zaktualizuj je do obsługiwanej wersji Pythona 3 (patrz poniżej).

Opcjonalnie: użycie dyrektywy handlers

Poza tym dyrektywa handlers, która kieruje ruch do aplikacji App Engine, również została wycofana. Środowisko wykonawcze nowej generacji oczekuje, że platformy internetowe będą zarządzać routingiem aplikacji, dlatego wszystkie „skrypty obsługi” należy zmienić na „auto”. Po połączeniu powyższych zmian otrzymasz następującą liczbę elementów app.yaml:

runtime: python38

handlers:
- url: /.*
  script: auto

Więcej informacji o usłudze script: auto znajdziesz na stronie dokumentacji.

Usuwam dyrektywę handlers

Ponieważ interfejs handlers został wycofany, możesz też usunąć całą sekcję, pozostawiając jednowierszowy app.yaml:

runtime: python38

Domyślnie uruchamiany jest serwer WWW Gunicorn WSGI, który jest dostępny dla wszystkich aplikacji. Jeśli znasz język gunicorn, oto polecenie wykonywane, gdy jest uruchamiane domyślnie z bonusem app.yaml:

gunicorn main:app --workers 2 -c /config/gunicorn.py

Opcjonalnie: użycie dyrektywy entrypoint

Jeśli jednak Twoja aplikacja wymaga konkretnego polecenia uruchamiania, można je podać za pomocą dyrektywy entrypoint, gdzie element app.yaml będzie wyglądać tak:

runtime: python38
entrypoint: python main.py

W tym przykładzie konkretnie zażądano użycia serwera programistycznego Flask zamiast gunicorn. Kod uruchamiający serwer programistyczny należy również dodać do aplikacji w interfejsie 0.0.0.0 na porcie 8080. W tym celu dodaj tę małą sekcję na dole kodu main.py:

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

Więcej informacji o usłudze entrypoint znajdziesz na stronie dokumentacji. Więcej przykładów i sprawdzonych metod znajdziesz w dokumentach dotyczących startupów w standardowym środowisku App Engine oraz w dokumentach dotyczących 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 pozyskuje i instaluje pakiety wymienione w regionie requirements.txt.

Plik konfiguracyjny appengine_config.py służy do rozpoznawania bibliotek/pakietów innych firm, niezależnie od tego, czy zostały one skopiowane przez Ciebie, czy też używasz już istniejących na serwerach App Engine (wbudowanych). Podsumowanie najważniejszych zmian po przejściu do Pythona 3:

  1. Nie pakuję skopiowanych bibliotek innych firm (wymienionych w regionie requirements.txt)
  2. Brak elementów pip install do folderu lib, co oznacza brak okresu folderu lib
  3. Brak informacji o wbudowanych bibliotekach innych firm w app.yaml
  4. Nie trzeba odwoływać się do bibliotek innych firm, więc nie ma pliku appengine_config.py

Wystarczy, że umieścisz w pliku requirements.txt listę wszystkich wymaganych bibliotek innych firm.

Wdróż aplikację

Wdróż aplikację ponownie, aby sprawdzić, czy działa. Możesz też sprawdzić, jak blisko Twojego rozwiązania jest przykładowy kod w module 2 w Pythonie 3. Aby zwizualizować różnice w stosunku do języka Python 2, porównaj ten kod z jego wersją w języku Python 2.

Gratulacje! Udało Ci się ukończyć bonusowy krok w module 2. Zapoznaj się z dokumentacją dotyczącą przygotowywania plików konfiguracji na potrzeby środowiska wykonawczego Pythona 3. Na koniec przejrzyj (wcześniejszą) stronę Podsumowanie/Czyszczenie, aby poznać następne kroki i wyczyścić dane.

Przygotowywanie Twojej aplikacji

Przy migrowaniu swojej aplikacji trzeba będzie przenieść main.py i inne pliki aplikacji do wersji 3.x, więc najlepiej jest postarać się, aby aplikacja 2.x była „zgodna do przekazywania dalej”. jak to tylko możliwe.

W internecie znajdziesz wiele materiałów, które Ci w tym pomogą. Oto kilka najważniejszych wskazówek:

  1. Sprawdź, czy wszystkie zależności aplikacji są w pełni zgodne z wersją 3.x
  2. Upewnij się, że aplikacja działa w wersji 2.6 (najlepiej 2.7).
  3. Sprawdź, czy aplikacja przeszła cały pakiet testów (i co najmniej 80% pokrycia)
  4. Używaj bibliotek zgodności, takich jak six, Future lub Modernize
  5. Zdobądź wiedzę na temat niekompatybilności wstecznej kluczy w wersjach 2.x i 3.x
  6. Każde wejście/wyjście prawdopodobnie prowadzi do niezgodności z Unicode i ciągami bajtów.

Właśnie dlatego została opracowana przykładowa aplikacja, dlatego działa na 2.x i 3.x.

8. Dodatkowe materiały

Problemy/opinie dotyczące modułu migracji App Engine

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 dla modułów 1 (START) i modułów 2 (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ęść 1

kod

(nd.)

Część 2

kod

kod

Zasoby App Engine

Poniżej znajdziesz dodatkowe materiały na temat tej migracji: