1. Prima di iniziare
Query Insights per Cloud SQL ti aiuta a rilevare, diagnosticare e prevenire i problemi di prestazioni delle query per i database Cloud SQL. Fornisce informazioni diagnostiche e un monitoraggio self-service e intuitivo che non si limitano al rilevamento per aiutarti a identificare la causa principale dei problemi di prestazioni.
In questo codelab imparerai a configurare un'istanza Cloud SQL per PostgreSQL, a eseguire il deployment di un'app Node.js per utilizzare l'istanza Cloud SQL come spazio di archiviazione backend e poi a utilizzare Query Insights per visualizzare e monitorare le query.
Prerequisiti
- Conoscenza di base del linguaggio di programmazione e degli strumenti Node.js
Attività previste
- Utilizza Cloud SQL in un'app Node.js.
- Attiva SQL Commenter in un'app Node.js.
- Utilizza Query Insights per Cloud SQL per monitorare e analizzare le prestazioni delle query.
Che cosa ti serve
- Un account Google Cloud in cui hai le autorizzazioni per abilitare le API e creare servizi
2. Configurazione e requisiti
Configurazione dell'ambiente autonomo
- Accedi alla console Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai già un account Gmail o Google Workspace, devi crearne uno.
Ricorda l'ID progetto che stai utilizzando. In questo codelab verrà chiamato PROJECT-ID.
- Successivamente, dovrai abilitare la fatturazione in Cloud Console per utilizzare le risorse Google Cloud.
L'esecuzione di questo codelab non dovrebbe costare molto, se non nulla. Assicurati di seguire le istruzioni riportate nella sezione "Pulizia e approfondimento", che ti consiglia come arrestare le risorse in modo da non incorrere in costi di fatturazione al termine di questo tutorial. I nuovi utenti di Google Cloud possono beneficiare del programma prova senza costi di 300$.
Attiva Cloud Shell
- Nella console Cloud, fai clic su Attiva Cloud Shell.
Se non hai mai avviato Cloud Shell, viene visualizzata una schermata intermedia (sotto la piega) che ne descrive le funzionalità. In questo caso, fai clic su Continua e non comparirà più. Ecco come si presenta la schermata intermedia:
Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.
Questa macchina virtuale è caricata con tutti gli strumenti per sviluppatori di cui avrai bisogno. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete.
- Esegui questo comando in Cloud Shell per verificare che il progetto in uso sia quello corretto:
Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è già autenticato e il progetto è già impostato sul tuo ID progetto.
Esegui questo comando per verificare che il progetto in uso sia quello corretto.
gcloud config list project
Se vuoi utilizzare un progetto diverso da quello selezionato all'apertura di Cloud Shell, puoi impostarne uno nuovo eseguendo:
gcloud config set project <PROJECT-ID>;
3. Configura un'istanza Cloud SQL per PostgreSQL con Query Insights abilitato
- Dopo l'avvio di Cloud Shell, puoi utilizzare la riga di comando per creare una nuova istanza Cloud SQL denominata
my-instance, con Query Insights abilitato:
gcloud sql instances create my-instance --tier db-f1-micro --database-version=POSTGRES_12 --region=us-central --root-password=<PASSWORD> --insights-config-query-insights-enabled --insights-config-record-application-tags --insights-config-record-client-address
Ecco una breve spiegazione dei flag e del loro significato:
- Il flag
--tier db-f1-microspecifica un tipo di macchina con risorse minime, poiché questo è a scopo di sviluppo e non hai bisogno di molte risorse per il codelab. Puoi scoprire di più sui livelli qui. - Il flag
--database-version=POSTGRES_12crea un'istanza con PostgreSQL versione 12. - Il flag
--region=us-centralspecifica la regione in cui verrà creata l'istanza. - Il flag
--root-password=<PASSWORD>consente di specificare la password per l'utente rootpostgres. Assicurati di sostituire <PASSWORD> con una password a tua scelta. - Il flag
--insights-config-query-insights-enabledabilita Query Insights sull'istanza. - Il flag
--insights-config-record-application-tagsconsente di registrare i tag delle applicazioni. Nelle sezioni successive scoprirai di più sui tag dell'applicazione. - Il flag
--insights-config-record-client-addressconsente di registrare gli indirizzi IP client in Query Insights.
Potrebbe esserti chiesto di abilitare l'API sqladmin.googleapis.com per il tuo progetto. Se richiesto, seleziona y per abilitare l'API.
La creazione dell'istanza richiederà diversi minuti. Al termine di questa operazione, l'istanza sarà pronta all'uso.
- Ora crea un database da utilizzare per l'app di esempio:
gcloud sql databases create votesdb --instance my-instance
Puoi anche accedere all'istanza e configurarla tramite la console Cloud.
- Recupera il nome della connessione dell'istanza nel formato
PROJECT-ID:ZONE-ID:INSTANCE-IDeseguendo questo comando. Lo utilizzerai in un secondo momento per configurare l'app Node.js.
gcloud sql instances describe my-instance | grep connectionName
4. Crea un service account da utilizzare con l'app
I service account vengono utilizzati per concedere le autorizzazioni per utilizzare diversi servizi all'interno del tuo progetto Google Cloud. Per questo codelab, ne hai bisogno per concedere al proxy Cloud SQL l'autorizzazione a connettersi alla tua istanza Cloud SQL.
Crea un service account nella console
- Vai alla pagina degli account di servizio IAM e fai clic sul pulsante
nella parte superiore della pagina.
- Assegna all'account di servizio un nome e un ID univoci e fai clic su CREA.
- Nella pagina successiva, fai clic sul menu a discesa Seleziona un ruolo. Filtra in base a "Cloud SQL" e seleziona il ruolo Client Cloud SQL. Fai clic su CONTINUA e poi su FINE.
- Dopo aver creato il service account, fai clic sui tre puntini in Azioni per il nuovo service account e scegli Gestisci chiavi. Nella pagina successiva, seleziona AGGIUNGI CHIAVE e poi Crea nuova chiave. JSON verrà selezionato; mantieni l'impostazione predefinita e fai clic su CREA. Verrà scaricato un file della chiave privata .json. Fai clic su CHIUDI.
- In Cloud Shell, fai clic sui tre puntini del menu Altro e scegli Carica file. Sfoglia il file .json scaricato sulla macchina locale e selezionalo. Il file .json verrà caricato nella home directory di Cloud Shell.
5. Installa e avvia il proxy Cloud SQL
Utilizzerai Cloud SQL Proxy per la comunicazione tra l'applicazione e l'istanza del database.
- Scarica il proxy Cloud SQL. In Cloud Shell, puoi eseguire:
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy && chmod +x cloud_sql_proxy
- Esegui il proxy come segue dopo aver sostituito
<INSTANCE_CONNECTION_NAME>con il nome della connessione dell'istanza che hai copiato dalla pagina Panoramica dell'istanza Cloud SQL.
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:5432 &
Se l'operazione va a buon fine, dovresti visualizzare alcune righe di output, che terminano con un messaggio Ready for new connections.
6. Clona e testa l'app in locale
- Clona il repository dell'applicazione di esempio e installa i pacchetti necessari per eseguire l'app.
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples/ cd nodejs-docs-samples/cloud-sql/postgres/knex npm install
- Imposta le seguenti variabili di ambiente:
export INSTANCE_CONNECTION_NAME='<PROJECT-ID>:<ZONE-ID>:<INSTANCE-ID>'
export DB_HOST='127.0.0.1:5432'
export DB_USER='postgres'
export DB_PASS='<PASSWORD>'
export DB_NAME='votesdb'
- Avvia l'app di esempio.
npm start
- Fai clic su Anteprima web
in Cloud Shell, poi seleziona Anteprima sulla porta 8080.

Nel browser dovresti visualizzare l'app di voto Tabs vs Spaces come mostrato qui:

- Fai clic sui pulsanti per esprimere alcuni voti e salvare alcuni dati nel database.
7. Aggiungere una pagina per visualizzare tutti i voti
Poiché questa applicazione di esempio è molto semplice, aggiungerai una pagina aggiuntiva che mostra tutti i voti. Il motivo principale è avere più dati da esaminare quando utilizzi Query Insights in un secondo momento.
- Inserisci
Ctrl+cin Cloud Shell per arrestare l'app di esempio. - In Cloud Shell, fai clic sul pulsante
per avviare l'editor di Cloud Shell. - In Esplora file, individua
nodejs-docs-samples/cloud-sql/postgres/knex/server.jse fai clic per caricare il fileserver.jsnell'editor.
Aggiungi il seguente codice dopo la definizione della funzione getVotes:
/**
* Retrieve all vote records from the database.
*
* @param {object} pool The Knex connection object.
* @returns {Promise}
*/
const getAllVotes = async pool => {
return await pool
.select('candidate', 'time_cast')
.from('votes')
.orderBy('time_cast', 'desc');
};
- Aggiungi il seguente codice per la route
'/getAllVotes'sotto la definizione delle altre route:
app.get('/getAllVotes', async (req, res) => {
pool = pool || createPool();
try {
// Query all votes from the database.
const votes = await getAllVotes(pool);
res.render('allvotes.pug', {
votes: votes,
});
} catch (err) {
console.error(err);
res
.status(500)
.send('Unable to load page; see logs for more details.')
.end();
}
});
- Crea un nuovo file denominato
allvotes.pugnella directorynodejs-docs-samples/cloud-sql/postgres/knex/views. Incolla il seguente codice:
doctype html
html(lang="en")
head
title Tabs VS Spaces
link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css")
link(rel="stylesheet", href="https://fonts.googleapis.com/icon?family=Material+Icons")
script(src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js")
body
nav(class="red lighten-1")
div(class="nav-wrapper")
a(href="#" class="brand-logo center") Tabs VS Spaces
div(class="section")
h4(class="header center") Recent Votes
ul(class="container collection center")
each vote in votes
li(class="collection-item avatar")
if vote.candidate.trim() === 'TABS'
i(class="material-icons circle green") keyboard_tab
else
i(class="material-icons circle blue") space_bar
span(class="title") A vote for <b>#{vote.candidate}</b>
p was cast at #{vote.time_cast}.
- Fai clic sul pulsante
per tornare a Cloud Shell ed eseguire:
npm start
- Apri l'app dall'anteprima web per assicurarti che funzioni. Aggiungi
/getAllVotesall'URL nel browser per visualizzare la nuova pagina che hai aggiunto.
8. Abilitare SQL Commenter nell'app
Ora installerai e attiverai SQL Commenter, una libreria open source che consente agli ORM di aumentare le istruzioni SQL con commenti prima dell'esecuzione. SQLcommenter supporta diversi ORM e framework, incluso quello utilizzato dall'app di esempio: Knex.js. Query Insights utilizza le informazioni contenute in questi commenti per fornire una visione incentrata sulle applicazioni delle prestazioni del database e identificare quale codice dell'applicazione sta causando problemi. L'overhead delle prestazioni dovrebbe essere minimo. Consulta la documentazione di Query Insights.
- Inserisci
Ctrl+cin Cloud Shell per arrestare l'app di esempio. - Esegui questo comando per installare i pacchetti necessari a SQLcommenter:
npm install @google-cloud/sqlcommenter-knex @opencensus/nodejs @opencensus/propagation-tracecontext @opentelemetry/api @opentelemetry/core --save
- In Cloud Shell, fai clic sul pulsante
per avviare l'editor di Cloud Shell. - In Esplora file, individua
nodejs-docs-samples/cloud-sql/postgres/knex/server.jse fai clic per caricare il fileserver.jsnell'editor. - Trova questo codice nel file:
const process = require('process');
Sotto, aggiungi il seguente codice:
const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
- Trova questo codice nel file:
// Set Content-Type for all responses for these routes.
app.use((req, res, next) => {
res.set('Content-Type', 'text/html');
next();
});
Sotto, aggiungi il seguente codice:
app.use(wrapMainKnexAsMiddleware(Knex, {
traceparent: true,
tracestate: true,
route: true,
db_driver: true
}));
Al termine, il codice dovrebbe essere simile al seguente:
...
// Require process, so we can mock environment variables.
const process = require('process');
const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
const express = require('express');
const Knex = require('knex');
const fs = require('fs');
const app = express();
app.set('view engine', 'pug');
app.enable('trust proxy');
// Automatically parse request body as form data.
app.use(express.urlencoded({extended: false}));
// This middleware is available in Express v4.16.0 onwards
app.use(express.json());
// Set Content-Type for all responses for these routes.
app.use((req, res, next) => {
res.set('Content-Type', 'text/html');
next();
});
app.use(wrapMainKnexAsMiddleware(Knex, {
traceparent: true,
tracestate: true,
route: true,
db_driver: true
}));
...
- Fai clic sul pulsante
per tornare a Cloud Shell ed eseguire:
npm start
- Nell'applicazione Tabs vs Spaces, fai clic sui pulsanti per aggiungere altri voti e quindi altri dati al database.
9. Utilizza Insights per visualizzare le prestazioni delle query e il tracciamento end-to-end
La dashboard di Query Insights ti aiuta a risolvere i problemi delle query Cloud SQL per cercare problemi di prestazioni. Per accedere a Insights, seleziona Query Insights nel riquadro di navigazione a sinistra per la tua istanza Cloud SQL.
Grafico Carico database - tutte le query
La dashboard Query Insights di primo livello mostra il grafico Carico database - tutte le query.

Il grafico contiene informazioni su capacità CPU, CPU e attesa CPU, attesa I/O e attesa blocco. Per scoprire di più sul significato di queste metriche, sulla loro posizione di archiviazione e per visualizzare alcuni esempi di come appare questo grafico per le query problematiche, consulta la documentazione. Nel caso di questa applicazione di esempio, il carico di query del database è basso, quindi non ci sono picchi elevati nel grafico.
Quali query sono responsabili del carico maggiore?
Sotto il grafico, troverai la tabella QUERY che contiene le query normalizzate per l'intervallo di tempo selezionato. Le query nella tabella sono ordinate in base al tempo di esecuzione totale.

Puoi fare clic su una singola query per visualizzare informazioni dettagliate, come il carico del database per questa query specifica, la latenza della query, gli esempi di piani di query e gli utenti principali. Se un'applicazione è creata utilizzando un ORM, come nel caso dell'applicazione di esempio, potresti non sapere quale parte dell'applicazione è responsabile di quale query. La sezione Tag più usati può aiutarti a scoprirlo.
Dove ha origine il caricamento della query nell'applicazione?
Passa dalla tabella QUERIES alla tabella TAGS per visualizzare un elenco di query taggate dalla logica di business, in modo da avere una visualizzazione più incentrata sull'applicazione.

Nella tabella TAGS, puoi vedere il carico del database suddiviso in base alla route che lo ha generato. Nello screenshot riportato sopra, puoi vedere che la route '/getAllVotes' ha un tempo di esecuzione medio più elevato e restituisce in media più righe. Sebbene il tempo di esecuzione visualizzato nella tabella non sia problematico in questo caso, facciamo clic sulla riga relativa a '/getAllVotes' per esaminare i dati in modo più dettagliato.
Perché le query vengono eseguite lentamente?
Fai clic sul punto nel grafico Esempi di piano di query per visualizzare un piano di query.

I piani di query mostrano come PostgreSQL esegue una query in background, semplificando la determinazione di eventuali operazioni che causano lentezza.
Quale codice dell'applicazione contribuisce alla lentezza?
Query Insights fornisce anche la visualizzazione contestuale della tracciabilità end-to-end, che può essere utile per ulteriori indagini sulle parti di un'applicazione che generano query lente.
Fai clic sulla scheda END TO END per visualizzare una traccia nel contesto.

10. Pulisci e scopri di più
Hai imparato a utilizzare Query Insights per monitorare e analizzare le prestazioni delle query con un'app Node.js e un database Cloud SQL PostgreSQL.
Pulizia
Se non vuoi che la tua istanza Cloud SQL continui a essere eseguita, puoi eliminarla ora.
gcloud sql instances delete my-instance