Google PCD: Architettura di applicazioni Cloud-Native e selezione dei servizi — Guida allo studio
Fa parte della Google Professional Cloud Developer — Guida allo studio. Esercitati con risposte verificate nel centro esami Google, oppure fai test cronometrati su ExamRoll.io.
Panoramica
L’architettura delle applicazioni cloud-native su Google Cloud si concentra sulla creazione di servizi stateless e resilienti che scalano orizzontalmente, minimizzano l’onere operativo e adottano servizi gestiti dove appropriato. La selezione efficace dei servizi richiede la comprensione dei compromessi tra controllo, portabilità, prestazioni, costi e responsabilità operativa. Questa sezione presenta principi e pattern che aiutano a progettare, modernizzare e gestire applicazioni per utenti globali con un’affidabilità prevedibile.
Principi Cloud-Native e Scelte Architetturali
Design stateless e a dodici fattori (twelve-factor)
- Codice sorgente, dipendenze e build-release-run: Fissare le dipendenze esatte, creare artefatti immutabili e separare la build dal rilascio. Le immagini container e le pipeline di Cloud Build garantiscono rilasci riproducibili.
- Configurazione nell’ambiente: Esternalizzare la configurazione utilizzando variabili d’ambiente, Secret Manager, Kubernetes Secrets o i metadati delle istanze per Compute Engine. Non includere credenziali o impostazioni specifiche per il deployment nelle immagini. Per i gruppi di istanze gestite di Compute Engine, utilizzare i metadati del modello di istanza per i valori specifici del deployment.
- Servizi di supporto (backing services): Trattare database, code e cache come risorse collegate. Preferire i servizi gestiti (Cloud SQL, Cloud Spanner, Firestore, Memorystore, Pub/Sub) per ridurre l’onere operativo.
- Processi stateless: Scalare aggiungendo istanze; archiviare lo stato della sessione esternamente (Memorystore for Redis, Firestore o Spanner). Scrivere i log su stdout/stderr o in file di log raccolti dall’agente di Cloud Logging.
- Monouso (Disposability): Avvio e arresto rapidi consentono una scalabilità veloce e aggiornamenti continui (rolling update). Gestire SIGTERM per un arresto controllato (graceful shutdown).
- Log come flussi di eventi: Emettere log strutturati; utilizzare Cloud Logging per l’ingestion e Cloud Monitoring per gli allarmi.
Compromessi architetturali
- Monolite
- Pro: Sviluppo/test semplificati, meno confini di rete, singola unità di deployment.
- Contro: Rilascio indipendente più lento, vincoli di scalabilità, forte accoppiamento tra domini.
- Modalità di fallimento: Un singolo percorso critico (hot path) può consumare risorse condivise; le regressioni impattano tutte le funzionalità.
- Monolite modulare
- Pro: Chiari confini tra i moduli interni, percorso di refactoring verso i servizi, singola unità di deployment.
- Contro: Ancora vincolato dal deployment e dal database monolitici.
- Da utilizzare per i team che stanno maturando i confini di dominio prima di estrarre i servizi.
- Microservizi
- Pro: Deployability indipendente, scalabilità mirata, autonomia del team, isolamento dei guasti con bulkhead adeguati.
- Contro: Complessità dei sistemi distribuiti, coerenza, osservabilità e overhead operativo.
- Modalità di fallimento: Fallimenti a cascata tramite chiamate sincrone; deviazione dello schema (schema drift); reti “chiacchierone” (chatty network).
- Guidata dagli eventi (Event-driven)
- Pro: Accoppiamento debole, resilienza asincrona, buffering naturale, auditabilità tramite log/stream.
- Contro: Complessità del debugging, consistenza finale (eventual consistency), l’ordinamento e la semantica “exactly-once” sono difficili da ottenere.
- Pub/Sub fornisce una consegna “at-least-once”; progettare consumer idempotenti.
- Serverless (Cloud Run, Cloud Functions, App Engine)
- Pro: Operatività minima, scalabilità fino a zero, autoscaling per richiesta, sicurezza e telemetria integrate.
- Contro: Limiti di tempo di esecuzione e di concorrenza, avvii a freddo (cold start), vincoli specifici della piattaforma.
- Da utilizzare per carichi di lavoro con picchi (bursty), backend per mobile/web ed elaborazione di eventi.
- Monolite
Pattern di Comunicazione e Selezione dei Servizi
Chiamate sincrone e asincrone
- Sincrone
- Da utilizzare per API di tipo richiesta/risposta che richiedono risultati immediati.
- Protocolli: gRPC (HTTP/2, streaming, Protobuf compatto; eccellente per la larghezza di banda mobile e contratti forti), HTTP/JSON (ampia compatibilità; debugging più semplice).
- Rischi: Accoppiamento stretto e amplificazione della latenza; utilizzare timeout, tentativi con jitter e circuit breaker.
- Asincrone
- Utilizzare Pub/Sub o Cloud Tasks quando il lavoro può essere posticipato o raggruppato (batch).
- Vantaggi: Appiana i picchi, isola i guasti, migliora la latenza percepita dall’utente tramite il completamento finale.
- Rischi: Richiede idempotenza e azioni di compensazione; la visibilità sul lavoro in corso deve essere implementata.
- Sincrone
Criteri di selezione dei servizi su Google Cloud
- Controllo e portabilità
- Compute Engine: Pieno controllo delle VM e immagini personalizzate; onere operativo più elevato.
- GKE: Container portabili e opzioni di service mesh; autoscaling robusto; responsabilità condivisa.
- Cloud Run: Alta portabilità per container con operatività minima; scalabilità fino a zero; orientato alla richiesta.
- App Engine: PaaS “opinionated” con routing e scalabilità integrati; il percorso più rapido per determinati linguaggi.
- Scalabilità e latenza
- Global HTTP(S) Load Balancing con Cloud CDN per l’accelerazione perimetrale (edge).
- Datastore:
- Cloud Spanner: Coerenza globale, scalabilità orizzontale, disponibilità multi-regionale del 99,999%.
- Cloud SQL: DB relazionale gestito, regionale, repliche di lettura anche cross-region.
- Firestore: DB a documenti con disponibilità globale in modalità multi-regionale, coerenza forte per singoli documenti.
- Cloud Bigtable: Bassa latenza, scalabilità massiva per casi d’uso a colonna larga (wide-column).
- Memorystore: Cache a bassa latenza per percorsi critici (hot path) e sessioni.
- Responsabilità operativa
- Preferire i servizi gestiti per le questioni fondamentali (disponibilità, patching, backup, aggiornamenti).
- L’autogestione offre flessibilità ma aggiunge onere operativo e superficie di guasto (es. Kafka self-hosted vs Pub/Sub).
- Spostamento e integrazione dei dati
- Utilizzare la connettività nativa VPC, Private Service Connect e l’Internal HTTP(S) Load Balancing per un accesso privato a bassa latenza.
- Service discovery: Nomi dei Service Kubernetes all’interno di un cluster; DNS interno di Compute Engine per le VM.
- Controllo e portabilità
Esempio di Service Kubernetes (individuazione del nome in-cluster):
undefined
undefined
undefined
undefined
undefined
undefined
undefined
undefined
undefined
undefined
undefined
Confini, compatibilità e pattern di affidabilità
Confini di dominio e ownership
- Usare il domain-driven design per definire bounded context. Ogni servizio è proprietario dei propri dati e pubblica API/eventi come contratti.
- Evitare database condivisi tra i servizi; usare interfacce ben definite e la propagazione di eventi.
- L’ownership implica la reperibilità (on-call), gli SLO, la cadenza di rilascio e la responsabilità del budget per ogni servizio.
Contratti API e retrocompatibilità
- Versionare le API in modo esplicito (es. v1 nel percorso o nell’header). Preferire modifiche additive; evitare di alterare campi o comportamenti esistenti (breaking changes).
- Usare test basati su contratti consumer-driven e rilasci canary. Deprecare definendo tempistiche e utilizzando la telemetria sull’utilizzo.
- Per i client mobili, aspettarsi una lunga coda di versioni (long tail); mantenere più versioni delle API contemporaneamente.
Isolamento dei guasti e resilienza
- Bulkhead (paratie): Isolare le risorse per servizio o classe di priorità (pool di nodi, gruppi di istanze, quote separati). Impedire che una funzionalità best-effort possa sottrarre risorse ai percorsi critici (starvation).
- Circuit breaker (interruttori): Si attivano (trip) dopo fallimenti consecutivi verso una dipendenza; riducono il carico (shed load) e concedono una finestra di tempo per il ripristino. Implementare tramite service mesh (es. Envoy), policy del gateway o librerie.
- Timeout e tentativi (retry): Usare l’exponential backoff troncato con jitter; assicurarsi che gli handler siano idempotenti.
- Degradazione graduale (graceful degradation): Omettere componenti UI non critici in caso di timeout; servire dati dalla cache o approssimati invece di errori.
- Health check e readiness probe: Indirizzare il traffico solo verso le istanze pronte (ready); usare i liveness probe per l’autoriparazione (self-healing).
Esempio di exponential backoff troncato (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”)
Considerazioni globali e operative
Pattern multi-regione per utenti globali
- Front-end globale: Utilizzare un Global External HTTP(S) Load Balancing con IP anycast e Cloud CDN per i contenuti statici. Configurare il caching negativo e la convalida per ridurre il carico sull’origine.
- Piano dati:
- Per una disponibilità del database al 99,999% (five-nines) e una latenza di lettura globale minimizzata, utilizzare un’istanza Cloud Spanner multi-regionale (es. nam-asia-eur1) e predisporre un numero di nodi sufficiente per il calcolo e il quorum (minimo tre nodi per la produzione).
- Per pattern con carichi di lettura intensi senza una coerenza globale rigorosa, considerare una regione primaria con repliche di lettura cross-region; accettare una latenza di scrittura più elevata tra i continenti.
- Piano applicativo:
- Distribuire servizi stateless in più regioni con autoscaling (GKE o Cloud Run). Utilizzare servizi di backend e network endpoint group per regione.
- Instradare in base alla latenza, rispettando i vincoli di residenza dei dati e di conformità.
- Cache: Posizionare Memorystore o cache perimetrali (edge) vicino agli utenti per assorbire il traffico di lettura e proteggere le origini.
Gestito vs autogestito
- Utilizzare Cloud Monitoring per le metriche, Cloud Logging per i log, Cloud Trace/Profiler per la latenza e gli hotspot di CPU/memoria. Creare policy di avviso per i tassi di consumo degli SLO (burn rate) e controlli di uptime per la disponibilità esterna.
- Se una piattaforma di osservabilità esistente deve rimanere il sistema di riferimento, ingerire prima i dati con Cloud Logging per allarmi a bassa latenza, quindi esportare tramite sink alla piattaforma esterna.
Modernizzazione e migrazione incrementale
- Pattern Strangler: Anteporre un gateway al monolite; instradare endpoint specifici a nuovi servizi. Sostituire gradualmente le funzionalità.
- Branch by abstraction: Introdurre un’interfaccia attorno a una dipendenza e scambiare l’implementazione sottostante (es. database o storage).
- Anti-corruption layer: Tradurre tra modelli di dati legacy e nuovi bounded context.
- Migrazione dei dati: Utilizzare scritture doppie con verifica o event sourcing per il popolamento retroattivo (backfill); pianificare i cutover con controlli di backpressure.
- Rilascio graduale (Phased delivery): Sostituire le funzionalità per fasi per minimizzare il rischio di business; misurare continuamente gli SLO.
Revisioni del design e valutazione dei compromessi
- Sicurezza: Modello delle minacce (threat model), principio del privilegio minimo (least privilege) in IAM, account di servizio invece di chiavi incorporate (usare Application Default Credentials su GCE/GKE/Cloud Run), CMEK dove richiesto, connettività privata, WAF e limiti di frequenza (rate limit), scansione delle vulnerabilità e della sicurezza web.
- Affidabilità: Definire SLO ed error budget, piani di failover multi-regione, margine di capacità (capacity headroom), esercitazioni di chaos (chaos drills), mappe delle dipendenze.
- Prestazioni: Analisi della latenza di coda (tail latency), test di carico perimetrali e sull’origine, riutilizzo delle connessioni (HTTP/2, gRPC), compressione, strategia di caching.
- Costo: Dimensionare correttamente le risorse, policy di autoscaling, sconti per utilizzo continuativo (CUD), scale-to-zero per carichi di lavoro con picchi (bursty), traffico in uscita (egress) e offload su CDN.
- Operazioni: Runbook, rollback, rilascio progressivo (canary, blue/green), policy as code, test di backup e DR, integrazione della risposta agli incidenti.
Scenario pratico
Nimbus Retail sta lanciando una piattaforma e-commerce globale con immagini personalizzate, obiettivi di latenza rigorosi sotto i 200 ms al p95 in tutto il mondo e un requisito di disponibilità del 99,999% per il database degli ordini. Devono anche mantenere il loro SIEM esistente migliorando la velocità degli allarmi.
- Stabilire un database globale e ad alta disponibilità usando Cloud Spanner
- Azione: Creare un’istanza Spanner multi-regionale in nam-asia-eur1 con almeno tre nodi e suddividere le tabelle in schemi interleaved appropriati per la località.
- Motivazione: Lo Spanner multi-regionale offre una disponibilità al 99,999% (five-nines) e una bassa latenza di lettura tramite repliche su tre continenti; tre o più nodi assicurano una capacità di calcolo e di quorum delle repliche sufficiente.
Esempio:
gcloud spanner instances create nimbus-orders
–config=nam-asia-eur1 –description=“Global orders” –nodes=3
- Deployment globale del frontend e delle API
- Azione: Utilizzare un Global External HTTP(S) Load Balancing con Cloud CDN per gli asset statici e l’instradamento dinamico verso i backend regionali (servizi GKE in us-central1, europe-west1, asia-east1).
- Motivazione: Il VIP anycast minimizza l’RTT; la CDN memorizza nella cache le immagini vicino agli utenti; i servizi di backend distribuiscono le richieste alla regione integra più vicina.
- Servizi stateless su GKE con discovery all’interno del cluster
- Azione: Distribuire i servizi di ridimensionamento immagini e API su GKE con horizontal pod autoscaling e Service di tipo ClusterIP per l’accesso basato su nome all’interno del cluster; esporre gli endpoint pubblici tramite un Ingress.
- Motivazione: I pod stateless consentono una scalabilità elastica; il Service di Kubernetes astrae gli IP dei pod e fornisce un DNS stabile, riducendo l’accoppiamento del client.
- Elaborazione di immagini guidata da eventi (event-driven)
- Azione: Pubblicare le attività di elaborazione delle immagini su Pub/Sub; eseguire servizi Cloud Run sottoscritti tramite push per elaborare gli oggetti archiviati in Cloud Storage. Implementare un backoff esponenziale troncato con jitter per gli errori GCS 429/5xx.
- Motivazione: Pub/Sub gestisce i picchi e isola i guasti; Cloud Run scala per ogni messaggio; il backoff riduce l’amplificazione degli errori e aiuta i bucket a “scaldarsi” gradualmente.
- Osservabilità e allarmi rapidi
- Azione: Utilizzare Cloud Logging e Cloud Monitoring per ingerire log e metriche, definire controlli di uptime per le API e creare policy di avviso su tassi di errore e latenza. Configurare un sink di log per esportare verso il SIEM esistente.
- Motivazione: La telemetria nativa fornisce allarmi a bassa latenza e controlli di uptime gestiti; l’esportazione mantiene il SIEM centralizzato senza sacrificare la velocità degli allarmi.
- Configurazione e secret esternalizzati
- Azione: Archiviare la configurazione non segreta nei ConfigMap; i secret e le chiavi API in Secret Manager con Workload Identity per GKE. Per qualsiasi job basato su Compute Engine, utilizzare i metadati dell’istanza per i valori specifici di ogni deployment.
- Motivazione: La configurazione esternalizzata abilita immagini immutabili e impostazioni specifiche per l’ambiente; evita di incorporare i secret; i metadati supportano la variabilità delle VM senza modifiche al codice.
- Isolamento dei guasti e degradazione graduale (graceful degradation)
- Azione: Applicare bulkhead con pool di nodi separati per i carichi di lavoro di personalizzazione best-effort; imporre budget di richieste e circuit breaker per i servizi di personalizzazione. Nell’interfaccia utente, omettere i widget non critici in caso di timeout delle dipendenze.
- Motivazione: Isolare la capacità impedisce che le funzionalità best-effort sottraggano risorse al processo di checkout; i circuit breaker limitano il raggio d’impatto (blast radius); la degradazione graduale preserva i percorsi utente principali.
- Contratti API e compatibilità
- Azione: Definire contratti gRPC per i client mobili (v1) con transcodifica HTTP/JSON per il web; adottare modifiche additive e mantenere almeno due versioni durante il rollout sui dispositivi mobili.
- Motivazione: gRPC riduce la larghezza di banda e fornisce una tipizzazione forte; la transcodifica facilita l’integrazione con browser e partner; il versioning preserva la retrocompatibilità.
- Sicurezza e identità
- Azione: Utilizzare account di servizio Google per servizio con IAM basato sul principio del privilegio minimo; fare affidamento su Application Default Credentials. Abilitare Cloud Armor per le protezioni perimetrali (edge) e imporre TLS ovunque.
- Motivazione: Workload Identity elimina i rischi legati alla gestione delle chiavi; WAF e rate limit mitigano gli abusi; la crittografia in transito è predefinita e obbligatoria.
- Continuous delivery e sicurezza dei rilasci
- Azione: Implementare rilasci canary con suddivisione del traffico basata su percentuale a livello di load balancer e rollback automatico in caso di allarmi sul consumo dell’SLO (burn rate). Mantenere ambienti blue/green per regione.
- Motivazione: Il rilascio progressivo limita il rischio; un ambiente blue/green regionale accelera il rollback e abilita migrazioni sicure dello schema allineate con le API versionate.
Tutti i domini · Piattaforme di runtime Compute →
Esercitati su queste domande → · Pratica cronometrata su 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.
Supera l'esame →