Question

Quelle est la meilleure façon de configurer votre piscine en ce qui concerne: -

  1. Quand créez-vous des connexions?
  2. Quand fermez-vous les connexions et les fermez-vous toutes?
  3. Est-ce que vous testez les connexions qui sont toujours bonnes? Quand et comment?
  4. Comment trouvez-vous un bon nombre pour le nombre maximal de connexions?
  5. Quel type de surveillance avez-vous mis en place pour vous assurer que les utilisateurs du pool se comportent bien? Pouvez-vous empêcher un mauvais morceau de code de tout supprimer?
  6. Avez-vous écrit votre propre pool ou utilisé une bibliothèque tierce?

Je pense qu'il s'agit d'une question agnostique, mais des commentaires sur les "fonctionnalités". des bases de données / langues particulières sont les bienvenues. Par exemple, la connexion à certaines bases de données peut être plus lente ou plus coûteuse que d’autres.

Pour clarifier, je n’ai pas l’intention d’écrire un pool à partir de rien, cette question porte plus sur la configuration d’une bibliothèque existante qui effectue le pooling.

Était-ce utile?

La solution

J'ai écrit un pool de connexions pour la base de données en Java alors qu'il ne s'agissait que d'un modèle de conception et non d'une bibliothèque commune. J'utilise maintenant celui intégré à Tomcat.

J'ai utilisé un thread pour surveiller plusieurs aspects du pool et plusieurs paramètres pour contrôler son comportement ...

  1. minimumInPool = " 3 "... Ces trois premiers sont créés lors du lancement. La piscine n'est jamais autorisée à descendre en dessous de trois.
  2. maximumIdleTimeBeforeRemoval = "60" ... Si une connexion est inactive pendant une heure, supprimez-la et créez-en une nouvelle. Le temps d'inactivité signifie probablement qu'il n'y a qu'un minimum de trois personnes dans le pool.
  3. maximumInUseTimeBeforeRemoval = "30" ... Si une connexion donnée a été extraite pendant plus de 30 minutes, il est probable que quelque chose ne va pas. Rappelez-le et tuez la connexion.
  4. maximumTimeBeforeRemoval = "60" ... Supprimez-le s'il a plus de 60 minutes.
  5. maximumUsageBeforeRemoval = "1000" ... Supprimez-le s'il a été extrait plus de 1000 fois.
  6. monitorInterval = "15" ... Vérifiez les paramètres ci-dessus toutes les 15 minutes.

Cela m’a très bien servi pendant quelques années. Le plus haut que j'ai jamais vu la piscine était 151 connexions au cours d'un coup d'oeil sauvage. Habituellement, la piscine était à peu près une douzaine lors d’une utilisation intensive et restait au ralenti au moins trois heures du matin.

J'ai utilisé les pilotes minces JDBC d'Oracle et je me suis connecté à une base de données Oracle.

Autres conseils

Voici la justification que j'ai utilisée pour une implémentation récente.

  1. Vous avez deux sortes de connexions dans votre pool de connexion. Le premier est prêt, c'est-à-dire ouvert mais non utilisé par un client. Le second est actif, ce qui signifie qu’il est utilisé par un client.

  2. Demandez à votre regroupement de connexions de conserver un petit nombre de connexions prêtes, un minimum de N et un maximum de M. N peut être ajusté en fonction de la vitesse de pointe à laquelle vos clients demandent des connexions. Si le nombre de connexions prêtes tombe à zéro, vous avez besoin d'un plus grand N. Si le nombre est constamment élevé (par exemple, supérieur à 10), vous avez besoin d'un N plus bas.

  3. Quand un client veut une connexion, donnez-lui l'un des prêts (le rendant actif), puis ouvrez immédiatement un nouveau s'il y a maintenant moins de N prêt (mais ne faites pas attendre le client pour cela compléter, sinon vous perdrez l’avantage de la mise en commun). Cela garantit qu'il y aura toujours au moins N connexions prêtes. Si aucun client n'est prêt lorsque le client en souhaite un, il devra attendre pendant que vous en créez un.

  4. Lorsque le client termine avec une connexion active, remettez-la à l'état Prêt si le nombre de connexions disponibles est inférieur à M. Sinon fermez-le. Cela vous évite d'avoir plus de M. connexions prêtes.

  5. Recyclez régulièrement les connexions prêtes pour éviter les connexions obsolètes. S'il y a plus de N connexions prêtes, fermez simplement la connexion la plus ancienne. Sinon, fermez-le et rouvrez-en un autre.

Cela présente l'avantage de disposer de suffisamment de et connexions jeunes disponibles dans votre pool de connexions sans surcharger le serveur.

Jakarta Commons DBCP fait déjà tout ce que vous avez énuméré:

  • il crée les connexions nécessaires et les gère dans un pool
  • il peut fermer des connexions si elles ne sont pas utilisées depuis un certain temps
  • il peut exécuter une requête sur une connexion avant de la distribuer et, en cas d'erreur, la connexion est supprimée et une nouvelle est créée. Les connexions peuvent également être testées périodiquement en mode inactif.
  • vous pouvez définir une limite sur les connexions qui seront créées et également sur le nombre minimum de connexions à avoir. La limite dépend bien sûr de votre application.
  • Je ne sais pas comment, mais DBCP sait quand une connexion n'est pas fermée et la ferme pour vous, en lançant une exception afin que vous sachiez ce qui s'est passé lorsque vous voyez votre journal.
  • DBCP a un paramètre de délai qui est très utile. Si toutes les connexions du pool sont utilisées, le système attendra le retour d’une connexion au pool et s’il n’y en a pas de disponible lorsque la limite est atteinte, vous obtenez une erreur.

Vous pouvez ajuster votre pool en jouant avec le nombre minimal de connexions, le nombre maximal de connexions à créer et le délai d'attente. Un délai plus long vous permettra d'avoir une limite inférieure de connexions, alors qu'un délai plus court nécessitera probablement un nombre plus important. Cela dépend beaucoup de ce que fait votre application et de la façon dont elle utilise les connexions.

Je suis d'accord avec matt b sur le fait que nous ne devrions pas réinventer la roue.

Cependant, l'utilisation de Commons DBCP est discutable sur la base des réponses de ceci et cette question. Il existe de meilleures alternatives, telles que c3po ou proxool .

Vous pouvez également utiliser le mécanisme de regroupement de connexions dépendant de rdbms.

Je ne suis pas sûr du contexte dans lequel vous utilisez vos connexions, mais je peux partager ce qui semble fonctionner pour moi.

J'utilise SQL Server comme serveur principal et j'utilise une combinaison de mise en cache avec celui-ci pour améliorer les performances. Ma pratique est de ne garder la connexion ouverte que si j'en ai réellement besoin et de ne pas la mettre en pool afin qu’elle nettoie immédiatement et que je puisse voir dans le moniteur d’activité SQL exactement ce qui est actif et ce qui ne l’est pas. Chaque connexion utilise de la mémoire, il est donc agréable de la garder silencieuse quand ils ne sont pas nécessaires.

Avant de répondre aux questions d'ouverture et de fermeture de la connexion, permettez-moi de dire que la mise en cache est vraiment importante. Obtenir un objet de la mémoire cache va vous faire gagner beaucoup de temps. Dans certaines de mes applications asp.net lorsque la mise en cache est active dans dev, j'ai constaté que je pouvais à peine mesurer la latence, alors qu'avec un appel à une base de données, cela pouvait prendre entre 15 ms et 45 ms et que cela ne prend même pas en compte une autre latence. facteurs ou charge. L’autre méthode que j’utilise est une bonne structure d’objet pour mes données, de sorte que je n’effectue une mise à jour de base de données que si quelque chose change. J'ai implémenté des méthodes sur mon objet pour m'assurer de faire le moins d'ES possible.

Cela étant dit, nous savons tous que nous devons accéder à notre base de données et écrire à un moment donné pour que je respecte deux principes:

  1. Laissez les portes et les fenêtres fermées pour économiser de l'énergie. Une connexion ouverte à un endroit signifie qu’elle n’est pas disponible ailleurs (ou que la mémoire et les autres ressources sont plus limitées). Nous avons désactivé la mise en commun car cela nous a permis d'améliorer nos performances.

  2. Je fais autant en batch ou en une fois que je peux quand la connexion est ouverte. C’est un peu plus compliqué alors laissez-moi vous expliquer.

    • L’une des méthodes que j’ai utilisée consiste à transmettre mes objets de connexion par le canal de sorte que tous les objets puissent utiliser un seul objet de connexion. Cela se traduit par une connexion ouverte et fermée au lieu de 10 ou plus, selon votre application. Un bon exemple en est l’un de nos modèles d’achat qui tire parti de la puissance du serveur SQL pour la collecte de statistiques et l’élaboration de modèles de commande complexes. Cela n’a aucun sens de continuer à ouvrir et à fermer la connexion lorsque vous effectuez une recherche à partir de 200 Ko de base de données ou quelle que soit l’application utilisée par les applications. L'autre partie est que, lorsque j'utilise un objet, j'essaie de regrouper mes mises à jour afin de réduire le temps pendant lequel je maintiens la connexion ouverte. Donc, en faisant un scope_identity sur l’appel d’insertion, je me charge de mon insertion et de la recherche de l’ID unique à ajouter à mon objet avant de le mettre en cache. À l’époque où je développais pour la première fois des applications ASP, j’ouvrais la connexion dès le début du chargement de la page, puis la refermais ensuite. Je ne recommande plus de le faire. Maintenant, un jour, ces sortes d’abstractions et de couches présentent un grand avantage que je recommande à tout programmeur débutant de porter une attention particulière.

Mes deux cents:

Cachez vos données! Cachez vos données! Cachez vos données! Faites aussi peu d’accès à la base de données que possible lorsque vous ne pouvez pas mettre en cache puis mettre en cache vos données!

Pourquoi réinventer la roue?

Quelqu'un a probablement déjà résolu le problème, et mieux.

Si vous êtes dans le monde Java, vous pouvez utiliser le Commons DBCP .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top