Google PCD: Architektura aplikacji cloud-native oraz wybór usług — Przewodnik do nauki
Część Google Professional Cloud Developer — Przewodnik do nauki. Ćwicz ze zweryfikowanymi odpowiedziami w centrum egzaminów Google, albo rozwiąż testy na czas na ExamRoll.io.
Przegląd
Architektura aplikacji natywnych dla chmury w Google Cloud koncentruje się na budowaniu bezstanowych, odpornych usług, które skalują się horyzontalnie, minimalizują wysiłek operacyjny i wykorzystują usługi zarządzane tam, gdzie jest to właściwe. Efektywny dobór usług wymaga zrozumienia kompromisów między kontrolą, przenośnością, wydajnością, kosztem i odpowiedzialnością operacyjną. Ta sekcja przedstawia zasady i wzorce, które pomagają projektować, modernizować i obsługiwać aplikacje dla globalnych użytkowników z przewidywalną niezawodnością.
Zasady i wybory architektoniczne w podejściu Cloud-Native
Projektowanie bezstanowe i zgodne z metodyką dwunastu czynników (Twelve-Factor App)
- Baza kodu, zależności i cykl build-release-run: Przypinaj dokładne wersje zależności, twórz niezmienne artefakty i oddzielaj proces budowania od wydawania. Obrazy kontenerów i potoki Cloud Build wymuszają powtarzalność wydań.
- Konfiguracja w środowisku: Eksternalizuj konfigurację za pomocą zmiennych środowiskowych, Secret Manager, Kubernetes Secrets lub metadanych instancji Compute Engine. Nie umieszczaj na stałe w obrazach poświadczeń ani ustawień specyficznych dla wdrożenia. W przypadku zarządzanych grup instancji Compute Engine używaj metadanych szablonu instancji do przekazywania wartości dla danego wdrożenia.
- Usługi wspierające (backing services): Traktuj bazy danych, kolejki i pamięci podręczne jako dołączone zasoby. Preferuj usługi zarządzane (Cloud SQL, Cloud Spanner, Firestore, Memorystore, Pub/Sub), aby zmniejszyć obciążenie operacyjne.
- Procesy bezstanowe: Skaluj przez dodawanie instancji; przechowuj stan sesji zewnętrznie (Memorystore for Redis, Firestore lub Spanner). Zapisuj logi na stdout/stderr lub do plików logów zbieranych przez agenta Cloud Logging.
- Jednorazowość (disposability): Szybkie uruchamianie/zamykanie umożliwia błyskawiczne skalowanie i aktualizacje wdrożeń (rolling updates). Obsługuj sygnał SIGTERM w celu płynnego zamknięcia.
- Logi jako strumienie zdarzeń: Emituj logi strukturalne; używaj Cloud Logging do ich pozyskiwania i Cloud Monitoring do alertowania.
Kompromisy architektoniczne
- Monolit
- Zalety: Uproszczony rozwój i testowanie, mniej granic sieciowych, pojedyncza jednostka wdrożeniowa.
- Wady: Wolniejsze niezależne dostarczanie, ograniczenia skalowalności, silne powiązania między domenami.
- Tryby awarii: Jedna intensywnie używana ścieżka może zużyć współdzielone zasoby; regresje wpływają na wszystkie funkcje.
- Monolit modułowy
- Zalety: Wyraźne granice między wewnętrznymi modułami, ścieżka refaktoryzacji w kierunku usług, pojedynczy artefakt wdrożeniowy.
- Wady: Wciąż ograniczony przez monolityczne wdrożenie i bazę danych.
- Stosuj w zespołach, które dopracowują granice domen przed wydzieleniem usług.
- Mikrousługi
- Zalety: Niezależne wdrażanie, celowane skalowanie, autonomia zespołów, izolacja awarii przy użyciu odpowiednich przegród (bulkheads).
- Wady: Złożoność systemów rozproszonych, spójność, obserwowalność i narzut operacyjny.
- Tryby awarii: Awarie kaskadowe przez wywołania synchroniczne; dryf schematu; nadmierna komunikacja sieciowa.
- Architektura sterowana zdarzeniami
- Zalety: Luźne powiązania, odporność dzięki asynchroniczności, naturalne buforowanie, audytowalność poprzez logi/strumienie.
- Wady: Złożoność debugowania, spójność ostateczna (eventual consistency), trudności w zapewnieniu kolejności i semantyki „dokładnie raz” (exactly-once).
- Pub/Sub zapewnia dostarczanie „co najmniej raz” (at-least-once); projektuj idempotentnych konsumentów.
- Architektura bezserwerowa (Serverless) (Cloud Run, Cloud Functions, App Engine)
- Zalety: Minimalny wysiłek operacyjny, skalowanie do zera, autoskalowanie per żądanie, zintegrowane bezpieczeństwo i telemetria.
- Wady: Limity czasu wykonania i współbieżności, zimne starty, ograniczenia specyficzne dla platformy.
- Stosuj dla obciążeń o charakterze szczytowym, backendów mobilnych/webowych i przetwarzania zdarzeń.
- Monolit
Wzorce komunikacji i dobór usług
Wywołania synchroniczne a asynchroniczne
- Synchroniczne
- Używaj dla API typu żądanie/odpowiedź (request/response) wymagających natychmiastowych wyników.
- Protokoły: gRPC (HTTP/2, streaming, kompaktowy Protobuf; doskonały dla ograniczonej przepustowości mobilnej i silnych kontraktów), HTTP/JSON (szeroka kompatybilność; prostsze debugowanie).
- Ryzyka: Silne powiązania i wzmacnianie opóźnień; stosuj limity czasu (timeouts), ponowienia z losowym opóźnieniem (jitter) i wyłączniki (circuit breakers).
- Asynchroniczne
- Używaj Pub/Sub lub Cloud Tasks, gdy praca może być odroczona lub przetwarzana wsadowo.
- Korzyści: Wygładza skoki obciążenia, izoluje awarie, poprawia odczuwalne przez użytkownika opóźnienie dzięki ostatecznemu zakończeniu operacji.
- Ryzyka: Wymaga idempotentności i akcji kompensujących; należy zbudować mechanizmy wglądu w zadania w toku.
- Synchroniczne
Kryteria doboru usług w Google Cloud
- Kontrola i przenośność
- Compute Engine: Pełna kontrola nad maszyną wirtualną i niestandardowe obrazy; większe obciążenie operacyjne.
- GKE: Przenośne kontenery i opcje service mesh; solidne autoskalowanie; współdzielona odpowiedzialność.
- Cloud Run: Wysoka przenośność dla kontenerów przy minimalnym wysiłku operacyjnym; skalowanie do zera; zorientowany na żądania.
- App Engine: Ukierunkowana platforma PaaS z wbudowanym routingiem i skalowaniem; najszybsza ścieżka dla niektórych języków.
- Skala i opóźnienia
- Globalny HTTP(S) Load Balancing z Cloud CDN dla akceleracji na brzegu sieci (edge).
- Magazyny danych:
- Cloud Spanner: Globalna spójność, skalowanie horyzontalne, dostępność 99,999% w trybie wieloregionalnym.
- Cloud SQL: Zarządzana relacyjna baza danych, regionalna, repliki do odczytu (w tym międzyregionalne).
- Firestore: Dokumentowa baza danych z globalną dostępnością w trybie wieloregionalnym, silna spójność dla pojedynczych dokumentów.
- Cloud Bigtable: Niskie opóźnienia, ogromna skala dla zastosowań szerokokulumnowych.
- Memorystore: Niskie opóźnienia pamięci podręcznej dla intensywnie używanych ścieżek i sesji.
- Odpowiedzialność operacyjna
- Preferuj usługi zarządzane w kluczowych obszarach (dostępność, instalowanie poprawek, kopie zapasowe, aktualizacje).
- Samodzielne zarządzanie oferuje elastyczność, ale zwiększa wysiłek operacyjny i powierzchnię ataku/awarii (np. samodzielnie hostowana Kafka vs Pub/Sub).
- Przenoszenie i integracja danych
- Używaj łączności natywnej dla VPC, Private Service Connect i wewnętrznego HTTP(S) Load Balancing dla prywatnego dostępu z niskimi opóźnieniami.
- Odnajdywanie usług (Service discovery): Nazwy usług Kubernetes wewnątrz klastra; wewnętrzny DNS Compute Engine dla maszyn wirtualnych.
- Kontrola i przenośność
Przykład usługi Kubernetes (odnajdywanie nazw wewnątrz klastra): apiVersion: v1 kind: Service metadata: name: image-resize spec: selector: app: image-resize ports:
- port: 80 targetPort: 8080 type: ClusterIP
Granice, kompatybilność i wzorce niezawodności
Granice domen i odpowiedzialność
- Używaj Domain-Driven Design do definiowania ograniczonych kontekstów (bounded contexts). Każda usługa jest właścicielem swoich danych i publikuje API/zdarzenia jako kontrakty.
- Unikaj współdzielonych baz danych między usługami; używaj dobrze zdefiniowanych interfejsów i propagacji zdarzeń.
- Własność (ownership) pociąga za sobą odpowiedzialność za dyżury (on-call), SLO, cykl wydawniczy i budżet dla każdej usługi.
Kontrakty API i kompatybilność wsteczna
- Jawnie wersjonuj API (np. v1 w ścieżce lub nagłówku). Preferuj zmiany addytywne; unikaj zmian łamiących (breaking changes) w polach lub zachowaniach.
- Stosuj testy kontraktowe sterowane przez konsumenta (consumer-driven contract tests) i wydania canary. Oznaczaj funkcjonalności jako przestarzałe (deprecate), podając harmonogram wycofania i zbierając telemetrię użycia.
- W przypadku klientów mobilnych spodziewaj się długiego ogona starych wersji; utrzymuj wiele wersji API jednocześnie.
Izolacja awarii i odporność
- Grodzie (Bulkheads): Izoluj zasoby według usługi lub klasy priorytetu (oddzielne pule węzłów, grupy instancji, limity). Zapobiegaj sytuacji, w której funkcjonalność typu best-effort „zagłodzi” krytyczne ścieżki.
- Wyłączniki awaryjne (Circuit Breakers): Wyzwalają się po serii kolejnych niepowodzeń w komunikacji z zależnością; zrzucają obciążenie i zapewniają okno na odzyskanie sprawności. Implementowane za pomocą siatki usług (service mesh, np. Envoy), polityk w bramie (gateway) lub bibliotek.
- Limity czasu (Timeouts) i ponowienia (retries): Stosuj obcięty wykładniczy backoff z jitterem; zapewnij idempotentność handlerów.
- Płynna degradacja (Graceful Degradation): Pomijaj niekrytyczne komponenty UI w przypadku timeoutu; serwuj dane z pamięci podręcznej (cache) lub dane przybliżone zamiast błędów.
- Kontrole stanu (Health checks) i sondy gotowości (readiness probes): Kieruj ruch tylko do gotowych instancji; używaj sond żywotności (liveness probes) do samonaprawy.
Przykład obciętego wykładniczego backoffu (HTTP 429): retry = 0 max_retry = 5 base = 0.5 while retry < max_retry: resp = fetch_gcs_object() if resp.status_code == 200: break if resp.status_code in (429, 500, 503): sleep = min(8, base * (2 ** retry)) + random.uniform(0, 0.25) time.sleep(sleep) retry += 1 else: raise Exception(“Non-retryable error”)
Przećwicz te pytania → · Testy na czas na ExamRoll.io →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
Zdaj egzamin →