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.
Celem tego ćwiczenia w Codelabs jest pokazanie programistom App Engine w języku Python 2, jak przejść z zadań pull kolejki zadań App Engine do Cloud Pub/Sub. Dostępna jest też migracja z App Engine NDB do Cloud NDB na potrzeby dostępu do Datastore (omówiona głównie w module 2), a także przejście na Pythona 3.
W module 18 dowiesz się, jak dodać do aplikacji zadania pull. W tym module ukończysz aplikację z modułu 18, a następnie przeprowadzisz migrację do Cloud Pub/Sub. Użytkownicy korzystający z kolejek zadań do wykonywania zadań push zamiast tego zostaną przeniesieni do Cloud Tasks i powinni zapoznać się z modułami 7–9.
Dowiesz się, jak:
- Zastąp korzystanie z kolejki zadań App Engine (zadania pull) usługą Cloud Pub/Sub
- Zastąp korzystanie z App Engine NDB za pomocą Cloud NDB (zobacz też moduł 2).
- Portowanie aplikacji w języku Python 3
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.
- Przykładowa aplikacja działającego modułu 18 App Engine
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
Kolejka zadań App Engine obsługuje zarówno zadania push, jak i pobieranie. Aby zwiększyć przenośność aplikacji, Google Cloud zaleca migrację ze starszych pakietów usług, takich jak kolejka zadań, do innych samodzielnych usług Cloud lub ich odpowiedników innych firm.
- Użytkownicy zadań push w kolejce zadań powinni przeprowadzić migrację do Cloud Tasks.
- Użytkownicy zadania pull kolejki zadań powinni przeprowadzić migrację do Cloud Pub/Sub.
Moduły 7–9 migracji obejmują migrację zadań push, a moduły 18–19 koncentrują się na migracji zadań pull. O ile Cloud Tasks odpowiada bliżej zadań push kolejki zadań, Pub/Sub nie jest aż tak zbliżony do zadań pull kolejki zadań.
Pub/Sub ma więcej funkcji niż funkcja pull dostępna w kolejce zadań. Na przykład Pub/Sub ma również funkcję push, jednak Cloud Tasks przypomina zadania push kolejki zadań, więc push Pub/Sub nie jest objęta żadnym modułem migracji. W tym ćwiczeniu z programowania w module 19 pokazujemy, jak przełączyć mechanizm kolejkowania z kolejek zadań do Pub/Sub oraz przejść z App Engine NDB do Cloud NDB w celu uzyskania dostępu do Datastore, powtarzając migrację modułu 2.
Chociaż kod modułu 18 jest „reklamowany” jako przykładowa aplikacja w języku Python 2, samo źródło jest zgodne z językiem Python 2 i 3 i pozostaje tak nawet po migracji do Cloud Pub/Sub (i Cloud NDB) w module 19.
W tym samouczku omawiamy następujące kroki:
- Konfiguracja/praca
- Aktualizacja konfiguracji
- Modyfikowanie kodu aplikacji
3. Konfiguracja/praca
W tej sekcji dowiesz się, jak:
- Konfigurowanie projektu Cloud
- Pobierz przykładową aplikację bazową
- (Ponowne) wdrażanie i weryfikowanie aplikacji bazowej
- Włącz nowe usługi i interfejsy API Google Cloud
Dzięki tym krokom masz pewność, że zaczynasz od działającego kodu i czy jest on gotowy do migracji do usług Cloud.
1. Konfigurowanie projektu
Jeśli masz już za sobą moduł 18 z programowania, wykorzystaj ponownie ten sam projekt (i kod). Możesz też utworzyć nowy projekt lub wykorzystać inny istniejący projekt. Sprawdź, czy projekt ma aktywne konto rozliczeniowe i włączoną aplikację App Engine. Znajdź identyfikator projektu, który będzie Ci potrzebny podczas tego ćwiczenia z programowania. Użyj go, gdy natrafisz na zmienną PROJECT_ID
.
2. Pobierz przykładową aplikację bazową
Jednym z warunków wstępnych jest działająca aplikacja z modułu 18 App Engine, więc wykonaj ćwiczenia z programowania (zalecane; link powyżej) lub skopiuj kod modułu 18 z repozytorium. Bez względu na to, czy używasz swoich czy naszych danych, od tego zaczniemy („START”). To ćwiczenie w Codelabs przeprowadzi Cię przez proces migracji, zakończy się kodem podobnym do tego, który znajduje się w folderze repozytorium modułu 19 („FINISH”).
- START: folder modułu 18 (Python 2)
- ZAKOŃCZ: folder modułu 19 (Python 2 i 3)
- Całe repozytorium (aby sklonować lub pobrać plik ZIP)
Niezależnie od tego, której aplikacji w module 18 używasz, folder powinien wyglądać tak jak poniżej (może być też zawierający folder lib
):
$ ls README.md appengine_config.py queue.yaml templates app.yaml main.py requirements.txt
3. (Ponowne) wdrażanie i weryfikowanie aplikacji bazowej
Aby wdrożyć aplikację w module 18, wykonaj te czynności:
- Usuń folder
lib
(jeśli istnieje), a następnie uruchom poleceniepip install -t lib -r requirements.txt
, aby ponownie uzupełnić danelib
. Jeśli na komputerze, na którym tworzysz aplikacje, masz zainstalowany język Python 2 i 3, może być konieczne użycie interfejsupip2
. - Upewnij się, że masz zainstalowane i zainicjowane narzędzie wiersza poleceń
gcloud
, a także sprawdź, jak używasz tego narzędzia. - (Opcjonalnie) Jeśli nie chcesz wpisywać
PROJECT_ID
przy każdym uruchamianym poleceniugcloud
, ustaw w swoim projekcie Cloud wartośćgcloud config set project
PROJECT_ID
. - Wdróż przykładową aplikację za pomocą:
gcloud app deploy
- Sprawdź, czy aplikacja działa prawidłowo, bez problemów. Jeśli udało Ci się ukończyć Moduł 18, aplikacja wyświetli najczęstszych użytkowników wraz z najnowszymi wizytami (poniżej). Jeśli nie, może nie być żadnej liczby użytkowników do wyświetlenia.
Przed migracją przykładowej aplikacji modułu 18 musisz najpierw włączyć usługi Cloud, których będzie używać zmodyfikowana aplikacja.
4. Włącz nowe usługi i interfejsy API Google Cloud
Stara aplikacja korzystała z pakietów App Engine, które nie wymagają dodatkowej konfiguracji, w przeciwieństwie do samodzielnych usług Cloud, które wymagają aktualizacji. Zaktualizowana aplikacja będzie wykorzystywać zarówno Cloud Pub/Sub, jak i Cloud Datastore (za pomocą biblioteki klienta Cloud NDB). Interfejsy App Engine i oba interfejsy API Cloud mają „Zawsze bezpłatne” poziomu. Jeśli będziesz go przekraczać, nie będziemy naliczać opłat za wykonanie tego samouczka. Interfejsy Cloud APIs można włączyć w konsoli Cloud lub z poziomu wiersza poleceń – w zależności od potrzeb.
W konsoli Google Cloud
Otwórz stronę biblioteki menedżera interfejsów API (odpowiedni projekt) w konsoli Cloud i za pomocą paska wyszukiwania na środku strony wyszukaj interfejsy Cloud Datastore i Cloud Pub/Sub API:
Kliknij przycisk Włącz oddzielnie dla każdego interfejsu API – może pojawić się prośba o podanie informacji rozliczeniowych. Oto przykładowa strona biblioteki Cloud Pub/Sub API:
Wiersz poleceń
Chociaż dobrze jest korzystać z interfejsu API w konsoli, niektórzy wolą używać wiersza poleceń. Uruchom polecenie gcloud services enable pubsub.googleapis.com datastore.googleapis.com
, aby włączyć oba interfejsy API jednocześnie:
$ gcloud services enable pubsub.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Może pojawić się prośba o podanie informacji rozliczeniowych. Jeśli chcesz włączyć inne interfejsy Cloud API i chcesz poznać ich identyfikatory URI, znajdziesz je u dołu strony z biblioteką każdego z interfejsów API. Na przykład obserwuj pubsub.googleapis.com
jako „Nazwę usługi” na dole strony Pub/Sub tuż powyżej.
Po wykonaniu tych czynności Twój projekt będzie miał dostęp do interfejsów API. Teraz czas zaktualizować aplikację, aby używała tych interfejsów API.
4. Tworzenie zasobów Pub/Sub
Podsumowanie procesu tworzenia kolejki zadań z modułu 18.
- Moduł 18 użył pliku
queue.yaml
do utworzenia kolejki pull o nazwiepullq
. - Aplikacja dodaje do kolejki pull zadania, które śledzą użytkowników.
- Zadania są ostatecznie przetwarzane przez pracownika i wynajmowane na określony czas (na godzinę).
- Wykonywane są zadania polegające na zliczaniu ostatnich użytkowników.
- Po zakończeniu zadania są usuwane z kolejki.
Zamierzasz powielić podobny przepływ pracy w Pub/Sub. W następnej sekcji przedstawimy podstawową terminologię Pub/Sub oraz 3 różne sposoby tworzenia niezbędnych zasobów Pub/Sub.
Terminologia Cloud Pub/Sub z kolejki zadań App Engine (pobieranie)
Przejście na Pub/Sub wymaga niewielkiego dostosowania słownika. Poniżej znajdziesz listę głównych kategorii wraz z odpowiednimi hasłami dotyczącymi obu usług. Zapoznaj się też z przewodnikiem po migracji, który zawiera podobne porównania.
- Tworzenie struktury danych w kolejce: w ramach kolejki zadań dane trafiają do kolejek pobierania. dzięki Pub/Sub dane trafiają do tematów.
- Jednostki danych w kolejce: zadania pobierania z kolejki zadań są nazywane wiadomościami w Pub/Sub.
- Podmioty przetwarzające dane: dzięki kolejki zadań pracownicy mają dostęp do zadań pull; używając Pub/Sub, do odbierania wiadomości potrzebujesz subskrybentów.
- Wyodrębnianie danych: dzierżawienie zadania pull jest jednoznaczne z pobieraniem wiadomości z tematu (za pomocą subskrypcji).
- Czyszczenie/ukończenie: usunięcie zadania z kolejki zadań z kolejki pull po zakończeniu jest analogiczne do potwierdzenia wiadomości Pub/Sub.
Chociaż usługa kolejkowania się zmienia, przepływ pracy pozostaje względnie podobny:
- Zamiast kolejki pull aplikacja używa tematu o nazwie
pullq
. - Zamiast dodawać zadania do kolejki pull, aplikacja wysyła wiadomości do tematu (
pullq
). - Zamiast instancji roboczej leasingu zadań z kolejki pull, subskrybent o nazwie
worker
pobiera wiadomości z tematupullq
. - Aplikacja przetwarza ładunki wiadomości, zwiększając liczbę użytkowników w Datastore.
- Zamiast usuwać zadania z kolejki pull, aplikacja potwierdza przetworzone wiadomości.
W przypadku kolejki zadań konfiguracja obejmuje utworzenie kolejki pull. Konfiguracja Pub/Sub wymaga utworzenia zarówno tematu, jak i subskrypcji. W module 18 przetworzyliśmy queue.yaml
poza wykonaniem aplikacji. to samo trzeba zrobić w przypadku Pub/Sub.
Dostępne są 3 opcje tworzenia tematów i subskrypcji:
- W konsoli Google Cloud
- z poziomu wiersza poleceń,
- Z kodu (krótki skrypt Pythona)
Wybierz jedną z poniższych opcji i postępuj zgodnie z odpowiednimi instrukcjami, aby utworzyć zasoby Pub/Sub.
W konsoli Google Cloud
Aby utworzyć temat w konsoli Cloud, wykonaj te czynności:
- Otwórz stronę tematów Pub/Sub w konsoli Cloud.
- Kliknij Utwórz temat u góry. otworzy się nowe okno (patrz obraz poniżej)
- W polu Identyfikator tematu wpisz
pullq
. - Odznacz wszystkie zaznaczone opcje i wybierz Klucz szyfrowania zarządzany przez Google.
- Kliknij przycisk Utwórz temat.
Okno tworzenia tematu wygląda tak:
Po utworzeniu tematu musisz utworzyć dla niego subskrypcję:
- Otwórz stronę subskrypcji Pub/Sub w konsoli Cloud.
- Kliknij Utwórz subskrypcję na górze (patrz ilustracja poniżej).
- W polu Identyfikator subskrypcji wpisz
worker
. - Wybierz
pullq
z menu Select a Cloud Pub/Sub topic (Wybierz temat Cloud Pub/Sub) z zachowaniem pełnej i odpowiedniej nazwy ścieżki. na przykładprojects/PROJECT_ID/topics/pullq
- W polu Typ dostawy wybierz Pociągnij.
- Pozostaw wszystkie inne opcje bez zmian i kliknij przycisk Utwórz.
Tak wygląda ekran tworzenia subskrypcji:
Subskrypcję możesz również utworzyć na stronie Tematy – ten „skrót” mogą być przydatne w powiązaniu tematów z subskrypcjami. Więcej informacji o tworzeniu subskrypcji znajdziesz w dokumentacji.
Wiersz poleceń
Użytkownicy Pub/Sub mogą tworzyć tematy i subskrypcje za pomocą poleceń gcloud pubsub topics create
TOPIC_ID
i gcloud pubsub subscriptions create
SUBSCRIPTION_ID
--topic=
TOPIC_ID
. Wykonanie tych poleceń z parametrem TOPIC_ID
o wartości pullq
i SUBSCRIPTION_ID
o wartości worker
daje w projekcie PROJECT_ID
takie dane wyjściowe:
$ gcloud pubsub topics create pullq Created topic [projects/PROJECT_ID/topics/pullq]. $ gcloud pubsub subscriptions create worker --topic=pullq Created subscription [projects/PROJECT_ID/subscriptions/worker].
Zapoznaj się też z tą stroną w krótkiej dokumentacji. Wiersz poleceń może uprościć przepływy pracy, w których tematy i subskrypcje są regularnie tworzone. W tym celu można stosować takie polecenia w skryptach powłoki.
Z kodu (krótki skrypt Pythona)
Innym sposobem automatyzacji tworzenia tematów i subskrypcji jest użycie interfejsu Pub/Sub API w kodzie źródłowym. Poniżej znajdziesz kod skryptu maker.py
z folderu repozytorium modułu 19.
from __future__ import print_function
import google.auth
from google.api_core import exceptions
from google.cloud import pubsub
_, PROJECT_ID = google.auth.default()
TOPIC = 'pullq'
SBSCR = 'worker'
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)
def make_top():
try:
top = ppc_client.create_topic(name=TOP_PATH)
print('Created topic %r (%s)' % (TOPIC, top.name))
except exceptions.AlreadyExists:
print('Topic %r already exists at %r' % (TOPIC, TOP_PATH))
def make_sub():
try:
sub = psc_client.create_subscription(name=SUB_PATH, topic=TOP_PATH)
print('Subscription created %r (%s)' % (SBSCR, sub.name))
except exceptions.AlreadyExists:
print('Subscription %r already exists at %r' % (SBSCR, SUB_PATH))
try:
psc_client.close()
except AttributeError: # special Py2 handler for grpcio<1.12.0
pass
make_top()
make_sub()
Wykonanie tego skryptu spowoduje wyświetlenie oczekiwanych danych wyjściowych (o ile nie będzie żadnych błędów):
$ python3 maker.py Created topic 'pullq' (projects/PROJECT_ID/topics/pullq) Subscription created 'worker' (projects/PROJECT_ID/subscriptions/worker)
Wywołanie interfejsu API w celu utworzenia już istniejących zasobów powoduje zgłoszenie wyjątku google.api_core.exceptions.AlreadyExists
zgłoszonego przez bibliotekę klienta. Obsługiwany jest w sposób płynny przez skrypt:
$ python3 maker.py Topic 'pullq' already exists at 'projects/PROJECT_ID/topics/pullq' Subscription 'worker' already exists at 'projects/PROJECT_ID/subscriptions/worker'
Jeśli nie masz doświadczenia z Pub/Sub, zapoznaj się z dokumentem na temat architektury Pub/Sub, aby uzyskać dodatkowe informacje.
5. Aktualizacja konfiguracji
Zmiany w konfiguracji obejmują zarówno zmianę różnych plików konfiguracji, jak i utworzenie odpowiednika kolejek pull App Engine, ale w ramach ekosystemu Cloud Pub/Sub.
Usuwanie pliku Que.yaml
Wycofujemy się całkowicie z kolejki zadań, więc usuń queue.yaml
, ponieważ Pub/Sub nie korzysta z tego pliku. Zamiast tworzyć kolejkę pull, możesz utworzyć temat (i subskrypcję) w Pub/Sub.
requirements.txt
Dołącz zarówno google-cloud-ndb
, jak i google-cloud-pubsub
do elementu requirements.txt
, tak aby złączyć flask
z Modułu 18. Twój zaktualizowany moduł 19 (requirements.txt
) powinien teraz wyglądać tak:
flask
google-cloud-ndb
google-cloud-pubsub
Ten plik requirements.txt
nie zawiera żadnych numerów wersji, co oznacza, że wybierane są najnowsze wersje. Jeśli wystąpią jakiekolwiek niezgodności, stosuj standardową metodę blokowania wersji roboczych aplikacji, używając numerów wersji.
app.yaml
Zmiany w języku app.yaml
różnią się w zależności od tego, czy chcesz pozostać w Pythonie 2, czy przejść na Pythona 3.
Python 2
W ramach powyższej aktualizacji requirements.txt
dodaliśmy biblioteki klienta Google Cloud. Wymagają one dodatkowej obsługi ze strony App Engine, czyli kilku bibliotek wbudowanych oraz setuptools
i grpcio
. Korzystanie z wbudowanych bibliotek wymaga sekcji libraries
w tagu app.yaml
i numerów wersji biblioteki lub atrybutu „najnowsza” . Moduł 18 app.yaml
nie zawiera jeszcze jednej z tych sekcji:
PRZED:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Dodaj sekcję libraries
do pliku app.yaml
wraz z wpisami dotyczącymi setuptools
i grpcio
, wybierając ich najnowsze wersje. W momencie pisania tego posta dodaj też symbol zastępczy runtime
dotyczący Pythona 3 wraz z obecną wersją 3.x, na przykład 3.10. Po wprowadzeniu tych zmian app.yaml
wygląda tak:
PO:
#runtime: python310
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: setuptools
version: latest
- name: grpcio
version: latest
Python 3
W przypadku użytkowników Pythona 3 i app.yaml
chodzi przede wszystkim o usuwanie różnych rzeczy. W tej sekcji usuniesz sekcję handlers
, dyrektywy threadsafe
i api_version
oraz nie utworzysz sekcji libraries
.
Środowiska wykonawcze drugiej generacji nie zawierają wbudowanych bibliotek zewnętrznych, więc sekcja libraries
nie jest potrzebna w systemie app.yaml
. Poza tym kopiowanie (nazywane czasem „dodawaniem do dostawców” lub „samodzielnym grupowaniem”) niewbudowanych pakietów innych firm nie jest już wymagane. Wystarczy, że w requirements.txt
zamieścisz listę bibliotek innych firm, z których korzysta Twoja aplikacja.
Sekcja handlers
w narzędziu app.yaml
służy do określania aplikacji (skryptu) i statycznych modułów obsługi plików. Ponieważ środowisko wykonawcze Pythona 3 wymaga platform internetowych do samodzielnego routingu, należy zmienić wszystkie moduły obsługi skryptów na auto
. Jeśli Twoja aplikacja (np. Moduł 18) nie obsługuje plików statycznych, wszystkie trasy miałyby postać auto
, przez co są nieistotne. Oznacza to, że sekcja handlers
też jest niepotrzebna, więc ją usuń.
W Pythonie 3 nie są używane dyrektywy threadsafe
ani api_version
, więc je też usuń. Najważniejsze jest, aby usunąć wszystkie sekcje app.yaml
, aby pozostała tylko dyrektywa runtime
określająca nowoczesną wersję Pythona 3, na przykład 3.10. Tak wygląda app.yaml
przed aktualizacją i po niej:
PRZED:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
PO:
runtime: python310
Dla użytkowników, którzy nie są gotowi na usunięcie wszystkiego z app.yaml
w języku Python 3, w folderze repozytorium modułu 19 udostępniliśmy alternatywny plik app3.yaml
. Jeśli chcesz użyć tego pliku we wdrożeniach, dołącz tę nazwę pliku na końcu polecenia: gcloud app deploy app3.yaml
(w przeciwnym razie aplikacja będzie domyślnie działać i wdrożona z niezmienionym plikiem Python 2 app.yaml
).
appengine_config.py
Jeśli aktualizujesz Pythona 3 do wersji 3, nie potrzebujesz dyrektywy appengine_config.py
, więc usuń ją. Nie jest to konieczne, ponieważ obsługa bibliotek zewnętrznych wymaga ich jedynie w polu requirements.txt
. Użytkownicy języka Python 2 – czytaj dalej.
Moduł 18 appengine_config.py
zawiera odpowiedni kod do obsługi bibliotek zewnętrznych, np. biblioteki Flask i biblioteki klienta Cloud dodane właśnie do requirements.txt
:
PRZED:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Jednak ten kod nie wystarczy do obsługi dodanych przed chwilą bibliotek wbudowanych (setuptools
, grpcio
). Potrzebnych jest jeszcze kilka wierszy, więc zaktualizuj appengine_config.py
, by wyglądał tak:
PO:
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)
Więcej informacji o zmianach wymaganych do obsługi bibliotek klienta Cloud znajdziesz w dokumentacji migracji pakietów usług.
Inne aktualizacje konfiguracji
Jeśli masz folder lib
, usuń go. Jeśli korzystasz z języka Python 2, uzupełnij folder lib
, wykonując to polecenie:
pip install -t lib -r requirements.txt # or pip2
Jeśli w Twoim systemie programistycznym masz zainstalowany język Python 2 i 3, może być konieczne użycie pip2
zamiast pip
.
6. Modyfikowanie kodu aplikacji
W tej sekcji znajdziesz informacje o aktualizacjach w głównym pliku aplikacji main.py
, które zastąpiły użycie kolejek pull kolejki zadań App Engine usługą Cloud Pub/Sub. W szablonie internetowym (templates/index.html
) nie wprowadzono żadnych zmian. Obie aplikacje powinny działać identycznie i wyświetlać te same dane.
Aktualizowanie importów i inicjowania
Wprowadzono kilka aktualizacji dotyczących importowania i inicjowania:
- Na potrzeby importu zastąp NDB i kolejkę zadań App Engine danymi Cloud NDB i Pub/Sub.
- Zmień nazwę
pullq
zQUEUE
naTOPIC
. - W przypadku zadań pobierania instancja robocza dzierżawi je na godzinę, ale w przypadku Pub/Sub limity czasu są mierzone na podstawie poszczególnych wiadomości, więc usuń stałą
HOUR
. - Interfejsy Cloud APIs wymagają użycia klienta API, więc inicjuj je dla Cloud NDB i Cloud Pub/Sub, a ten drugi będzie dostarczać klienty zarówno dla tematów, jak i subskrypcji.
- Pub/Sub wymaga identyfikatora projektu Cloud, więc zaimportuj go i pobierz z usługi
google.auth.default()
. - Pub/Sub wymaga „pełnych i jednoznacznych nazw ścieżek” dla tematów i subskrypcji, więc twórz je za pomocą wygodnych funkcji
*_path()
.
Poniżej znajdziesz informacje o importach i inicjowaniu z Modułu 18, a następnie, jak powinny wyglądać poszczególne sekcje po wprowadzeniu powyższych zmian, przy czym większość nowego kodu to różne zasoby Pub/Sub:
PRZED:
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb
HOUR = 3600
LIMIT = 10
TASKS = 1000
QNAME = 'pullq'
QUEUE = taskqueue.Queue(QNAME)
app = Flask(__name__)
PO:
from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, pubsub
LIMIT = 10
TASKS = 1000
TOPIC = 'pullq'
SBSCR = 'worker'
app = Flask(__name__)
ds_client = ndb.Client()
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
_, PROJECT_ID = google.auth.default()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)
Aktualizacje modelu danych wizyt
Model danych Visit
się nie zmienia. Dostęp do Datastore wymaga jawnego użycia menedżera kontekstu klienta Cloud NDB API (ds_client.context()
). W kodzie oznacza to opakowanie wywołań Datastore zarówno w store_visit()
, jak i fetch_visits()
wewnątrz bloków Pythona with
. Ta aktualizacja jest identyczna z informacjami omówionymi w module 2.
Najważniejsza zmiana w przypadku Pub/Sub polega na zastąpieniu zadania pobierania kolejki zadań publikacją wiadomości Pub/Sub w temacie pullq
. Poniżej znajduje się kod przed wprowadzeniem tych zmian i po ich wprowadzeniu:
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 in Datastore and queue request to bump visitor count'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
QUEUE.add(taskqueue.Task(payload=remote_addr, method='PULL'))
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)
def store_visit(remote_addr, user_agent):
'create new Visit in Datastore and queue request to bump visitor count'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
ppc_client.publish(TOP_PATH, remote_addr.encode('utf-8'))
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Aktualizacje modelu danych liczby użytkowników
Model danych VisitorCount
nie zmienia się i zmienia działanie fetch_counts()
z wyjątkiem pakowania zapytania Datastore w blok with
, jak pokazano poniżej:
PRZED:
class VisitorCount(ndb.Model):
visitor = ndb.StringProperty(repeated=False, required=True)
counter = ndb.IntegerProperty()
def fetch_counts(limit):
'get top visitors'
return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)
PO:
class VisitorCount(ndb.Model):
visitor = ndb.StringProperty(repeated=False, required=True)
counter = ndb.IntegerProperty()
def fetch_counts(limit):
'get top visitors'
with ds_client.context():
return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)
Zaktualizuj kod instancji roboczej
Kod instancji roboczej aktualizuje się aż do zastąpienia NDB przez Cloud NDB, a kolejka zadań na Pub/Sub, ale jego przepływ pracy pozostaje taki sam.
- Opakuj wywołania Datastore w bloku
with
menedżera kontekstu Cloud NDB. - Czyszczenie kolejki zadań obejmuje usunięcie z niej wszystkich zadań. W przypadku Pub/Sub „identyfikatory potwierdzenia” są zbierane w
acks
, a następnie usuwane/potwierdzone na końcu. - Zadania pull kolejki zadań są dzierżawione w podobny sposób, jak pobieranie wiadomości Pub/Sub. Usuwanie zadań pull odbywa się za pomocą samych obiektów zadań, a wiadomości Pub/Sub są usuwane za pomocą ich identyfikatorów potwierdzenia.
- Ładunki wiadomości Pub/Sub wymagają bajtów (nie ciągów Pythona), dlatego podczas publikowania i pobierania wiadomości z tematu jest odpowiednie kodowanie i dekodowanie UTF-8.
Zastąp log_visitors()
zaktualizowanym kodem poniżej, wprowadzając opisane poniżej zmiany:
PRZED:
@app.route('/log')
def log_visitors():
'worker processes recent visitor counts and updates them in Datastore'
# tally recent visitor counts from queue then delete those tasks
tallies = {}
tasks = QUEUE.lease_tasks(HOUR, TASKS)
for task in tasks:
visitor = task.payload
tallies[visitor] = tallies.get(visitor, 0) + 1
if tasks:
QUEUE.delete_tasks(tasks)
# increment those counts in Datastore and return
for visitor in tallies:
counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
if not counter:
counter = VisitorCount(visitor=visitor, counter=0)
counter.put()
counter.counter += tallies[visitor]
counter.put()
return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
len(tasks), len(tallies))
PO:
@app.route('/log')
def log_visitors():
'worker processes recent visitor counts and updates them in Datastore'
# tally recent visitor counts from queue then delete those tasks
tallies = {}
acks = set()
rsp = psc_client.pull(subscription=SUB_PATH, max_messages=TASKS)
msgs = rsp.received_messages
for rcvd_msg in msgs:
acks.add(rcvd_msg.ack_id)
visitor = rcvd_msg.message.data.decode('utf-8')
tallies[visitor] = tallies.get(visitor, 0) + 1
if acks:
psc_client.acknowledge(subscription=SUB_PATH, ack_ids=acks)
try:
psc_client.close()
except AttributeError: # special handler for grpcio<1.12.0
pass
# increment those counts in Datastore and return
if tallies:
with ds_client.context():
for visitor in tallies:
counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
if not counter:
counter = VisitorCount(visitor=visitor, counter=0)
counter.put()
counter.counter += tallies[visitor]
counter.put()
return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
len(msgs), len(tallies))
Nie zmienił się główny moduł obsługi aplikacji root()
. Nie musisz wprowadzać żadnych zmian w pliku szablonu HTML (templates/index.html
), więc obejmuje to wszystkie niezbędne aktualizacje. Gratulujemy dotarcia do nowej aplikacji modułu 19 wykorzystującej Cloud Pub/Sub.
7. Podsumowanie/Czyszczenie
Wdróż aplikację, aby sprawdzić, czy działa prawidłowo i w odpowiednich danych wyjściowych. Uruchom także instancję roboczą, aby przetworzyć liczbę użytkowników. Po sprawdzeniu aplikacji wykonaj czynności związane z czyszczeniem i zastanów się nad dalszymi czynnościami.
Wdróż i zweryfikuj aplikację
Sprawdź, czy masz już utworzony temat pullq
i subskrypcję worker
. Jeśli przykładowa aplikacja jest gotowa do użycia, wdróż ją za pomocą gcloud app deploy
. Dane wyjściowe powinny być takie same jak dane z aplikacji modułu 18, z wyjątkiem tego, że cały bazowy mechanizm kolejki został zastąpiony:
Internetowy frontend aplikacji weryfikuje teraz działanie tej części aplikacji. W tej części aplikacji użytkownicy wyszukują informacje oraz wyświetlają informacje o największych i ostatnich wizytach. Pamiętaj jednak, że aplikacja rejestruje tę wizytę razem z zadaniem pull, aby dodać tego użytkownika do łącznej liczby użytkowników. To zadanie oczekuje teraz na przetworzenie.
Możesz to zrobić, korzystając z usługi backendu App Engine, zadania cron
, przeglądając stronę /log
lub wysyłając żądanie HTTP z wiersza poleceń. Oto przykładowe wykonanie, które nie spowoduje wywołania kodu instancji roboczej za pomocą curl
(zastąp PROJECT_ID
):
$ curl https://PROJECT_ID.appspot.com/log DONE (with 1 task[s] logging 1 visitor[s])
Zaktualizowana liczba zostanie uwzględniona podczas następnej wizyty w witrynie. Znakomicie.
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:
- Różne komponenty Cloud Pub/Sub mają poziom bezpłatny. określić ogólne wykorzystanie, aby uzyskać więcej informacji na temat kosztów usługi i zapoznać się ze stroną z cennikiem.
- 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.
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 (zadań push) do Cloud Tasks
- Moduły 12–13: migracja z App Engine Memcache do Cloud Memorystore
- Moduły 15–16: migracja z App Engine Blobstore do Cloud Storage
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.
8. Dodatkowe materiały
Poniżej znajdziesz dodatkowe materiały dla deweloperów omawiające ten lub powiązany moduł migracji oraz powiązane usługi. Są to miejsca, w których można przesłać opinię o tych treściach, linki do kodu i różne artykuły, które mogą Ci się przydać.
Problemy/opinie dotyczące ćwiczeń z programowania
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 18 (START) i modułach 19 (FINISH) znajdziesz w tabeli poniżej.
Codelab | Python 2 | Python 3 |
(nd.) | ||
Moduł 19 (to ćwiczenia z programowania) | (tak samo jak w Pythonie 2, z wyjątkiem użycia app3.yaml, chyba że zaktualizujesz app.yaml w sposób opisany powyżej) |
Dokumentacja online
Poniżej znajdziesz informacje na temat tego samouczka:
Kolejka zadań App Engine
- Omówienie kolejki zadań App Engine
- Omówienie kolejek pull kolejki zadań App Engine
- Przykładowa pełna aplikacja do kolejki zadań App Engine
- Tworzenie kolejek pull dotyczących kolejki zadań
- Film o uruchamianiu kolejki pull Google I/O 2011 ( przykładowa aplikacja dla wyborców)
queue.yaml
– dokumentacja- Usługa
queue.yaml
a Cloud Tasks - Przewodnik po migracji Pub/Sub
Cloud Pub/Sub
- Strona usługi Cloud Pub/Sub
- Korzystanie z bibliotek klienta Pub/Sub
- Przykłady biblioteki klienta Pub/Sub w języku Python
- Dokumentacja biblioteki klienta Pub/Sub w Pythonie
- Twórz i zarządzaj tematami Pub/Sub
- Wytyczne dotyczące nazewnictwa tematów Pub/Sub
- Twórz i zarządzaj subskrypcjami Pub/Sub
- Przykładowa aplikacja App Engine (elastyczna) (możesz ją też wdrożyć w wersji Standard; Python 3)
- Repozytorium przykładowej aplikacji powyżej
- Subskrypcje pull Pub/Sub
- Subskrypcje push w Pub/Sub
- Przykładowa aplikacja push Pub/Sub App Engine (Python 3)
- Repozytorium przykładowej aplikacji typu push w App Engine Pub/Sub
- Informacje o cenach Pub/Sub
- Cloud Tasks czy Cloud Pub/Sub? (push vs. pull)
App Engine NDB i Cloud NDB (Datastore)
- Dokumentacja App Engine NDB
- Repozytorium App Engine NDB
- Dokumentacja Google Cloud NDB
- Repozytorium Google Cloud NDB
- Informacje o cenach Cloud Datastore
Platforma App Engine
- Dokumentacja App Engine
- Środowisko wykonawcze App Engine (środowisko standardowe) Pythona 2
- Korzystanie z wbudowanych bibliotek App Engine w Pythonie 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
- Przykłady migracji dokumentacji
- Przykłady 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
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.