2009-10-14 23 views
58

¿Existen patrones o mejores prácticas que se pueden usar para simplificar el cambio de perfiles de configuración para aplicaciones web Java en múltiples entornos? p.ej. URLs JDBC, puntos finales SOAP, etc.Patrones de configuración de aplicaciones web Java

Como un poco de contexto para ayudar a aclarar mi pregunta, trabajo con varias aplicaciones web java grandes que durante un ciclo de lanzamiento determinado se mueven a través de 6 entornos diferentes; desarrollo, integración, control de calidad, rendimiento y, finalmente, se implementan en múltiples servidores de producción. En cada entorno, la configuración debe cambiar. En este momento, la mayoría de los cambios de configuración para cada implementación se realizan de forma manual, lo cual consume mucho tiempo y está abierto a errores.
¿Hay alguna manera de sacar la intervención manual de este proceso?

+0

Respuestas relacionadas: http://stackoverflow.com/questions/1634458/can-i-use-a-single-war-file-in-multiple-environments-should-i – McDowell

+1

JNDI (java.sun.com/ products/jndi) fue creado específicamente para resolver este problema, y ​​es lo que normalmente uso para los sistemas de producción, ya que se escala bien (funciona ya sea que tenga 1 entorno o 6). También separa claramente las responsabilidades del desarrollador y del administrador del sistema. Dicho esto, si sabes que solo tendrás 6 entornos, y ese número casi nunca cambiará, la solución de Jeremy debería funcionar, y creo que es lo que usan las convenciones más nuevas sobre los marcos de configuración (por ejemplo, Grails). –

+0

Dicho sea de paso, la configuración JNDI requerirá una configuración manual, pero solo lo hará una vez por entorno (algo así como instalar el servidor de la aplicación o el sistema operativo del entorno). –

Respuesta

14

Tiendo a trabajar más con .NET últimamente, por lo que mi Java está bastante oxidada. Estoy bastante seguro de que esto funcionaría en cualquier idioma con un pequeño ajuste.

Usamos una extensión del sistema de configuración .NET que nos permite usar configuraciones específicas del entorno y/o la aplicación junto con una configuración más global. El sistema de configuración usa una configuración global para que cada máquina lo identifique como dev, beta o producción (el valor predeterminado). Un conjunto de archivos cargados en orden y la configuración del último archivo anula cualquier configuración definida en un archivo previamente cargado. Los archivos se cargan en el siguiente orden:

  1. configuración global
  2. ajustes específicos de aplicación
  3. Aplicación entorno específico anula

Todos los archivos están en control de código fuente, y dado que el medio ambiente se define en la máquina en la que se ejecuta la aplicación; dado que no accederá a la configuración "beta" a menos que la configuración de la máquina lo identifique como "beta", podemos promocionar todos los archivos de configuración sin temor a apuntar inadvertidamente nuestra aplicación de producción a una base de datos de desarrollo.

+0

Creo que esta es la mejor respuesta a la pregunta de detectar y cargar automáticamente la configuración basada en el entorno actual sin ningún trabajo manual durante la implementación de la aplicación . También permite el caso donde la configuración puede diferir entre servidores en el mismo entorno. El uso de esto y el uso de la configuración de Commons para las anulaciones, como lo sugirió John Munsch, contribuirían a resolver el problema. –

6

Esto va a depender en gran medida de las opciones que los servidores de aplicaciones web le den. Tenemos varios entornos para JBoss con diferentes URL JDBC, el nombre JNDI sigue siendo el mismo en todos los servidores, solo cambia la configuración en la instancia local, por lo que nada va mal de una generación a otra.

Supongo que la respuesta corta es que la mejor práctica es externalizar las configuraciones y mantener un buen archivo en su lugar con las configuraciones correctas para cada servidor, y hacer que la aplicación web lea esa configuración. La naturaleza exacta de la externalización y la lectura dependerá de la configuración específica y del servidor de aplicaciones.

EDITAR: Estas configuraciones no existen como parte de la guerra (oído en nuestro caso) de esa manera no se sobrescriben.

+0

Gracias por su respuesta. Nosotros externalizamos la configuración y la ubicación de esos archivos es la misma en todos los servidores (WEB-INF/config). Sin embargo, los archivos de configuración deben colocarse en esa ubicación después de cada implementación. ¿Tiene los archivos ubicados fuera de la guerra ampliada o cómo es que no están sobrescritos o deben volver a colocarse en su lugar después de una nueva instalación? –

+2

@Donal Boyle, poner su configuración en WEB-INF/config realmente no la exterioriza, ya que todavía es parte de su aplicación web. –

2

Al principio tenemos todos los ajustes de configuración que cambian con frecuencia en un solo lugar. Es realmente difícil, si necesita configurar JNDI, editar valores de base de datos y modificar archivos de propiedades, todo al mismo tiempo, para completar la configuración. Prefiera el medio que sea más fácil de editar y también más fácil de verificar que todo esté configurado correctamente. Diría que los archivos de propiedades son la mejor solución. Puede editarlos fácilmente y solo necesita echar un vistazo rápido para ver que todo esté bien. Si opta por los archivos de propiedad, seleccione cuidadosamente una ubicación estándar para ellos y asigne una variable ambiental para la ruta.

También ayuda si tiene una prueba simple que verifique que todo esté configurado correctamente. Por ejemplo, puede tener una página de prueba que muestre los parámetros de configuración y realice algunas pruebas básicas, como intentar conectarse a bases de datos o servidores remotos.

+0

Me gusta la idea de la página de prueba. Algo así haría mucho más fácil confirmar/denegar la configuración incorrecta. –

+0

esto no es una buena práctica y no elimina el trabajo manual del proceso como OP – anton1980

11

Aquí hay algunas prácticas posibles que he usado o encontrado. La combinación de estos generalmente se necesita en la práctica.

Sustituyendo los valores de las variables en conffiles en la construcción de

Aquí hay un ejemplo de cómo se puede hacer esto con Apache Ant. las propiedades de Ant (${var.name}) se pueden controlar con los archivos de configuración de construcción:

<filterset id="variables.to.replace"> 
    <filter token="APPNAME" value="${app.name}"/> 
    <filter token="WEBAPP-PATH" value="${webapp.path}"/> 
    <filter token="ENCRYPT-ALGORITHM" value="${encrypt.algorithm}"/> 
    <filter token="ERROR-MAILTO" value="${error.mailTo}"/> 
    <!--...--> 
</filterset> 

<!-- Then, when building & copying the conf, replace the variables: --> 
<copy todir="${properties.target.dir}"> 
    <!-- env specific conf files --> 
    <fileset dir="${basedir}/env/${run.env}/webapp/WEB-INF/classes" /> 
    <filterset refid="variables.to.replace"/> 
</copy> 

Lo bueno es que se obtiene un control preciso de las diferentes configuraciones en tiempo de construcción. Lo que es malo es que el sistema tiende a volverse muy complejo y difícil de mantener si usa este método extensivamente para un gran número de configuraciones diferentes. Además, tener que compilar los conffiles también significa ciclos de desarrollo más lentos.

Sustituyendo las variables de conf dentro de la guerra en el arranque webapp

Esto es lo que suele hacer cuando se utiliza Spring Framework, incluso si sólo hay una configuración possble, obteniendo los beneficios de la separación de las preocupaciones. Con Spring, puede hacer que los valores conf se reemplacen con PlaceholderPropertyConfigurer dentro del contexto Spring en el inicio de la aplicación web. En este caso, debe elegir la configuración correcta, que se puede configurar, por ejemplo, en el tiempo de compilación.

En comparación con el reemplazo del tiempo de compilación, es más fácil manipular temporalmente los valores en una aplicación web no comprimida, si es necesario. Por supuesto, la aplicación web necesita reiniciarse si cambia algo, y los cambios manuales no persistirán en las redistribuciones de la aplicación de la webapp. Spring también está limitado al contexto de Spring, así que this doesnt' work e.g. in web.xml (pero tener variables en web.xml probablemente se debería evitar de todos modos debido a sus limitaciones).

Lectura de la conf local a partir de un archivo predefinido

Este enfoque es probablemente el más fácil de configurar: acaba de inventar una ruta del archivo de configuración, por ejemplo, $HOME/mywebapp/conf.properties y haga que su aplicación web de alguna manera la lea al inicio.

Lo bueno aquí es que no tiene que preocuparse por la configuración al compilar/implementar la aplicación web. De todos modos, debe tener algunos valores predeterminados de configuración razonables que luego pueden ser anulados por el conf local.

Tener la conf en una base de datos

Ésta es la solución más flexible para sobrescribir los parámetros conf, pero también puede complicarse en algunos casos. Tener el conf en una tabla con name y value columnas debería funcionar para la mayoría de los casos.

Por supuesto, no puede configurar las URL de conexión JDBC en una tabla de base de datos, pero esta es una buena solución para conf simple textual/numical que afecta la operación de la aplicación después de que se haya configurado la conexión db. Para evitar una penalización de rendimiento, asegúrese de almacenar en caché la conf de alguna manera si se accederá con frecuencia.

prácticas adicionales

como ha señalado kgiannakakis, sino que también ayuda a crear una página de configuración de diagnóstico de algún tipo para su aplicación.

0

Hay algunas maneras posibles de acercarse a este:

  • archivos de uso de propiedad como lo hace, pero añade un archivo "propiedades meta" que se utiliza para seleccionar el archivo de los bienes utilizados por la definición de un mapa entre un valor de entorno (por ejemplo, localhost hostname) en el nombre del archivo de propiedad para cargar.

  • ponga sus propiedades en una base de datos y defina la conexión de la base de datos a las tablas de propiedades en su servidor de aplicaciones como recurso recogido por su aplicación web.

  • No coloque los archivos de propiedad en su .war o .ear, pero cree un archivo properties-deployhost.jar que contenga los archivos de propiedades por cada host de destino. ata el apropiado.archivo jar a la aplicación Web desplegada por añadirlo a la ruta de clase (por ejemplo a través de las bibliotecas compartidas en la configuración del servidor de aplicaciones por web-app.)

Sólo el primero de ellos no necesita pasos manuales adicionales al implementar a expensas de tener que actualizar su fuente de configuración y crear nuevos archivos de implementación cuando se renombran sus sistemas de destino.

Estoy seguro de que son posibles muchas variaciones en estos y su enfoque, cuál es la mejor opción depende de su situación.

0

Lo que hacemos funciona bastante bien.

Al inicio, nuestros programas leen un archivo de configuración en una ruta de acceso codificada. Digamos que es:

/config/fun_prog/config.xml 

Cada programa tiene un camino duro codificado diferente (FunProgram está en fun_prog, super servidor está en sup_serv, lo que sea), por lo que no tenemos que preocuparnos por ellos caminando sobre la otra.

Los archivos XML son leídos por una pequeña biblioteca de configuración que creamos. El archivo XML contiene la información de conexión de BD, generalmente datos de configuración del servidor de correo, direcciones de correo electrónico para enviar notificaciones, si debe operar en modo de prueba, URLs de servicios externos, etc.

Entonces, cuando necesitamos hacer cambios, Copie el archivo de configuración, edite lo que queremos y reinicie el programa. Como tenemos una configuración de servidor estándar, cualquier programa se puede implementar en cualquier servidor simplemente copiando estos archivos (y el retoque httpd.conf necesario).

No es elegante, pero funciona muy bien. Es extremadamente simple de entender, agrega nuevas opciones de configuración, copia de seguridad y edición. Funciona en todas las plataformas (Unix es obvio, Windows traduce rutas que comienzan con/en c: \ para que funcione sin modificaciones también).

Nuestras estaciones de trabajo básicamente ejecutan el mismo software que el servidor, solo con algunos cambios en ese archivo de configuración.

1

El buen ejemplo de lo que quiere se usa en Seam o Grails (tomado de Rails).Hay perfiles, por defecto tres: prod, dev, test, pero puede definir más si lo desea.

En Seam, la compilación del proyecto se realiza mediante archivos Ant. Cada archivo que los contenidos pueden variar se define para cada perfil, p. datasource, sql scripts o archivos de propiedades.

import-dev.sql
import-prod.sql
import-test.sql

Cuando el archivo de hormigas se ejecuta con el perfil elegido, archivo apropiado se toma y nombre del perfil se trunca a partir de ese nombre de archivo.

A continuación se muestra fragmento de código que se puede colocar en sus objetivos

<copy tofile="${war.dir}/WEB-INF/classes/import.sql" 
     file="${basedir}/resources/import-${profile}.sql"/> 

JDBC URL, nombres de los controladores puede ser exteriorizada a archivos de propiedades (por supuesto, con los nombres de perfil como sufijos)

<filterset id="persistence"> 
    <filter token="transactionManagerLookupClass" value="${transactionManagerLookupClass}"/> 

<copy tofile="${war.dir}/WEB-INF/classes/META-INF/persistence.xml" 
    file="${basedir}/resources/META-INF/persistence-${profile}.xml"> 
    <filterset refid="persistence"/> 
</copy> 

o valores de las propiedades que puede pasar a la llamada de compilación de hormigas desde la línea de comandos. Este es un breve ejemplo de lo que está en Seam hecho.

Otra opción es utilizar Maven. De la misma manera, puede hacerlo por propiedades y por profiles, pero también puede usar módulos separados para dividir la configuración y crear otros módulos con la funcionalidad principal. Ejemplos típicos de casos de uso de propiedades y perfiles de maven son la configuración de varias bases de datos, servidores de implementación, etc. Es aún más difícil cuando se quiere crear una configuración para diferentes proveedores, pero para Maven eso no es un problema :)

Gran ejemplo de usar perfiles maven es este formulario de publicación Carlos Sanchez blog.

En resumen, recomiendo encarecidamente que busque Ant/Seam an Maven parametrization (profiles). Esas soluciones tienen otra ventaja: la secuencia de comandos ant o maven se puede ejecutar en el servidor de CI (como Hudson) y permite ejecutar/probar simultáneamente todos sus perfiles.

31

Me sorprende que nadie haya citado la API de configuración de Jakarta Commons (http://commons.apache.org/configuration/) para responder esta pregunta. Le permite tener una jerarquía de archivos (u otras fuentes de configuración como XML, JNDI, JDBC, etc.). Eso es de lo que Jeremy Seghi estaba hablando y te da una buena manera de tener tanto valores predeterminados como anulaciones locales también.

La mejor parte es que es una solución de trabajo probada, por lo que no tiene que ir a crear algo usted mismo.

+0

+1 para esta recomendación. Solo me enteré de esta biblioteca desde que originalmente publiqué esta pregunta. Debería ser muy útil, aunque hasta ahora no veo una forma integrada de cargar automáticamente diferentes archivos de configuración basados ​​en el entorno actual. –

0

favor, eche un vistazo a la siguiente dirección: http://issues.apache.org/jira/browse/CONFIGURATION-394

El marco de configuración que estamos buscando es algo en lo alto de configuración de Apache Commons y debe ser compatible con concurrencia Problemas, problemas de JMX y la mayoría de las tiendas (por ejemplo. archivo de propiedades, archivos .xml o PreferencesAPI).

Lo que el equipo de weblogic proporciona en 'Consola de administración' es interesante, a través del cual puede tener actualizaciones transaccionales (atómicas) en las configuraciones para que los oyentes registrados sean notificados.

¡Los muchachos de Apache insisten en que este proyecto está fuera de los alcances de la Configuración de Commons, tal vez!

He adjuntado un marco de configuración simple, mira por favor.

+1

Suena similar a lo que mi amigo tiene la intención de hacer con tools4j-conifg - http://stoffe.deephacks.org/2012/02/01/tools4j-config/ – Kristian

1

Puede utilizar el Patrón de configuración de componentes en su idioma de elección

Se describe en los libros POSA (creo que en el cuarto volumen)

(en Java se puede utilizar el componente commons-configuration) .

Cuestiones relacionadas