Mysql
 sql >> Base de données >  >> RDS >> Mysql

Noeud js (getConnection)

Pour clarifier - Node.js n'est pas mono-thread. Votre code d'application est exécuté dans un thread, mais sous le capot, il les utilise en cas de besoin - jetez un œil ici (à la fois la réponse et les commentaires en dessous):

Et :

Comme vous pouvez le voir le mysql le module que vous utilisez nécessite que vous passiez un rappel pour le query() méthode (et probablement pour beaucoup d'autres). Ainsi, lorsque vous l'appelez, l'exécution de votre code se poursuit et le rappel est appelé lorsque les résultats de la base de données arrivent.

Quant à votre question - vous ne créez pas une nouvelle connexion pour chaque demande. Jetez un œil au lisez-moi fichier du mysql module, le Mise en commun des connexions rubrique :

Lorsque vous appelez dbPool.getConnection() la connexion est créée uniquement s'il n'y a plus de connexions disponibles dans le pool - sinon, il en saisit simplement une par le haut. Appel de objConn.release() libère la connexion au pool - il n'est pas déconnecté. Cet appel lui permet d'être réutilisé par d'autres parties de votre application.

Pour résumer :

  • Créer une nouvelle connexion pour chaque requête n'est pas une bonne idée car il utilisera plus de ressources (CPU, RAM) sur les machines de votre application et de la base de données.
  • L'utilisation d'une seule connexion pour toutes les requêtes est également erronée, car si l'une des opérations prend beaucoup de temps pour se terminer, votre connexion se bloquera et toutes les autres requêtes l'attendront.
  • Utiliser un pool de connexions est une excellente idée qui vous permet d'effectuer plusieurs opérations sur votre base de données en même temps, même si l'une d'entre elles prend beaucoup de temps.

Mise à jour : Pour répondre aux questions des commentaires :

Lorsque vous utilisez une connexion pour chaque requête, le mysql Le module doit ouvrir un nouveau socket, se connecter à la base de données et s'authentifier avant de faire votre requête - cela prend du temps et consomme des ressources. À cause de cela, c'est une mauvaise approche.

En revanche, lors de l'utilisation d'une seule connexion (pas le pool de connexions), l'exécution d'une requête qui prend beaucoup de temps à se terminer bloquera toutes les autres requêtes sur cette connexion jusqu'à ce qu'elle se termine - ce qui signifie que toute autre requête devra attendre. C'est aussi une mauvaise approche.

Créer un nouveau pool de connexions pour chaque requête revient à utiliser une nouvelle connexion, sauf si vous appelez pool.getConnection() plusieurs fois - alors c'est encore pire (prenez les ressources utilisées en créant une nouvelle connexion et multipliez-les par le nombre de pool.getConnection() appels).

Pour clarifier davantage une connexion pour chaque opération vs toutes les opérations en une seule connexion questions :

Chaque opération dans chaque connexion est lancée après la fin de la précédente (c'est synchrone, mais pas côté client), donc si vous avez une table avec quelques milliards de lignes et que vous lancez SELECT * FROM yourtable il faudra un certain temps pour terminer, bloquant chaque opération sur cette connexion jusqu'à ce qu'elle se termine.

Si vous avez une connexion pour chaque opération qui doit être émise en parallèle (par exemple pour chaque demande), le problème disparaît. Mais comme indiqué précédemment, l'ouverture d'une nouvelle connexion nécessite du temps et des ressources, c'est pourquoi le pool de connexion concept a été introduit.

La réponse est donc :utilisez un pool de connexions pour toutes les requêtes (comme vous le faites dans votre exemple de code) - le nombre de connexions sera adapté en fonction du trafic sur votre application.

Mise à jour 2 :

Sur la base des commentaires, je vois que je devrais également expliquer le concept derrière les pools de connexion. Comment cela fonctionne est que vous démarrez une application avec un pool de connexion vide et initialisé pour créer un maximum de n connexions (autant que je sache, c'est 10 pour mysql module par défaut).

Chaque fois que vous appelez dbPool.getConnection() il vérifie s'il existe des connexions disponibles dans le pool. S'il y en a, il en attrape un (le rend indisponible), sinon il en crée un nouveau. Si la limite de connexion est atteinte et qu'aucune connexion n'est disponible, une sorte d'exception est déclenchée.

Appel de connection.release() libère la connexion au pool afin qu'elle soit à nouveau disponible.

Utiliser un pool pour obtenir une seule connexion globale pour une application entière est totalement faux et contraire au concept lui-même (vous pouvez faire la même chose en créant simplement la connexion manuellement), donc en utilisez un pool de connexion Je veux dire utiliser un pool de connexions tel qu'il était censé être utilisé - pour obtenir des connexions à partir de celui-ci lorsque vous en avez besoin .