Existe-t-il des modèles ou des meilleures pratiques permettant de simplifier la modification des profils de configuration pour les applications Web Java sur plusieurs environnements. Par exemple, les URL JDBC, les points de terminaison SOAP, etc.
Comme un peu de contexte pour aider à clarifier ma question, je travaille avec plusieurs grandes applications Web Java qui, au cours d’un cycle de publication donné, passent par 6 environnements différents. développement, intégration, assurance qualité, performance et éventuellement déploiement sur plusieurs serveurs de production. Dans chaque environnement, la configuration doit changer. À l’heure actuelle, la plupart des modifications de configuration pour chaque déploiement sont effectuées manuellement, ce qui prend du temps et est sujet aux erreurs.
Existe-t-il un moyen de sortir l’intervention manuelle de ce processus?
J’ai tendance à travailler plus avec .NET récemment, donc mon Java est assez rouillé. Je suis sûr que cela fonctionnerait dans n’importe quelle langue avec un peu de peaufinage.
Nous utilisons une extension du système de configuration .NET qui nous permet d’utiliser des parameters spécifiques à l’environnement et / ou à l’application en conjonction avec une configuration plus globale. Le système de configuration utilise un paramètre Global pour chaque ordinateur qui l’identifie en tant que dev, beta ou production (valeur par défaut). Un ensemble de fichiers chargés dans l’ordre et le paramètre du dernier fichier remplace tout paramètre défini dans un fichier précédemment chargé. Les fichiers sont chargés dans l’ordre suivant:
Tous les fichiers sont sous contrôle de code source et, comme l’environnement est défini sur la machine sur laquelle s’exécute l’application; comme il n’accède pas à la configuration “bêta” à moins que la configuration de la machine ne l’identifie comme “bêta”, nous pouvons promouvoir tous les fichiers de configuration sans crainte de pointer par inadvertance notre application de production sur une firebase database de développement.
Je suis surpris que personne n’ait cité l’API de configuration de Jakarta Commons ( http://commons.apache.org/configuration/ ) pour répondre à cette question. Cela vous permet d’avoir une hiérarchie de fichiers (ou d’autres sources de configuration telles que XML, JNDI, JDBC, etc.). C’est ce dont Jeremy Seghi a parlé et cela vous donne un bon moyen d’avoir à la fois des défauts et des remplacements locaux.
La meilleure partie est que c’est une solution de travail testée afin que vous n’ayez pas à fabriquer vous-même quelque chose.
Voici quelques pratiques possibles que j’ai utilisées ou rencontrées. La combinaison de ces éléments est généralement nécessaire dans la pratique.
Substituer les valeurs de variable dans les fichiers de configuration lors de la construction
Voici un exemple de la façon dont cela peut être fait avec Apache Ant. Les propriétés Ant ( ${var.name}
) peuvent être contrôlées avec les fichiers de configuration de la construction:
La bonne chose est que vous avez un bon contrôle sur les différentes configurations au moment de la construction. Ce qui est mauvais, c’est que le système a tendance à devenir très complexe et difficile à gérer si vous utilisez cette méthode de manière intensive pour un grand nombre de configurations différentes. De plus, le fait de devoir créer des fichiers de configuration signifie également des cycles de développement plus lents.
Substituer les variables de conf inside war au démarrage de webapp
C’est ce que je fais habituellement lors de l’utilisation de Spring Framework, même s’il n’y a qu’une seule configuration possible, bénéficiant des avantages de la séparation des problèmes. Avec Spring, vous pouvez remplacer les valeurs conf par PlaceholderPropertyConfigurer dans le contexte Spring au démarrage de Webapp. Dans ce cas, vous devez de toute façon choisir la bonne configuration, qui peut être configurée par exemple au moment de la construction.
Par rapport au temps de génération nécessaire, il est plus facile de manipuler temporairement les valeurs dans une application Web non compressée, si nécessaire. Bien sûr, l’application Web doit être redémarrée si vous modifiez quelque chose, et les modifications manuelles ne se poursuivront pas lors des redéploiements d’application Web. Spring est également limité au contexte Spring, donc cela ne fonctionne pas, par exemple, dans web.xml (mais avoir des variables dans web.xml devrait probablement être évité de toute façon à cause de ses limitations).
Lecture de la conf locale à partir d’un fichier prédéfini
Cette approche est probablement la plus facile à configurer: $HOME/mywebapp/conf.properties
simplement un chemin de fichier de configuration, par exemple $HOME/mywebapp/conf.properties
et faites en sorte que votre application Web le lise au démarrage.
La bonne chose ici est que vous n’avez pas à vous soucier de la conf lors de la création / déploiement de l’application Web. Quoi qu’il en soit, vous devez avoir quelques valeurs par défaut qui peuvent être remplacées par la configuration locale.
Avoir la conf dans une firebase database
C’est la solution la plus flexible pour remplacer les parameters de configuration, mais elle peut également être compliquée dans certains cas. Avoir le conf dans une table avec les colonnes name
et value
devrait fonctionner dans la plupart des cas.
Bien sûr, vous ne pouvez pas configurer les URL de connexion JDBC dans une table de firebase database, mais c’est une bonne solution pour une simple configure textuelle / numérique qui affecte le fonctionnement de l’application Web après la configuration de la connexion db. Pour éviter une pénalité de performance, assurez-vous de mettre en cache la conf si vous y accéderez fréquemment.
Pratiques supplémentaires
Comme le souligne kgiannakakis, il est également utile de créer une page de diagnostic de configuration pour votre application.
Cela va fortement dépendre des options que les serveurs d’application Web vous offrent. Nous avons plusieurs environnements pour JBoss avec différentes URL JDBC, le nom JNDI rest le même sur tous les serveurs, seule la configuration de l’instance locale change, donc rien ne se passe de la génération à la génération.
Je pense que la réponse courte est que la meilleure pratique consiste à externaliser les configurations et à conserver un bon fichier avec les parameters corrects pour chaque serveur, et que l’application Web lise cette configuration. La nature exacte de l’externalisation et de la lecture va dépendre de la configuration spécifique et du serveur d’applications.
EDIT: Ces configurations n’existent pas dans le cadre de la guerre (oreille dans notre cas), elles ne sont donc pas écrasées.
Au début, tous les parameters de configuration changent fréquemment au même endroit. C’est vraiment difficile, si vous devez configurer JNDI, éditez les valeurs de firebase database et modifiez les fichiers de propriétés en même temps afin de terminer la configuration. Préférez le support le plus facile à éditer et aussi plus facile à vérifier que tout est configuré correctement. Je dirais que les fichiers de propriété sont la meilleure solution. Vous pouvez facilement les éditer et vous n’avez besoin que d’un rapide coup d’œil pour voir que tout va bien. Si vous optez pour des fichiers de propriétés, sélectionnez-les avec soin et affectez-leur une variable d’environnement.
Cela aide aussi si vous avez un test simple qui vérifie que tout est configuré correctement. Par exemple, vous pouvez avoir une page de test qui affiche les parameters de configuration et effectue des tests de base, comme la tentative de connexion à une firebase database ou à des serveurs distants.
Le bon exemple que vous voulez est utilisé dans Seam ou Grails (emprunté à Rails). Il y a des profils, par défaut trois: prod, dev, test, mais vous pouvez en définir plus si vous voulez.
Dans Seam, la construction du projet est effectuée par des fichiers Ant. Le fichier Eeach que le contenu peut varier est défini pour chaque profil, par exemple la source de données, les scripts SQL ou les fichiers de propriétés.
import-dev.sql
import-prod.sql
import-test.sql
Lorsque le fichier ant est exécuté avec le profil choisi, le fichier approprié est pris et le nom du profil est tronqué à partir de ce nom de fichier.
Voici l’extrait de code que vous pouvez placer dans vos cibles
URL du JDBC, les noms des pilotes peuvent être externalisés dans des fichiers de propriétés (bien sûr avec des noms de profils sous forme de suffixes)
ou les valeurs des propriétés que vous pouvez transmettre à Ant Build Call depuis la ligne de commande. Ceci est un court exemple de ce que Seam est fait.
Une autre option consiste à utiliser Maven . De la même manière, cela se fait par propriétés et par profils , mais vous pouvez également utiliser des modules séparés pour diviser la configuration et créer d’autres modules avec des fonctionnalités principales. Des exemples de cas d’utilisation typiques de propriétés et de profils Maven sont la configuration d’exécution pour plusieurs bases de données, serveurs de déploiement, etc. C’est encore plus difficile lorsque vous souhaitez créer une configuration pour différents fournisseurs, mais pour Maven, cela ne pose aucun problème 🙂
Un bon exemple d’utilisation des profils maven est ce blog de Carlos Sanchez .
En résumé, je recommande fortement de rechercher la paramésortingsation Ant / Seam an Maven (profils). Ces solutions ont un autre avantage: le script ant ou maven peut être exécuté sur un serveur CI (comme Hudson ) et permet de lancer / tester simultanément tous vos profils.
Vous pouvez utiliser le modèle de configuration de composant dans la langue de votre choix
Il est décrit dans les livres POSA (je pense que dans le 4ème volume)
(en Java, vous pouvez utiliser le composant commons-configuration ).
Il y a quelques manières possibles d’aborder ceci:
utilisez des fichiers de propriétés comme vous, mais ajoutez un fichier “meta properties” utilisé pour sélectionner le fichier de propriétés utilisé en définissant une carte entre une valeur d’environnement (par exemple, nom d’hôte localhost) sur le nom du fichier de propriétés à charger.
placez vos propriétés dans une firebase database et définissez la connexion de firebase database aux tables de propriétés de votre serveur d’applications en tant que ressource capturée par votre application Web.
ne mettez pas les fichiers de propriétés dans votre fichier .war ou .ear, mais créez des archives properties-deployhost.jar contenant les fichiers de propriétés par hôte cible. liez le fichier .jar approprié à l’application Web déployée en l’ajoutant au chemin d’access aux classes (par exemple, via des bibliothèques partagées dans la configuration du serveur d’applications par application Web).
Seul le premier d’entre eux n’a pas besoin d’étapes manuelles supplémentaires lors du déploiement au désortingment de la mise à jour de votre source de configuration et de la création de nouveaux fichiers de déploiement lorsque vos systèmes cibles sont renommés.
Je suis sûr que de nombreuses variantes sont possibles sur ce point et que votre approche dépend de votre situation.
Ce que nous faisons fonctionne plutôt bien.
Au démarrage, nos programmes lisent un fichier de configuration dans un chemin d’access codé. Disons que c’est:
/config/fun_prog/config.xml
Chaque programme a un chemin différent codé en dur (FunProgram est dans fun_prog, Super Server est dans sup_serv, peu importe), nous n’avons donc pas à nous soucier de les dépasser.
Les fichiers XML sont lus par une petite bibliothèque de configuration que nous avons créée. Le fichier XML contient les informations de connexion à la firebase database, généralement les données de configuration du serveur de messagerie, les adresses e-mail auxquelles envoyer les notifications, le mode de test, les URL des services externes, etc.
Donc, lorsque nous devons apporter des modifications, nous copions le fichier de configuration, modifions ce que nous voulons et redémarrons le programme. Etant donné que nous avons une configuration de serveur standard, tout programme peut être déployé sur n’importe quel serveur en copiant simplement ces fichiers (et le bricolage httpd.conf nécessaire).
Ce n’est pas compliqué, mais ça marche très bien. Il est extrêmement simple à comprendre, à append de nouvelles options de configuration, à sauvegarder et à modifier. Fonctionne sur toutes les plates-formes (unix est évident, Windows traduit les chemins commençant par / dans c: \ pour que cela fonctionne sans modifications).
Nos stations de travail utilisent essentiellement le même logiciel que le serveur, avec quelques modifications dans ce fichier de configuration.
S’il vous plaît jeter un oeil à cette URL: http://issues.apache.org/jira/browse/CONFIGURATION-394
La structure de configuration que nous recherchons est en partie supérieure à la configuration d’Apache Commons et doit prendre en charge les problèmes de concurrence, les problèmes JMX et la plupart des magasins (par exemple, fichier .properties, fichiers .xml ou PreferencesAPI).
Ce que l’équipe weblogic fournit sur «Administration Console» est intéressant car elle vous permet d’avoir des mises à jour transactionnelles (atomiques) sur les configurations afin que les écouteurs enregistrés soient avertis.
Les gars d’Apache insistent sur le fait que ce projet est hors de scope de Commons Configuration, peut-être!
J’ai attaché un cadre de configuration simple, regardez s’il vous plaît.