Przeprowadź migrację do Cloud NDB App Engine w języku Python 2 & Aplikacja Cloud Tasks do Pythona 3 i Cloud Datastore (moduł 9)

1. Przegląd

Seria codelabów Serverless Migration Station (samodzielne, praktyczne samouczki) i powiązane z nimi filmy mają na celu pomóc deweloperom usług bezserwerowych Google Cloud w modernizacji aplikacji poprzez przeprowadzenie ich przez co najmniej jedną migrację, głównie z usług starszego typu. Dzięki temu Twoje aplikacje będą bardziej przenośne, a Ty zyskasz więcej opcji i elastyczności, co umożliwi Ci integrację z szerszą gamą usług w chmurze i łatwiejsze przechodzenie na nowsze wersje języka. Chociaż początkowo skupialiśmy się na pierwszych użytkownikach usług w chmurze, głównie na deweloperach App Engine (środowisko standardowe), ta seria jest wystarczająco szeroka, aby obejmować inne platformy bezserwerowe, takie jak Cloud FunctionsCloud Run, lub inne, jeśli ma to zastosowanie.

Celem tego laboratorium jest przeniesienie przykładowej aplikacji z modułu 8 do Pythona 3, a także zmiana dostępu do Datastore (Cloud Firestore w trybie Datastore) z Cloud NDB na natywną bibliotekę klienta Cloud Datastore i uaktualnienie do najnowszej wersji biblioteki klienta Cloud Tasks.

W module 7 dodaliśmy użycie kolejki zadań do zadań push, a następnie w module 8 przenieśliśmy to użycie do Cloud Tasks. W module 9 przechodzimy do Pythona 3 i Cloud Datastore. Użytkownicy korzystający z kolejek zadań do zadań typu pull przejdą na Cloud Pub/Sub i powinni zapoznać się z modułami 18–19.

Dowiesz się, jak:

  • Przenoszenie przykładowej aplikacji z modułu 8 do Pythona 3
  • Przełączanie dostępu do Datastore z Cloud NDB na biblioteki klienta Cloud Datastore
  • Uaktualnianie do najnowszej wersji biblioteki klienta Cloud Tasks

Czego potrzebujesz

Ankieta

Jak zamierzasz korzystać z tego samouczka?

Tylko przeczytaj Przeczytaj i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenie z Pythonem?

Początkujący Średnio zaawansowany Zaawansowany

Jak oceniasz korzystanie z usług Google Cloud?

Początkujący Średnio zaawansowany Zaawansowany

2. Tło

Moduł 7 pokazuje, jak używać zadań push w kolejce zadań App Engine w aplikacjach App Engine w języku Python 2 Flask. W module 8 przeniesiesz tę aplikację z kolejki zadań do Cloud Tasks. W module 9 kontynuujemy tę podróż i przenosimy aplikację do Pythona 3, a także zmieniamy dostęp do Datastore z Cloud NDB na natywną bibliotekę klienta Cloud Datastore.

Cloud NDB działa zarówno w przypadku Pythona 2, jak i 3, więc wystarczy użytkownikom App Engine, którzy przenoszą aplikacje z Pythona 2 na Pythona 3. Dodatkowa migracja bibliotek klienta do Cloud Datastore jest całkowicie opcjonalna i jest tylko jeden powód, dla którego warto ją rozważyć: masz aplikacje inne niż App Engine (lub aplikacje App Engine w Pythonie 3), które już korzystają z biblioteki klienta Cloud Datastore, i chcesz skonsolidować bazę kodu, aby uzyskiwać dostęp do Datastore za pomocą tylko jednej biblioteki klienta. Cloud NDB zostało stworzone specjalnie dla programistów App Engine w Pythonie 2 jako narzędzie do migracji do Pythona 3. Jeśli nie masz jeszcze kodu korzystającego z biblioteki klienta Cloud Datastore, nie musisz rozważać tej migracji.

Ostatnią kwestią jest to, że biblioteka klienta Cloud Tasks jest rozwijana tylko w Pythonie 3, więc „migrujemy” z jednej z ostatnich wersji Pythona 2 do jego współczesnej wersji w Pythonie 3. Na szczęście w porównaniu z Pythonem 2 nie ma żadnych istotnych zmian, więc nie musisz niczego robić.

Ten samouczek obejmuje te kroki:

  1. Konfiguracja/przygotowanie
  2. Aktualizacja konfiguracji
  3. Modyfikowanie kodu aplikacji

3. Konfiguracja/przygotowanie

Z tej sekcji dowiesz się, jak:

  1. Konfigurowanie projektu w chmurze
  2. Pobieranie przykładowej aplikacji podstawowej
  3. (Ponowne) wdrażanie i weryfikowanie aplikacji podstawowej

Dzięki tym czynnościom masz pewność, że zaczynasz od działającego kodu, który jest gotowy do migracji do usług w chmurze.

1. Konfigurowanie projektu

Jeśli masz za sobą laboratorium z modułu 8, użyj tego samego projektu (i kodu). Możesz też utworzyć zupełnie nowy projekt lub użyć innego istniejącego projektu. Upewnij się, że projekt ma aktywne konto rozliczeniowe i włączoną aplikację App Engine. Znajdź identyfikator projektu, ponieważ będzie Ci potrzebny podczas tego szkolenia. Używaj go zawsze, gdy napotkasz zmienną PROJECT_ID.

2. Pobieranie przykładowej aplikacji podstawowej

Jednym z wymagań wstępnych jest działająca aplikacja App Engine z modułu 8: wykonaj ćwiczenia z programowania z modułu 8 (zalecane) lub skopiuj aplikację z modułu 8 z repozytorium. Niezależnie od tego, czy używasz swojego kodu, czy naszego, zaczniemy od kodu modułu 8 („START”). W tym Codelabs dowiesz się, jak przeprowadzić migrację. Na końcu znajdziesz kod podobny do tego w folderze repozytorium modułu 9 („FINISH”).

Niezależnie od tego, której aplikacji z modułu 7 używasz, folder powinien wyglądać jak poniżej. Może też zawierać folder lib:

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

3. (Ponowne) wdrażanie i weryfikowanie aplikacji podstawowej

Aby wdrożyć aplikację z modułu 8, wykonaj te czynności:

  1. Usuń folder lib, jeśli istnieje, i uruchom polecenie pip install -t lib -r requirements.txt, aby ponownie wypełnić folder lib. Jeśli na komputerze używanym do programowania masz zainstalowane zarówno Pythona 2, jak i 3, może być konieczne użycie polecenia pip2.
  2. Sprawdź, czy narzędzie wiersza poleceń gcloud zostało zainstalowanezainicjowane oraz czy zapoznano się z jego użyciem.
  3. (opcjonalnie) Ustaw projekt w chmurze za pomocą polecenia gcloud config set project PROJECT_ID, jeśli nie chcesz wpisywać PROJECT_ID przy każdym poleceniu gcloud.
  4. Wdrażanie przykładowej aplikacji za pomocą gcloud app deploy
  5. Sprawdź, czy aplikacja działa zgodnie z oczekiwaniami i nie sprawia problemów. Jeśli udało Ci się ukończyć ćwiczenia z programowania w module 8, aplikacja wyświetli najważniejszych użytkowników wraz z najnowszymi wizytami (jak na ilustracji poniżej). U dołu znajduje się informacja o starszych zadaniach, które zostaną usunięte.

4aa8a2cb5f527079.png

4. Aktualizacja konfiguracji

requirements.txt

Nowy requirements.txt jest prawie taki sam jak w module 8, z jedną dużą zmianą: zastąp google-cloud-ndb elementem google-cloud-datastore. Wprowadź tę zmianę, aby plik requirements.txt wyglądał tak:

flask
google-cloud-datastore
google-cloud-tasks

Ten plik requirements.txt nie zawiera numerów wersji, co oznacza, że wybrane są najnowsze wersje. Jeśli wystąpią jakiekolwiek niezgodności, standardową praktyką jest używanie numerów wersji do blokowania działających wersji aplikacji.

app.yaml

Środowisko wykonawcze App Engine drugiej generacji nie obsługuje wbudowanych bibliotek innych firm, tak jak w przypadku wersji 2.x, ani kopiowania niewbudowanych bibliotek. Jedynym wymaganiem dotyczącym pakietów innych firm jest umieszczenie ich na liście w requirements.txt. W związku z tym cała sekcja librariesapp.yaml może zostać usunięta.

Kolejna zmiana polega na tym, że środowisko wykonawcze Python 3 wymaga używania platform internetowych, które same wykonują routing. W związku z tym wszystkie moduły obsługi skryptów muszą zostać zmienione na auto. Jednak ponieważ wszystkie trasy muszą zostać zmienione na auto, a ta przykładowa aplikacja nie obsługuje żadnych plików statycznych, nie ma znaczenia, czy są w niej jakiekolwiek moduły obsługi. Usuń więc również całą sekcję handlers.

app.yaml wystarczy ustawić środowisko wykonawcze na obsługiwaną wersję Pythona 3, np. 3.10. Wprowadź tę zmianę, aby nowa, skrócona wersja app.yaml składała się tylko z tego jednego wiersza:

runtime: python310

Usuwanie plików appengine_config.py i lib

Środowiska wykonawcze App Engine nowej generacji zmieniają sposób korzystania z pakietów innych firm:

  • Wbudowane biblioteki to biblioteki sprawdzone przez Google i udostępnione na serwerach App Engine, prawdopodobnie dlatego, że zawierają kod C/C++, którego deweloperzy nie mogą wdrażać w chmurze. Nie są one już dostępne w środowiskach wykonawczych 2 generacji.
  • Kopiowanie bibliotek wbudowanych (czasami nazywane „dostarczaniem” lub „samodzielnym pakowaniem”) nie jest już potrzebne w środowiskach wykonawczych drugiej generacji. Zamiast tego powinny być wymienione w requirements.txt, gdzie system kompilacji automatycznie zainstaluje je w Twoim imieniu w momencie wdrażania.

W wyniku tych zmian w zarządzaniu pakietami innych firm plik appengine_config.py ani folder lib nie są już potrzebne, więc je usuń. W środowiskach wykonawczych drugiej generacji App Engine automatycznie instaluje pakiety innych firm wymienione w requirements.txt. Podsumowywanie:

  1. Brak bibliotek innych firm w pakiecie lub skopiowanych; wymień je w requirements.txt
  2. Brak pip install w folderze lib, co oznacza, że nie ma folderu lib.
  3. Brak wbudowanych bibliotek innych firm w informacjach o produkcie (a tym samym brak sekcji libraries) w app.yaml; wymień je w requirements.txt
  4. Brak bibliotek innych firm, do których można się odwoływać w aplikacji, oznacza brak pliku appengine_config.py.

Wymaganiem dla dewelopera jest tylko wymienienie wszystkich żądanych bibliotek innych firm w requirements.txt.

5. Aktualizowanie plików aplikacji

Jest tylko jeden plik aplikacji, main.py, więc wszystkie zmiany w tej sekcji dotyczą tylko tego pliku. Poniżej znajduje się ilustracja „różnic” przedstawiająca ogólne zmiany, które należy wprowadzić, aby refaktoryzować istniejący kod w nową aplikację. Nie oczekujemy, że czytelnicy będą czytać kod wiersz po wierszu, ponieważ jego celem jest po prostu uzyskanie poglądowego przeglądu tego, co jest wymagane w tej refaktoryzacji (ale w razie potrzeby możesz otworzyć go w nowej karcie lub pobrać i powiększyć).

5d043768ba7be742.png

Aktualizowanie importów i inicjowanie

Sekcja importu w main.py w module 8 korzysta z Cloud NDB i Cloud Tasks i powinna wyglądać tak:

PRZED:

from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, tasks

app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()

W środowiskach wykonawczych drugiej generacji, takich jak Python 3, rejestrowanie jest uproszczone i ulepszone:

  • Aby uzyskać kompleksowe logowanie, użyj Cloud Logging.
  • Aby prosto rejestrować dane, wyślij je na adres stdout (lub stderr) za pomocą print().
  • Nie musisz używać modułu Pythona logging (więc go usuń).

W związku z tym usuń import logging i zamień google.cloud.ndb na google.cloud.datastore. Podobnie zmień ds_client, aby wskazywał klienta Datastore zamiast klienta NDB. Po wprowadzeniu tych zmian górna część nowej aplikacji będzie wyglądać tak:

PO:

from datetime import datetime
import json
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import datastore, tasks

app = Flask(__name__)
ds_client = datastore.Client()
ts_client = tasks.CloudTasksClient()

Migracja do Cloud Datastore

Teraz możesz zastąpić użycie biblioteki klienta NDB usługą Datastore. Zarówno App Engine NDB, jak i Cloud NDB wymagają modelu danych (klasy). W przypadku tej aplikacji jest to Visit. Funkcja store_visit() działa tak samo we wszystkich pozostałych modułach migracji: rejestruje wizytę, tworząc nowy rekord Visit, i zapisuje adres IP klienta odwiedzającego oraz jego agenta użytkownika (typ przeglądarki).

PRZED:

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'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

Cloud Datastore nie używa jednak klasy modelu danych, więc usuń tę klasę. Ponadto Cloud Datastore nie tworzy automatycznie sygnatury czasowej podczas tworzenia rekordów, co wymaga ręcznego wykonania tej czynności za pomocą wywołania datetime.now().

Bez klasy danych zmodyfikowany tag store_visit() powinien wyglądać tak:

PO:

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    entity = datastore.Entity(key=ds_client.key('Visit'))
    entity.update({
        'timestamp': datetime.now(),
        'visitor': '{}: {}'.format(remote_addr, user_agent),
    })
    ds_client.put(entity)

Główna funkcja to fetch_visits(). Nie tylko wykonuje pierwotne zapytanie o najnowsze Visit, ale też pobiera sygnaturę czasową ostatniego wyświetlonego Visit i tworzy zadanie push, które wywołuje /trim (a tym samym trim()), aby masowo usunąć stare Visit. Oto przykład użycia Cloud NDB:

PRZED:

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    with ds_client.context():
        data = Visit.query().order(-Visit.timestamp).fetch(limit)
    oldest = time.mktime(data[-1].timestamp.timetuple())
    oldest_str = time.ctime(oldest)
    logging.info('Delete entities older than %s' % oldest_str)
    task = {
        'app_engine_http_request': {
            'relative_uri': '/trim',
            'body': json.dumps({'oldest': oldest}).encode(),
            'headers': {
                'Content-Type': 'application/json',
            },
        }
    }
    ts_client.create_task(parent=QUEUE_PATH, task=task)
    return (v.to_dict() for v in data), oldest_str

Najważniejsze zmiany:

  1. Zastąp zapytanie Cloud NDB odpowiednikiem Cloud Datastore. Style zapytań różnią się nieznacznie.
  2. Datastore nie wymaga używania menedżera kontekstu ani wyodrębniania danych (za pomocą to_dict()), jak to ma miejsce w przypadku Cloud NDB.
  3. Zastępowanie logowania połączeń usługą print()

Po wprowadzeniu tych zmian fetch_visits() wygląda tak:

PO:

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    query = ds_client.query(kind='Visit')
    query.order = ['-timestamp']
    visits = list(query.fetch(limit=limit))
    oldest = time.mktime(visits[-1]['timestamp'].timetuple())
    oldest_str = time.ctime(oldest)
    print('Delete entities older than %s' % oldest_str)
    task = {
        'app_engine_http_request': {
            'relative_uri': '/trim',
            'body': json.dumps({'oldest': oldest}).encode(),
            'headers': {
                'Content-Type': 'application/json',
            },
        }
    }
    ts_client.create_task(parent=QUEUE_PATH, task=task)
    return visits, oldest_str

Zwykle to wystarczy. Niestety jest jeden poważny problem.

(Opcjonalnie) Utwórz nową kolejkę push

W module 7 dodaliśmy do istniejącej aplikacji z modułu 1 korzystanie z App Enginetaskqueue. Jedną z kluczowych zalet zadań typu push jako starszej funkcji App Engine jest to, że automatycznie tworzona jest „domyślna” kolejka. Gdy w module 8 aplikacja została przeniesiona do Cloud Tasks, ta domyślna kolejka już istniała, więc wciąż nie musieliśmy się nią wtedy przejmować. W module 9 to się zmienia.

Ważną kwestią jest to, że nowa aplikacja App Engine nie korzysta już z usług App Engine, więc nie możesz już zakładać, że App Engine automatycznie tworzy kolejkę zadań w innym produkcie (Cloud Tasks). Zgodnie z tym zapisem utworzenie zadania w fetch_visits() (dla nieistniejącej kolejki) nie powiedzie się. Potrzebna jest nowa funkcja, która sprawdzi, czy kolejka („default”) istnieje, a jeśli nie, utworzy ją.

Wywołaj tę funkcję _create_queue_if() i dodaj ją do aplikacji tuż nad fetch_visits(), ponieważ tam jest wywoływana. Treść funkcji do dodania:

def _create_queue_if():
    'app-internal function creating default queue if it does not exist'
    try:
        ts_client.get_queue(name=QUEUE_PATH)
    except Exception as e:
        if 'does not exist' in str(e):
            ts_client.create_queue(parent=PATH_PREFIX,
                    queue={'name': QUEUE_PATH})
    return True

Funkcja Cloud Tasks create_queue() wymaga pełnej ścieżki do kolejki z wyjątkiem nazwy kolejki. Aby uprościć kod, utwórz kolejną zmienną PATH_PREFIX reprezentującą QUEUE_PATH pomniejszoną o nazwę kolejki (QUEUE_PATH.rsplit('/', 2)[0]). Dodaj jej definicję u góry, aby blok kodu ze wszystkimi przypisaniami stałych wyglądał tak:

_, PROJECT_ID = google.auth.default()
REGION_ID = 'REGION_ID'    # replace w/your own
QUEUE_NAME = 'default'     # replace w/your own
QUEUE_PATH = ts_client.queue_path(PROJECT_ID, REGION_ID, QUEUE_NAME)
PATH_PREFIX = QUEUE_PATH.rsplit('/', 2)[0]

Teraz zmodyfikuj ostatni wiersz w pliku fetch_visits(), aby używać _create_queue_if(). Najpierw utwórz kolejkę (w razie potrzeby), a potem utwórz zadanie:

    if _create_queue_if():
        ts_client.create_task(parent=QUEUE_PATH, task=task)
    return visits, oldest_str

Zarówno _create_queue_if(), jak i fetch_visits() powinny teraz wyglądać w sumie tak:

def _create_queue_if():
    'app-internal function creating default queue if it does not exist'
    try:
        ts_client.get_queue(name=QUEUE_PATH)
    except Exception as e:
        if 'does not exist' in str(e):
            ts_client.create_queue(parent=PATH_PREFIX,
                    queue={'name': QUEUE_PATH})
    return True

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    query = ds_client.query(kind='Visit')
    query.order = ['-timestamp']
    visits = list(query.fetch(limit=limit))
    oldest = time.mktime(visits[-1]['timestamp'].timetuple())
    oldest_str = time.ctime(oldest)
    print('Delete entities older than %s' % oldest_str)
    task = {
        'app_engine_http_request': {
            'relative_uri': '/trim',
            'body': json.dumps({'oldest': oldest}).encode(),
            'headers': {
                'Content-Type': 'application/json',
            },
        }
    }
    if _create_queue_if():
        ts_client.create_task(parent=QUEUE_PATH, task=task)
    return visits, oldest_str

Poza koniecznością dodania tego dodatkowego kodu pozostała część kodu Cloud Tasks jest w większości taka sama jak w module 8. Ostatnim fragmentem kodu, na który warto zwrócić uwagę, jest procedura obsługi zadań.

Aktualizacja (push) modułu obsługi zadań

W funkcji obsługi zadań trim() kod Cloud NDB wysyła zapytanie o wizyty starsze niż najstarsza wyświetlana wizyta. Aby przyspieszyć działanie, używa zapytania dotyczącego tylko kluczy – po co pobierać wszystkie dane, jeśli potrzebne są tylko identyfikatory wizyt? Gdy uzyskasz wszystkie identyfikatory wizyt, usuń je wszystkie w partii za pomocą funkcji delete_multi() Cloud NDB.

PRZED:

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = float(request.get_json().get('oldest'))
    with ds_client.context():
        keys = Visit.query(
                Visit.timestamp < datetime.fromtimestamp(oldest)
        ).fetch(keys_only=True)
        nkeys = len(keys)
        if nkeys:
            logging.info('Deleting %d entities: %s' % (
                    nkeys, ', '.join(str(k.id()) for k in keys)))
            ndb.delete_multi(keys)
        else:
            logging.info(
                    'No entities older than: %s' % time.ctime(oldest))
    return ''   # need to return SOME string w/200

Podobnie jak w przypadku fetch_visits(), większość zmian polega na zastąpieniu kodu Cloud NDB kodem Cloud Datastore, dostosowaniu stylów zapytań, usunięciu użycia menedżera kontekstu i zmianie wywołań logowania na print().

PO:

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = float(request.get_json().get('oldest'))
    query = ds_client.query(kind='Visit')
    query.add_filter('timestamp', '<', datetime.fromtimestamp(oldest))
    query.keys_only()
    keys = list(visit.key for visit in query.fetch())
    nkeys = len(keys)
    if nkeys:
        print('Deleting %d entities: %s' % (
                nkeys, ', '.join(str(k.id) for k in keys)))
        ds_client.delete_multi(keys)
    else:
        print('No entities older than: %s' % time.ctime(oldest))
    return ''   # need to return SOME string w/200

Główny moduł obsługi aplikacji root() pozostaje bez zmian.

Przenoszenie do Pythona 3

Ta przykładowa aplikacja została zaprojektowana tak, aby działała zarówno w Pythonie 2, jak i 3. Wszelkie zmiany dotyczące Pythona 3 zostały omówione wcześniej w odpowiednich sekcjach tego samouczka. Nie są wymagane żadne dodatkowe czynności ani biblioteki zgodności.

Aktualizacja Cloud Tasks

Ostatnia wersja biblioteki klienta Cloud Tasks obsługująca Pythona 2 to 1.5.0. W momencie pisania tego artykułu najnowsza wersja biblioteki klienta dla Pythona 3 jest w pełni zgodna z tą wersją, więc nie wymaga dalszych aktualizacji.

Aktualizacja szablonu HTML

Nie musisz też wprowadzać żadnych zmian w pliku szablonu HTML templates/index.html. W ten sposób zakończysz wszystkie niezbędne zmiany, aby uzyskać aplikację z modułu 9.

6. Podsumowanie i czyszczenie

Wdrażanie i weryfikowanie aplikacji

Po wprowadzeniu zmian w kodzie, głównie przeniesieniu go do języka Python 3, wdróż aplikację za pomocą gcloud app deploy. Dane wyjściowe powinny być identyczne z aplikacjami z modułów 7 i 8, z tym wyjątkiem, że dostęp do bazy danych został przeniesiony do biblioteki klienta Cloud Datastore, a aplikacja została zaktualizowana do Pythona 3:

Moduł 7. Aplikacja visitme

W ten sposób zakończysz to ćwiczenie. Zachęcamy do porównania swojego kodu z kodem w folderze Moduł 9. Gratulacje!

Czyszczenie danych

Ogólne

Jeśli na razie nie chcesz już korzystać z usługi, zalecamy wyłączenie aplikacji App Engine, aby uniknąć naliczania opłat. Jeśli jednak chcesz przeprowadzić więcej testów lub eksperymentów, platforma App Engine ma bezpłatny limit, więc dopóki nie przekroczysz tego poziomu wykorzystania, nie powinny być naliczane żadne opłaty. Dotyczy to obliczeń, ale mogą też wystąpić opłaty za odpowiednie usługi App Engine, więc więcej informacji znajdziesz na stronie z cennikiem. Jeśli migracja obejmuje inne usługi w chmurze, są one rozliczane oddzielnie. W każdym przypadku, jeśli to konieczne, zapoznaj się z sekcją „Specyficzne dla tego laboratorium” poniżej.

Wdrożenie na bezserwerowej platformie obliczeniowej Google Cloud, takiej jak App Engine, wiąże się z niewielkimi kosztami kompilacji i przechowywania. 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 bezpłatnego pakietu, więc kontroluj wykorzystanie miejsca na dane, aby zminimalizować potencjalne koszty. Sprawdź te „foldery” Cloud Storage:

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • Linki do pamięci masowej powyżej zależą od PROJECT_ID i *LOC*acji, np. „us”, jeśli Twoja aplikacja jest hostowana w Stanach Zjednoczonych.

Jeśli nie zamierzasz kontynuować pracy z tą aplikacją ani innymi powiązanymi z nią samouczkami dotyczącymi migracji i chcesz wszystko całkowicie usunąć, wyłącz projekt.

Dotyczy tych ćwiczeń z programowania

Usługi wymienione poniżej są dostępne tylko w tym laboratorium. Więcej informacji znajdziesz w dokumentacji poszczególnych usług:

Dalsze kroki

To już koniec migracji zadań push z kolejki zadań App Engine do Cloud Tasks. Opcjonalna migracja z Cloud NDB do Cloud Datastore jest też omówiona osobno (bez kolejki zadań ani Cloud Tasks) w module 3. Oprócz modułu 3 istnieją inne moduły migracji, które koncentrują się na przejściu ze starszych usług pakietowych App Engine. Warto wziąć pod uwagę te moduły:

App Engine nie jest już jedyną platformą bezserwerową w Google Cloud. Jeśli masz małą aplikację App Engine lub aplikację o ograniczonej funkcjonalności i chcesz przekształcić ją w samodzielny mikroserwis albo podzielić aplikację monolityczną na wiele komponentów wielokrotnego użytku, warto rozważyć przejście na Cloud Functions. Jeśli konteneryzacja stała się częścią procesu tworzenia aplikacji, zwłaszcza jeśli obejmuje potok CI/CD (tryb ciągłej integracji/tryb ciągłego dostarczania lub wdrażanie), rozważ migrację do Cloud Run. Te scenariusze są omówione w tych modułach:

  • Migracja z App Engine do Cloud Functions: patrz moduł 11
  • Migracja z App Engine do Cloud Run: w module 4 dowiesz się, jak skonteneryzować aplikację za pomocą Dockera, a w module 5 – jak to zrobić bez kontenerów, wiedzy o Dockerze ani Dockerfiles

Przejście na inną platformę bezserwerową jest opcjonalne. Zanim wprowadzisz jakiekolwiek zmiany, zalecamy rozważenie najlepszych opcji dla Twoich aplikacji i przypadków użycia.

Niezależnie od tego, który moduł migracji wybierzesz, wszystkie materiały dotyczące Serverless Migration Station (ćwiczenia z programowania, filmy, kod źródłowy [jeśli jest dostępny]) znajdziesz w repozytorium open source. W repozytorium README znajdziesz też wskazówki dotyczące migracji, które warto rozważyć, oraz odpowiednią „kolejność” modułów migracji.

7. Dodatkowe materiały

Problemy z Codelabs lub opinie na ich temat

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 8 (START) i modułu 9 (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

Module 8

kod

(n/a)

Moduł 9

(n/a)

kod

Zasoby online

Poniżej znajdziesz zasoby online, które mogą być przydatne w tym samouczku:

App Engine

Cloud NDB

Cloud Datastore

Cloud Tasks

Inne informacje o chmurze

Licencja

To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.