Comment gérez-vous les fichiers de configuration et les bibliothèques intégrées dans webapps java?

StackOverflow https://stackoverflow.com/questions/582248

Question

Je travaille actuellement sur un projet j2ee qui a été en version bêta depuis un certain temps maintenant. En ce moment, nous sommes en train de marteler quelques-uns des problèmes avec le processus de déploiement. Plus précisément, il y a un certain nombre de fichiers intégrés dans la guerre (certains fichiers XML et .properties) qui ont besoin de différentes versions selon que le déploiement que vous êtes dans un environnement dev, test ou production. Des trucs comme loglevels, pools de connexion, etc.

Alors je me demandais comment les développeurs structurent ici leur processus de déploiement webapps. Avez-vous débarquez autant la configuration que vous pouvez sur le serveur d'application? Remplacez-vous les fichiers de paramètres par programme avant de déployer? Choisissez une version au cours du processus de construction? modifier manuellement les guerres?

Aussi bien comment vous allez dans la fourniture de dépendances à travers les serveurs d'applications de bibliothèques statiques et combien vous mettez dans la guerre eux-mêmes? Tout cela juste pour obtenir quelques idées de ce que la pratique courante (ou peut-être mieux) est à l'heure actuelle.

Était-ce utile?

La solution

Je travaille dans un environnement où une équipe de serveur distinct effectue la configuration des serveurs d'assurance qualité et de production pour nos applications. Chaque application est généralement déployée sur deux serveurs QA et trois serveurs en production. Mon équipe de dev a découvert qu'il est préférable de minimiser la quantité de configuration requise sur le serveur en mettant autant que possible la configuration de la guerre (ou de l'oreille). Cela rend plus facile la configuration du serveur et minimise également la chance que l'équipe du serveur configure correctement le serveur.

Nous n'avons pas la configuration spécifique à la machine, mais nous avons une configuration spécifique de l'environnement (Dev, QA et production). Nous avons des fichiers de configuration stockés dans le fichier de guerre qui sont nommés par l'environnement (ex. Dev.properties, qa.properties, prod.properties). Nous avons mis une propriété -D sur la ligne de commande java du serveur VM pour spécifier l'environnement (ex. Java -Dapp.env = prod ...). L'application peut rechercher la propriété système app.env et l'utiliser pour déterminer le nom du fichier de propriétés à utiliser.

Je suppose que si vous avez un petit nombre de propriétés spécifiques à la machine, alors vous pouvez les spécifier comme -D propriétés ainsi. Commons configuration fournit un moyen facile de combiner des fichiers de propriétés avec des propriétés du système.

configurer les pools de connexions sur le serveur. Nous nommons le pool de connexion identique pour tous les environnements et les serveurs il suffit de pointer qui sont affectés à chaque environnement à la base de données appropriée. L'application ne dispose que de connaître le nom du pool d'une connexion.

Autres conseils

Je pense que si les propriétés sont la machine / déploiement spécifique, ils appartiennent à la machine. Si je vais envelopper les choses dans une guerre, il doit être goutte-innable, ce qui signifie que rien qui est spécifique à la machine, il fonctionne sur. Cette idée va se briser si la guerre a des propriétés dépendant de la machine en elle.

Ce que je veux faire est de construire un projet avec un fichier properties.example, chaque machine a une .properties qui vit quelque part la guerre peut y accéder.

Une autre façon serait d'avoir des tâches de fourmis, par exemple pour dev-guerre, étape-guerre, prod-guerre et ont les ensembles de propriétés partie du projet, cuit au four dans la construction-guerre. Je n'aime pas autant parce que vous allez finir par avoir des choses comme l'emplacement des fichiers sur un serveur individuel dans le cadre de votre projet de construction de.

fichiers de configuration de WRT, je pense que réponse Steve est le meilleur jusqu'à présent. Je voudrais ajouter la suggestion de faire des fichiers externes par rapport au chemin d'installation du fichier de guerre -. De cette façon vous pouvez avoir plusieurs installations de la guerre en un serveur avec différentes configurations

par exemple. Si mon dev.war se décompressé dans /opt/tomcat/webapps/dev, alors j'utiliser Bill de mettre le moins possible dans ces fichiers de configuration externes. Utilisation de la base de données ou JMX en fonction de votre environnement pour stocker autant qu'il est logique de. Apache Commons Configuration a un bel objet la manipulation des configurations soutenues par une table de base de données.

En ce qui concerne les bibliothèques, je suis d'accord avec inconnu d'avoir toutes les libs dans le dossier WEB-INF/lib dans le fichier de guerre (emballé auto-). L'avantage est que chaque installation de l'application est autonome, et vous pouvez avoir différents builds de la guerre en utilisant différentes versions des bibliothèques en même temps.

L'inconvénient est qu'il utilisera comme chaque application Web plus de mémoire aura sa propre copie des classes, chargées par son propre chargeur de classe.

Si cela pose un réel problème, vous pouvez mettre les pots dans le dossier de la bibliothèque commune pour votre conteneur de servlets (de $CATALINA_HOME/lib pour tomcat). Toutes les installations de votre application Web en cours d'exécution sur le même serveur doivent utiliser les mêmes versions des bibliothèques bien. (En fait, ce n'est pas tout à fait vrai que vous pouvez mettre les versions prépondérants dans le dossier individuel WEB-INF/lib si nécessaire, mais qui devient assez compliqué à maintenir.)

Je construirais un programme d'installation automatisée pour les bibliothèques communes dans ce cas, en utilisant InstallShield ou NSIS ou équivalent pour votre système d'exploitation. Quelque chose qui peut le rendre facile de dire si vous avez le plus à jour ensemble de bibliothèques et de mise à niveau, déclassement, etc.

Je fais habituellement deux fichiers de propriétés:

  • un pour plus de détails d'application (messages, mots "magiques" internes) intégrés dans l'application,
  • l'autre pour plus de détails sur l'environnement (accès db, les niveaux de journaux et des chemins ...) exposés sur classpath et « Collé » de chaque serveur (non livré avec mon application). D'habitude, je « mavenise » ou « anttise » ces valeurs une à mettre spécifiques, en fonction de la cible env.
  • gars cool utilisent JMX pour maintenir leur application conf (peut être modifié conf en temps réel, sans redéployant), mais il est trop complexe pour mes besoins.

Bibliothèques de serveur (statique?): Je déconseille fortement l'utilisation de la bibliothèque de serveur dans mes applications car il ajoute la dépendance au serveur:

  1. OMI, mon application doit être « auto-emballé »: laisser tomber ma guerre, et voilà tout. J'ai vu des guerres avec 20 Mbs de pots en elle, et ce n'est pas déranger pour moi.
  2. Une meilleure pratique courante consiste à limiter vos dépendances externes à ce qui est offert par le dogme J2EE: l'API J2EE (utilisation des Servlets, EJB, JNDI, JMX, JMS ...). Votre application doit être « serveur agnostique ».
  3. Mettre les dépendances dans votre application (guerre, de l'oreille, wathever) est autodocumenté: vous savez ce que les bibliothèques de votre application dépend. Avec libs serveur, vous devez documenter clairement ces dépendances car ils sont moins évidentes (et bientôt vos développeurs oublieront cette petite magie).
  4. Si vous mettez à jour votre serveur d'applications, il est probable que le serveur lib vous dépend également changer. éditeurs AppServer ne sont pas censés assurer la compatibilité de leurs libs internes de la version à la version (et la plupart du temps, ils ne le font pas).
  5. Si vous utilisez un lib largement utilisé embarqué dans votre appServer (commons-logging jakarta, alias JCL, vient à l'esprit) et que vous voulez ugrade sa version pour obtenir les dernières fonctionnalités, vous prenez le risque énorme que votre appServer ne soutiendra pas il.
  6. Si vous repose sur un objet serveur statique (dans un champ statique d'une classe de serveur, par exemple une carte ou un journal), vous devrez redémarrer votre serveur d'applications pour nettoyer cet objet. Vous perdez la capacité à chaud redéployer votre application (ancien objet serveur existe toujours entre les redéploiements). Utilisation d'objets à l'échelle APPSERVER (autres que celles définies par J2EE) peut conduire à des bugs subtils, surtout si cet objet est partagé entre plusieurs applications. Voilà pourquoi je déconseille fortement l'utilisation d'objets qui réside dans un champ statique d'un appServer lib.

Si vous avez absolument besoin « cet objet dans le pot de ce serveur d'applications », essayez de copier le pot dans votre application, en espérant qu'il n'y a pas de dépendance sur le pot d'un autre serveur, et vérifier la politique de classloading de votre application (je prends l'habitude de mettre un « parent dernière » classloading politique sur toutes mes applications: Je suis sûr que je ne serai pas « polluée » par les pots de serveur - mais je ne sais pas si elle est une « meilleure pratique »)

Je mets toute configuration dans la base de données. Le conteneur (Tomcat, WebSphere, etc.) me donne accès à la connexion de base de données initiale et à partir de là, tout sort de la base de données. Cela permet de multiples environnements, clusters, et les changements dynamiques sans temps d'arrêt (ou au moins sans redéployer). Particulièrement agréable est d'être en mesure de changer le niveau de journal à la volée (bien que vous aurez besoin soit d'un écran d'administration ou un rafraîchisseur d'arrière-plan pour que les modifications soient). Il est évident que cela ne fonctionne que pour des choses qui ne sont pas nécessaires pour obtenir l'application a commencé, mais en général, vous pouvez accéder à la base de données assez rapidement après le démarrage.

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