Best practice per le prestazioni dei microservizi

ID regione

REGION_ID è un codice abbreviato assegnato da Google in base alla regione selezionata quando crei l'app. Il codice non corrisponde a un paese o a una provincia, anche se alcuni ID regione possono sembrare simili ai codici di paesi e province di uso comune. Per le app create dopo febbraio 2020, REGION_ID.r è incluso negli URL di App Engine. Per le app esistenti create prima di questa data, l'ID regione è facoltativo nell'URL.

Scopri di più sugli ID regione.

Lo sviluppo software è incentrato sui compromessi e i microservizi non fanno eccezione. Ciò che guadagni in termini di implementazione del codice e indipendenza operativa, lo paghi in termini di overhead delle prestazioni. Questa sezione fornisce alcuni consigli sui passaggi da seguire che puoi adottare per ridurre al minimo questo impatto.

Trasforma le operazioni CRUD in microservizi

I microservizi sono particolarmente adatti alle entità a cui si accede tramite il pattern di creazione, recupero, aggiornamento ed eliminazione (CRUD). Quando si lavora con entità, in genere si usa una sola entità alla volta, ad esempio un utente, e di solito eseguono solo una delle azioni CRUD alla volta. Pertanto, è necessaria una sola chiamata al microservizio per l'operazione. Cerca entità con operazioni CRUD, oltre a un insieme di metodi aziendali che potrebbero essere utilizzati in molte parti dell'applicazione. Queste entità sono ottime candidate per i microservizi.

Fornisci API batch

Oltre alle API in stile CRUD, puoi comunque offrire buone prestazioni dei microservizi per gruppi di entità fornendo API batch. Ad esempio, anziché rispetto alla sola esposizione di un metodo GET API che recupera un singolo utente, che prende un insieme di ID utente e restituisce un dizionario di utenti corrispondenti:

Richiesta:

/user-service/v1/?userId=ABC123&userId=DEF456&userId=GHI789

Risposta:

{
  "ABC123": {
    "userId": "ABC123",
    "firstName": "Jake",
    … },
  "DEF456": {
    "userId": "DEF456",
    "firstName": "Sue",
    … },
  "GHI789": {
    "userId": "GHI789",
    "firstName": "Ted",
    … }
}

L'SDK di App Engine supporta molte API batch, come la possibilità di recuperare molte da Cloud Datastore tramite una singola RPC, quindi gestire questi tipi di dati Le API possono essere molto efficienti.

Utilizzare le richieste asincrone

Spesso dovrai interagire con molti microservizi per scrivere una risposta. Ad esempio, potresti dover recuperare le preferenze dell'utente che ha eseguito l'accesso, nonché i dettagli della sua azienda. Spesso queste informazioni non dipendono e recuperarli in parallelo. La libreria Urlfetch nell'SDK App Engine supporta le richieste asincrone, consentendoti di chiamare i microservizi in parallelo.

Usa il percorso più breve

A seconda di come richiami Urlfetch, puoi causare una diversa infrastruttura e le route da utilizzare. Per utilizzare il percorso con il rendimento migliore, tieni conto dei seguenti consigli:

Utilizza REGION_ID.r.appspot.com, non un dominio personalizzato
Un dominio personalizzato fa sì che venga utilizzato un percorso diverso per il routing nell'infrastruttura Google. Poiché le chiamate ai microservizi sono interne, è facile da eseguire e ha un rendimento migliore se utilizzi https://PROJECT_ID.REGION_ID.r.appspot.com.
Imposta follow_redirects su False
Imposta esplicitamente follow_redirects=False quando chiami Urlfetch, in quanto evita un servizio più pesante progettato per seguire i reindirizzamenti. Gli endpoint API non devono necessariamente reindirizzare i client, perché sono i tuoi microservizi e gli endpoint devono restituire solo risposte HTTP della serie 200, 400 e 500.
Preferisci i servizi all'interno di un progetto rispetto a più progetti
Ci sono buoni motivi per utilizzare più progetti quando si crea basata su microservizi, ma se l'obiettivo principale sono le prestazioni, possono usare i servizi all'interno di un singolo progetto. I servizi di un progetto sono ospitati nello stesso data center e, anche se il throughput sulla rete inter-data center di Google è eccellente, le chiamate locali sono più veloci.

Evitare le conversazioni durante l'applicazione della sicurezza

L'utilizzo di meccanismi di sicurezza che richiedono molte comunicazioni avanti e indietro per autenticare l'API chiamante è dannoso per il rendimento. Ad esempio, se il tuo microservice deve convalidare un ticket dalla tua applicazione richiamando nuovamente l'applicazione, hai generato una serie di viaggi di andata e ritorno per recuperare i dati.

Un'implementazione OAuth2 può ammortizzare questo costo nel tempo utilizzando i token di aggiornamento e memorizzando nella cache un token di accesso tra le invocazioni di Urlfetch. Tuttavia, se il token di accesso memorizzato nella cache è memorizzato in memcache, dovrai utilizzare memcache per recuperarlo. Per evitare questo overhead, puoi memorizzare nella cache il token di accesso nella memoria dell'istanza, ma l'attività OAuth2 verrà comunque eseguita frequentemente, poiché ogni nuova istanza negozia un token di accesso. Ricorda che le istanze App Engine vengono avviate e interrotte di frequente. Un ibrido di memcache e cache delle istanze contribuirà ad attenuare il problema, ma la soluzione inizierà a diventare più complessa.

Un altro approccio che funziona bene consiste nel condividere un token segreto tra di microservizi trasmessi come un'intestazione HTTP personalizzata. In questo , ciascun microservizio potrebbe avere un token univoco per ogni chiamante. In genere, i secret condivisi sono una scelta discutibile per la sicurezza ma poiché tutti i microservizi si trovano nella stessa applicazione, non rappresenta più un problema, dato il miglioramento delle prestazioni. Con un secret condiviso, il microservizio deve solo eseguire un confronto di stringhe del secret in entrata con un dizionario presumibilmente in memoria e l'applicazione della sicurezza è molto leggera.

Se tutti i tuoi microservizi si trovano su App Engine, puoi anche esaminare in arrivo Intestazione X-Appengine-Inbound-Appid. Questa intestazione viene aggiunta dall'infrastruttura Urlfetch quando effettui una richiesta a in un altro progetto App Engine e non può essere impostato da un soggetto esterno. A seconda del tuo requisito di sicurezza, i microservizi potrebbero ispezionare questo intestazione in entrata per applicare il criterio di sicurezza.

Traccia le richieste dei microservizi

Man mano che crei la tua applicazione basata su microservizi, inizi ad accumulare overhead derivante da chiamate Urlfetch successive. In questi casi, puoi utilizzare Cloud Trace per capire quali chiamate vengono fatte e dove si trova il sovraccarico. È importante sottolineare che Cloud Trace può anche aiutarti a identificare dove vengono invocati in sequenza microservizi indipendenti, in modo da poter eseguire il refactoring del codice per eseguire questi recuperi in parallelo.

Una funzionalità utile di Cloud Trace viene attivata quando utilizzi più servizi all'interno di un singolo progetto. Poiché le chiamate vengono effettuate tra i servizi di microservizi Cloud Trace comprime tutte le chiamate in un unico grafico per consentirti di visualizzare l'intera richiesta end-to-end come un'unica traccia.

Screenshot di Google Cloud Trace

Tieni presente che nell'esempio precedente, le chiamate al pref-service e al Le user-service vengono eseguite in parallelo utilizzando un Urlfetch asincrono, in modo che le RPC appaiano criptate nella visualizzazione. Tuttavia, questo è comunque uno strumento prezioso per diagnosticare la latenza.

Passaggi successivi