Mysql
 sql >> Database >  >> RDS >> Mysql

Nodo js (getConnection)

Per chiarire:Node.js non a filo singolo. Il codice dell'applicazione viene eseguito in un thread, ma sotto il cofano li usa quando necessario:dai un'occhiata a qui (sia la risposta che i commenti sotto di essa):

E:

Come puoi vedere il mysql il modulo che usi richiede di passare una callback per query() metodo (e probabilmente per molti altri). Quindi, quando lo chiami, l'esecuzione del tuo codice continua e la richiamata viene chiamata quando arrivano i risultati dal database.

Per quanto riguarda la tua domanda, non stai creando una nuova connessione per ogni richiesta. Dai un'occhiata al readme file di mysql modulo, il Collegamento delle connessioni sezione :

Quando chiami dbPool.getConnection() la connessione viene creata solo se non ci sono più connessioni disponibili nel pool, altrimenti ne prende solo una dalla parte superiore. Chiamando objConn.release() rilascia la connessione al pool - non viene disconnesso. Questa chiamata consente di riutilizzarla da altre parti dell'applicazione.

Per riassumere:

  • Creare una nuova connessione per ogni richiesta non è una buona idea poiché utilizzerà più risorse (CPU, RAM) sia sui computer della tua app che su quelli del database.
  • Anche l'utilizzo di una connessione per tutte le richieste è sbagliato perché se una qualsiasi delle operazioni richiede molto tempo per completare la tua connessione si bloccherà facendo attendere tutte le altre richieste.
  • Utilizzo di un pool di connessione è un'ottima idea che ti consente di eseguire più operazioni sul database contemporaneamente, anche se una di esse richiede molto tempo per essere completata.

Aggiornamento: Per rispondere alle domande dai commenti:

Quando utilizzi una connessione per ogni richiesta, mysql il modulo deve aprire un nuovo socket, connettersi al database e autenticarsi prima di effettuare la query:questo richiede tempo e consuma alcune risorse. Per questo è un approccio sbagliato.

D'altra parte, quando si utilizza una sola connessione (non un pool di connessioni), l'esecuzione di una query che richiede molto tempo per essere completata bloccherà qualsiasi altra query su quella connessione fino al completamento, il che significa che qualsiasi altra richiesta dovrà attendere. È anche un cattivo approccio.

Creare un nuovo pool di connessioni per ogni richiesta è più o meno come usare una nuova connessione, a meno che non chiami pool.getConnection() più volte - poi è anche peggio (prendi le risorse utilizzate creando una nuova connessione e moltiplicale per il numero di pool.getConnection() chiamate).

Per chiarire ulteriormente il un collegamento per ogni operazione vs tutte le operazioni in una connessione domanda:

Ogni operazione in ogni connessione viene avviata dopo il completamento della precedente (è sincrona, ma non lato client), quindi se hai una tabella con qualche miliardo di righe ed emetti SELECT * FROM yourtable ci vorrà del tempo per completare, bloccando ogni operazione su questa connessione fino al suo completamento.

Se hai una connessione per ogni operazione che deve essere emessa in parallelo (es. per ogni richiesta) il problema scompare. Ma, come affermato in precedenza, l'apertura di una nuova connessione richiede tempo e risorse, motivo per cui il pool di connessione è stato introdotto il concetto.

Quindi la risposta è:usa un pool di connessioni per tutte le richieste (come fai nel tuo codice di esempio) - il numero di connessioni scalerà in base al traffico sulla tua app.

Aggiornamento n. 2:

Sulla base dei commenti, vedo che dovrei anche spiegare il concetto alla base dei pool di connessioni. Il modo in cui funziona è avviare un'app con un pool di connessioni vuoto e inizializzato per creare un massimo di n connessioni (afaik sono 10 per mysql modulo predefinito).

Ogni volta che chiami dbPool.getConnection() controlla se ci sono connessioni disponibili nel pool. Se ci sono ne prende uno (lo rende non disponibile), in caso contrario ne crea uno nuovo. Se viene raggiunto il limite di connessione e non ci sono connessioni disponibili, viene sollevata un'eccezione.

Chiamando connection.release() rilascia la connessione al pool in modo che sia nuovamente disponibile.

L'uso di un pool per ottenere una sola connessione globale per un'intera app è totalmente sbagliato e contrario al concetto stesso (puoi fare la stessa cosa semplicemente creando la connessione manualmente), quindi usa un pool di connessioni Voglio dire usa un pool di connessioni come doveva essere utilizzato, per ottenere connessioni da esso quando ne hai bisogno .