springbootservletinitializer java deployment java-ee

springbootservletinitializer - Implementación web de Java: código de compilación o despliegue.war?



spring boot war external tomcat (8)

Dos formas principales de implementar una aplicación web J2EE / Java (en un sentido muy simplista):

Implementar artefactos ensamblados en la caja de producción

Aquí, creamos el .war (o lo que sea) en otro lugar, lo configuramos para producción (posiblemente creando numerosos artefactos para numerosos cuadros) y colocamos los artefactos resultantes en los servidores de producción.

  • Pros : No hay herramientas de desarrollo en las cajas de producción, puede reutilizar los artefactos de las pruebas directamente, el personal que realiza la implementación no necesita conocimiento del proceso de compilación.
  • Contras : dos procesos para crear y desplegar artefactos; la configuración potencialmente compleja de artefactos preconstruidos podría dificultar la secuencia de comandos / automatización del proceso; tiene que versionar artefactos binarios

Construye los artefactos en la caja de producción

Aquí, el mismo proceso que se usa día a día para compilar e implementar localmente en los cuadros de desarrollador se utiliza para implementar en producción.

  • Pros : un proceso para mantener; y está fuertemente probado / validado por el uso frecuente. Configuración potencialmente más fácil de personalizar en el momento de creación del artefacto en lugar de personalizar el artículo posterior del artefacto preconstruido; no es necesario versionar los artefactos binarios.
  • Contras : herramientas de desarrollo potencialmente complejas que se necesitan en todas las cajas de producción; el personal de implementación necesita comprender el proceso de compilación; no estás implementando lo que probaste

En su mayoría he usado el segundo proceso, sin duda por necesidad (sin tiempo / prioridad para otro proceso de implementación). Personalmente, no compro argumentos como "la caja de producción tiene que estar limpia de todos los compiladores, etc.", pero puedo ver la lógica al implementar lo que has probado (en lugar de construir otro artefacto).

Sin embargo, las aplicaciones Java Enterprise son tan sensibles a la configuración, que se siente como pedir problemas para tener dos procesos para configurar artefactos.

¿Pensamientos?

Actualizar

Aquí hay un ejemplo concreto:

Usamos OSCache y habilitamos el caché de disco. El archivo de configuración debe estar dentro del archivo .war y hace referencia a una ruta de archivo. Esta ruta es diferente en cada entorno. El proceso de compilación detecta la ubicación configurada del usuario y garantiza que el archivo de propiedades colocado en la guerra sea correcto para su entorno.

Si tuviéramos que usar el proceso de compilación para la implementación, sería una cuestión de crear la configuración correcta para el entorno de producción (por ejemplo, production.build.properties ).

Si tuviéramos que seguir el "despliegue de los artefactos ensamblados en la caja de producción", necesitaríamos un proceso adicional para extraer las propiedades (incorrectas) de OSCache y reemplazarlo por uno apropiado para el entorno de producción.

Esto crea dos procesos para lograr lo mismo.

Entonces, las preguntas son:

  • ¿Esto es evitable sin "compilar en producción"?
  • Si no, ¿esto lo vale? Es el valor de "no compilar en la producción" mayor que "No repetir".

Actualizado con un escenario concreto, ver arriba


Estoy firmemente en contra de construir en la caja de producción, porque significa que estás usando una construcción diferente a la que probaste. También significa que cada máquina de implementación tiene un archivo JAR / WAR diferente. Si nada más, haga una compilación unificada solo para que cuando rastree errores no tenga que preocuparse por las inconsistencias entre los servidores.

Además, no necesita poner las compilaciones en control de versiones si puede mapear fácilmente entre una compilación y la fuente que lo creó.

Donde trabajo, nuestro proceso de implementación es el siguiente. (Esto está en Linux, con Tomcat).

  1. Pruebe los cambios y compruebe en Subversion. (No necesariamente en ese orden, no exigimos que se pruebe el código comprometido. Soy el único desarrollador a tiempo completo, por lo que el árbol SVN es esencialmente mi rama de desarrollo. Su millaje puede variar).

  2. Copie los archivos JAR / WAR a un servidor de producción en un directorio compartido con el nombre del número de revisión de Subversion. Los servidores web solo tienen acceso de lectura.

  3. El directorio de despliegue contiene enlaces simbólicos relativos a los archivos en los directorios nombrados por revisión. De esta forma, una lista de directorios siempre le mostrará qué versión del código fuente produjo la versión en ejecución. Al implementar, actualizamos un archivo de registro que es poco más que una lista de directorio. Eso hace que los roll-backs sean fáciles. (Uno tiene que ver, Tomcat comprueba si hay nuevos archivos WAR en la fecha de modificación del archivo real, no el enlace simbólico, así que tenemos que tocar el archivo anterior cuando retroceda).

Nuestros servidores web descomprimen los archivos WAR en un directorio local. El enfoque es escalable, ya que los archivos WAR están en un único servidor de archivos; podríamos tener un número ilimitado de servidores web y solo realizar una única implementación.


Existen servicios de configuración, como ZooKeeper de gran peso, y la mayoría de los contenedores le permiten usar JNDI para realizar alguna configuración. Estos separarán la configuración de la compilación, pero pueden ser excesivos. Sin embargo, ellos existen. Mucho depende de tus necesidades

También utilicé un proceso mediante el cual los artefactos se crean con marcadores de posición para los valores de configuración. Cuando se despliega la GUERRA, se explota y los marcadores de posición se reemplazan con los valores apropiados.


La mayoría de los lugares en los que he trabajado han utilizado el primer método con información de configuración específica del entorno desplegada por separado (y actualizada con mucha menos frecuencia) fuera de la guerra / oído.


Recomiendo mucho "Desplegar artefactos ensamblados en la caja de producción", como un archivo war. Esta es la razón por la cual nuestros desarrolladores utilizan el mismo script de compilación (Ant en nuestro caso) para construir la guerra en su entorno limitado de desarrollo, como se usa para crear el artefacto final. De esta forma se depura así como el código en sí, sin mencionar que es completamente repetible.


Si hace esta pregunta relativa a la gestión de la configuración, entonces su respuesta debe basarse en lo que usted considera que es un artefacto gestionado. Desde la perspectiva de CM, es una situación inaceptable que algunos archivos de origen funcionen en un entorno y no en otro. CM es sensible a las variables de entorno, las configuraciones de optimización, el compilador y las versiones en tiempo de ejecución, etc. y debe tener en cuenta estas cosas.

Si hace esta pregunta relativa a la creación repetible del proceso, entonces la respuesta debe basarse en la ubicación y cantidad de dolor que está dispuesto a tolerar. El uso de un archivo .war puede implicar un mayor dolor inicial para ahorrar esfuerzo en los ciclos de prueba e implementación. El uso de archivos fuente y herramientas de compilación puede ahorrar costos iniciales, pero tendrá que soportar un dolor adicional al tratar los problemas al final del proceso de implementación.

Actualización para un ejemplo concreto

Dos cosas para considerar en relación con su ejemplo.

  1. Un archivo .war es solo un archivo .zip con una extensión alternativa. Puede reemplazar el archivo de configuración con las utilidades de zip estándar.

  2. Posiblemente reconsidere la necesidad de poner el archivo de configuración dentro del archivo .war. ¿Sería suficiente tenerlo en el classpath o tener propiedades especificadas en la línea de comando de ejecución al inicio del servidor?

En general, intento mantener los requisitos de configuración de implementación específicos para la ubicación de implementación.


Usar 1 archivos de guerra empaquetados para implementar es una buena práctica.
usamos ant para reemplazar los valores que son diferentes entre ambientes. Verificamos el archivo con una variable @@@ que será reemplazada por nuestra secuencia de comandos ant. La secuencia de comandos ant reemplaza el elemento correcto en el archivo y luego actualiza el archivo de guerra antes de implementarlo en cada uno

<replace file="${BUILDS.ROOT}/DefaultWebApp/WEB-INF/classes/log4j.xml" token="@@@" value="${LOG4J.WEBSPHERE.LOGS}"/> <!-- update the war file We don''t want the source files in the war file.--> <war basedir="${BUILDS.ROOT}/DefaultWebApp" destfile="${BUILDS.ROOT}/myThomson.war" excludes="WEB-INF/src/**" update="true"/>

Para resumir, lo hace todo y usamos hormiguero para manejar hormigas. ant crea el archivo de guerra, reemplaza las rutas de archivos, actualiza el archivo de guerra y luego se implementa en el entorno de destino. Un proceso, de hecho, un clic en un botón en hormiguero.


Defendería el uso de una solución de integración continua que admita compilaciones distribuidas. El código registrado en su SCM puede desencadenar compilaciones (para pruebas inmediatas) y puede programar compilaciones para crear artefactos para QA. A continuación, puede promocionar estos artefactos para la producción y hacer que se implementen.

Esto es actualmente lo que estoy trabajando en la configuración, usando AnthillPro .

EDITAR: ahora estamos usando Hudson . ¡Altamente recomendado!