web-dev-qa-db-fra.com

Comment configurer le basculement de connexion pour une configuration de redondance d'UC PostgreSQL dans une application JavaEE?

J'ai deux serveurs Linux (A et B) avec une base de données PostgreSQL 9.5 Installée. J'ai configuré le mode hot standby comme décrit dans la documentation . Dans cette configuration, A est configuré comme maître, B en mode de redondance d'UC. Cela fonctionne bien et se comporte comme prévu.

Maintenant, je veux connecter une application indépendante Java EE (Exécutée sur une autre machine) via Hibernate/JDBC via une source de données TomEE à cette configuration de base de données.

La documentation pilote PostgreSQL indique que plusieurs hôtes peuvent être spécifiés dans l'url de connexion jdbc:

jdbc:postgresql://Host1:port1,Host2:port2/database

Mes questions sont donc:

  1. Si A est en panne et que B est basculé manuellement en mode de fonctionnement normal, mon application est-elle toujours en mesure de procéder au fonctionnement de la base de données avec une URL de connexion jdbc comme indiqué ci-dessus?
  2. Dois-je configurer d'autres paramètres/bibliothèques?

Remarque: De diverses sources, j'ai appris que PostgreSQL ne prend pas en charge le basculement automatique (sauf si un logiciel tiers est impliqué dans le processus - voir les commentaires ci-dessous). Pour cette raison, le basculement doit être effectué manuellement, ce qui est correct pour ce cas d'utilisation particulier.

EDIT-1:

J'ai décidé de tester pgBouncer (comme suggéré dans les commentaires) pour une solution de contournement. Cela fonctionne bien pour mon cas d'utilisation. J'ai écrit un script de surveillance, qui automatise les étapes manuelles:

  1. Vérifiez en permanence si A est toujours en vie et écoute les connexions entrantes.
  2. En cas de basculement, basculez B en mode de fonctionnement normal et laissez-le devenir le nouveau maître et redémarrez le service.
  3. Modifiez les paramètres pgBouncer pour pointer sur B au lieu de A et redémarrez le service.

Cependant, je serais toujours intéressé, si quelqu'un a des expériences sans logiciel tiers?

21
rzo

Dans ce genre de situations, il est probablement préférable de tester et de mesurer.

Je n'ai pas d'expérience pratique avec le mode de redondance d'UC PostrgeSQL, mais j'ai effectué un basculement de base de données pour une application Java.

Tout d'abord, testez les revendications sur la page de documentation pilote PostgreSQL sur le ?targetServerType=master paramètre (mentionné en bas de page).
Écrivez une petite classe Java "PgHsm" avec une méthode principale qui utilise le pilote JDBC PostgreSQL via DriverManager.getConnection et exécute une simple requête de mise à jour.
Il doit utiliser le serveur A pour effectuer la requête de mise à jour. Arrêtez PostgreSQL sur le serveur A, exécutez PgHsm: il ne devrait pas se connecter car le serveur B n'est pas un maître.
Faites du serveur B le maître, exécutez PgHsm: il devrait fonctionner correctement.

La source de données est soutenue par un pool de connexions de base de données dans TomEE. Cette page répertorie ceux disponibles dans TomEE. Mais tous les pools de connexions à la base de données ne sont pas égaux et je préfère maintenant HikariCP parce que, selon mon expérience, il gère le scénario de "base de données en panne" de manière plus prévisible. Voir aussi le test avec des résultats sur la page gestion de la base de données vers le bas de HikariCP.

Malheureusement, HikariCP utilise JDBC get/setNetworkTimeout pour se comporter de manière prévisible et le pilote JDBC PostgreSQL ne l'implémente pas (*). Pour être sûr que les threads d'application (JavaEE) ne se bloquent pas indéfiniment sur une action de base de données, vous devez définir les options du pilote JDBC connectTimeout et socketTimeout. La définition d'un socketTimeout est précaire car elle définit automatiquement un délai pour TOUTES les requêtes dans la base de données.

(*) Mise à jour: depuis la version 42.2.x les délais d'expiration du réseau sont implémentés .

Le deuxième test à effectuer consiste à mettre à jour la classe Java "PgHsm" pour utiliser l'implémentation du pool de connexion à la base de données de votre choix et démarrer (au moins) deux threads qui exécutent continuellement des requêtes de mise à jour simples dans une boucle ( dans la boucle, une connexion à la base de données est acquise à partir du pool et retournée au pool après validation/restauration). Pendant que vous mettez le serveur A et basculez le serveur B en mode "maître", surveillez les exceptions consignées par "PgHsm" et combien de temps un le thread attend/se bloque lors de l'exécution d'une action de base de données.
Les résultats des tests peuvent être utilisés pour mettre à jour les options du pilote JDBC et les paramètres du pool. Concentrez-vous sur les résultats où:

  • les connexions non valides sont supprimées du pool dès que possible afin que l'application obtienne principalement des connexions valides du pool
  • le moins possible de threads d'application se bloquent (pendant la plus courte durée) lorsqu'une base de données tombe en panne

Le deuxième test repose sur le serveur A n'étant pas disponible, de sorte que les requêtes de test de connexion (effectuées par le pool de connexions à la base de données) échouent. Dans le cas où les deux serveurs restent disponibles, mais le commutateur maître et esclave, une requête de test de connexion n'aidera pas et le pool de connexions de base de données fournira les connexions de base de données incorrectes (désormais en lecture seule) à l'application. Dans ce cas, une intervention manuelle est requise. Un "modèle de basculement" pour HikariCP est décrit ici (uniquement disponible avec l'option allowPoolSuspension décrite sur la page configuration ):

  • suspendPool ()
  • softEvictConnections ()
  • Attendez que activeConnections passe à 0.
  • resumePool ()

Le troisième test sera avec l'application JavaEE et maintenant, vous devriez avoir une bonne idée des problèmes à prévoir. Il n'est pas rare que les applications soient mises à jour après ce type de tests pour améliorer la gestion des scénarios de "base de données en panne" (par exemple, paramétrage (par défaut) délai d'expiration des requêtes ). Dans votre cas, une fonctionnalité "suspendre, vider et reprendre le pool de connexion à la base de données" (le modèle décrit ci-dessus) à utiliser lors du basculement manuel serait également souhaitable.

10
vanOekel