language-agnostic deployment maintenance

language agnostic - ¿Cuáles son algunas buenas estrategias para permitir que las aplicaciones implementadas sean corregibles?



language-agnostic deployment (3)

En un mundo ideal, nuestros procesos de desarrollo serían perfectos, lo que daría como resultado lanzamientos regulares que fueron tan minuciosamente probados que nunca sería necesario "reparar" una aplicación en ejecución.

Pero, lamentablemente, vivimos en el mundo real y, a veces, los bichos se nos escapan y no crían sus feas cabezas hasta que ya estamos ocupados descifrando el próximo lanzamiento. Y el error necesita ser arreglado ahora . No como parte de la próxima publicación programada. No esta noche cuando el tráfico se apaga. Ahora .

¿Cómo lidias con esta necesidad? Realmente puede ir en contra de las buenas prácticas de diseño, como la refacturación de su código en bibliotecas de clase discretas.

El marcado manual y los procedimientos almacenados en un servidor de producción pueden ser una receta para el desastre, pero también pueden evitar el desastre.

¿Cuáles son algunas buenas estrategias para el diseño de aplicaciones y las técnicas de implementación para encontrar un equilibrio entre las necesidades de mantenimiento y las buenas prácticas de codificación?


Dividimos nuestro código en código de marco y personalizaciones de negocios. Las clases de personalización de negocios se cargan usando un cargador de clases separado y tenemos una herramienta para enviar cambios a una instancia de producción en ejecución. cada vez que necesitamos un cambio en cualquier clase lo cambiamos y lo enviamos a una instancia en ejecución. la instancia en ejecución rechazará el cargador de clases anterior y usará un nuevo ataque de cargador de clases para cargar las clases nuevamente. Esto es similar a la implementación en caliente de JBoss EJB.


Una estrategia es usar mucho los archivos de configuración externa de estilo declarativo para los diferentes componentes.

Ejemplos de esto:

  • Acceso a la base de datos / mapeo relacional de objetos a través de una herramienta como IBatis / IBatis.NET
  • Registro a través de una herramienta como JLog / NLog
  • Inyección de dependencia a través de una herramienta como Spring / Spring.NET

De esta manera, a menudo puede mantener los componentes clave separados en partes discretas, reparar una aplicación en ejecución sin recompilar y usar el control de fuente sin problemas (particularmente en comparación con los procedimientos almacenados, que generalmente requieren un esfuerzo manual para controlar la fuente).


[Aunque probamos mucho antes de lanzar,] Lo que hacemos es esto:

Nuestro SVN se ve así:

/repo/trunk/ /repo/tags/1.1 /repo/tags/1.2 /repo/tags/1.3

Ahora cada vez que lanzamos, creamos una etiqueta que eventualmente verificamos en producción. Antes de que hagamos la producción, hacemos etapas que son [menos servidores pero] prácticamente iguales a la producción.

Las razones para crear una "etiqueta" incluyen que algunas de las configuraciones de nuestra aplicación en el código de producción son ligeramente diferentes (por ejemplo, no se envían errores, sino que se registran) desde "troncales" de todos modos, así que tiene sentido crear la etiqueta y comprometer esos cambios . Y luego pagar en el clúster de producción.

Ahora, cada vez que necesitamos solucionar un problema, lo solucionamos en etiquetas / x primero y luego svn update de la etiqueta y estamos bien. A veces pasamos por etapas, con algunos problemas (por ejemplo, correcciones menores / triviales como la ortografía) que pasamos por alto el montaje.

Lo único que debe recordar es aplicar todos los parches desde tags/x al trunk .

Si tiene más de un servidor, Capistrano es extremadamente útil para ejecutar todas esas operaciones.