La aplicación de doce factores es un conjunto de 12 principios o mejores prácticas para crear aplicaciones web que ahora se conocen más comúnmente como aplicaciones de software como servicio (SAAS). Fue publicado por el cofundador de Heroku, el Sr. Adam Wiggins en 2011. Estos principios son el resultado de todas las experiencias y observaciones que las personas que trabajan en Heroku, que es una plataforma como servicio, han adquirido durante una gran variedad de aplicaciones de software como servicio jamás implementadas en él.
Estos principios nos ayudan a crear las aplicaciones que usan programación declarativa para la automatización de la configuración, lo que a su vez reduce el tiempo de desarrollo y el costo de los proyectos cuando se une un nuevo desarrollador, no depende de ningún sistema operativo en particular y son fácilmente portátiles , son altamente adecuado para la implementación en la nube y permite la implementación continua y son fácilmente escalables horizontalmente sin requerir muchos cambios en la base de código. Los factores son los siguientes:
1. Base de código
Base de código única por aplicación rastreada en el control de versiones con muchas implementaciones. Rompamos la declaración oficial y tratemos de entender los dos términos principales que contiene. En términos ingenuos, una base de código es todo el código fuente escrito por humanos que no incluye los archivos de clase u objeto generados por las herramientas. Una implementación se refiere a una sola instancia en ejecución de esa aplicación en particular. Cada aplicación debe tener una única base de código. Cada una de estas bases de código debe administrarse en un sistema de control de versiones. Algunos VCS (Sistemas de control de versiones) populares incluyen git, svn y mercurial. Si existen múltiples bases de código, entonces no es una aplicación, es un sistema distribuido. Cada componente de ese sistema se conocerá como una aplicación que seguirá los principios de las aplicaciones de 12 factores.
2. Dependencias
Declarar y aislar explícitamente las dependencias. Todos debemos haber observado esto al menos una vez en nuestra carrera de programación que descargamos una biblioteca de python para algún propósito y luego descubrimos que descargamos la versión incorrecta de la biblioteca o que tenemos una versión incorrecta de python instalada en nuestro sistema. Esto generalmente sucede porque la tarea de administrar las dependencias se le da al desarrollador. Por lo tanto, este factor establece que siempre debemos declarar las dependencias en el archivo de manifiesto, un archivo que contiene los metadatos de las dependencias como nombre, versión. Aumenta la velocidad del desarrollo ya que ahora el desarrollador está libre de la tarea de administrar la versión correcta de las bibliotecas. Ya no es necesario descargar explícitamente los archivos JAR necesarios.
3. Configuración
Almacene la configuración en el entorno. El código fuente y las configuraciones deben estar completamente separados entre sí. Debemos almacenar todas las configuraciones como credenciales de base de datos, ruta, URI en las variables de entorno, ya que es una práctica general en la industria, las configuraciones de la aplicación varían de un entorno a otro, como desarrollo, prueba, producción, etc. Además, no se debe almacenar ninguna configuración en git en texto plano. Hay una forma muy sencilla de verificar si su aplicación actual sigue este principio de configuración o no, preguntándose si puede hacer que su aplicación sea de código abierto ahora mismo sin realizar ningún cambio y sin comprometer ninguna de sus credenciales.
4. Servicios de respaldo
Trate los servicios de respaldo como recursos adjuntos. Si hablamos en términos muy simples, cualquier servicio que consuma su aplicación a través de la red se conoce como servicio de respaldo. Su aplicación debe tratar estos servicios como recursos que consume a través de la red. Nos da la ventaja de que nuestros servicios se vuelven fácilmente intercambiables y ofrecen una gran portabilidad a nuestra aplicación.
Un ejemplo simple es que su aplicación está utilizando actualmente una base de datos PostgreSQL local para sus operaciones y luego se reemplaza con la que está alojada en el servidor de su empresa simplemente cambiando la URL y las credenciales de la base de datos.
5. Construya, Lance y Ejecute
Separe estrictamente las etapas de construcción y ejecución. La implementación de su aplicación debe separarse adecuadamente en tres fases no dependientes que no se superponen, a saber, compilación, lanzamiento y ejecución. La fase de construcción constituye la compilación del código que al final genera el artefacto como un archivo JAr o WAR. La segunda fase, liberación, toma el archivo del artefacto generado al final de la fase anterior y le agrega las configuraciones para un entorno particular. La última fase incluye la ejecución de la instancia de la aplicación.
6. Procesos
Ejecute la aplicación como uno o más procesos sin estado.Se dice que una aplicación sigue este principio si sus instancias se pueden crear y destruir en cualquier momento sin afectar la funcionalidad general de nuestra aplicación. Para lograr y cumplir con este principio, nuestra aplicación debe almacenar cualquier tipo de datos generados por ella en cualquier almacén de datos persistente (con estado). Pero eso no significa que no podamos usar la memoria de los procesos de nuestra aplicación. Podemos usarlo para almacenar como almacenamiento temporal. En términos simples, se debe evitar el uso de sesiones pegajosas. Las sesiones pegajosas, en términos simples, se refieren a capturar los datos de la sesión del usuario que inició sesión en la memoria local del proceso y luego dirigir cada solicitud posterior de ese usuario en particular al mismo proceso. El problema con las sesiones pegajosas es que provoca un equilibrio de carga desigual entre las instancias de la aplicación.
7. Enlace de puertos
Exportar servicios a través de la vinculación de puertos. Cualquier aplicación que siga este principio es completamente autónoma e independiente. Exporta HTTP como un servicio y no requiere ningún servidor como un Tomcat para escuchar las requests. Se une a algún puerto en particular y escucha todas las requests que llegan a ese puerto. También debe haberlo observado mientras diseñaba una aplicación o un microservicio que se ejecuta en un puerto en particular y acierta requests en ese puerto en particular utilizando cartero para obtener una respuesta. Esta información de en qué puerto escuchará nuestro servicio también se almacena en el propio archivo de configuración.
8. Concurrencia
Escale horizontalmente a través del modelo de proceso. Una aplicación que sigue este principio debe dividirse en diferentes procesos más pequeños en lugar de una sola aplicación grande. Cada uno de estos procesos debe poder iniciarse, finalizar y replicarse de forma independiente y en cualquier momento. Este principio permite escalar nuestra aplicación muy fácilmente. Al escalar horizontalmente nos referimos al escalado horizontal en el que ejecutamos múltiples instancias de nuestros procesos. Añade concurrencia a nuestra aplicación de una forma muy sencilla debido a la existencia de procesos independientes escalables horizontalmente.
9. Desechabilidad
Maximice la solidez con un inicio rápido y un apagado ordenado. La robustez de una aplicación se refiere al buen inicio y finalización de sus procesos sin afectar la funcionalidad general de la aplicación. Por ejemplo, uno de los procesos de nuestra aplicación es almacenar los detalles de un empleado recién agregado a la empresa en una base de datos. Pero mientras lo hace, ocurre un error inesperado que hace que el proceso finalice inesperadamente. Sin embargo, el estado de nuestra aplicación o base de datos no debe verse afectado por ello y el proceso debe ser a prueba de fallas. Además, debe comenzar rápidamente cuando sea necesario.
10. Paridad desarrollo/producción
Mantenga el desarrollo, la puesta en escena y la producción lo más similares posible. Simplemente significa que el entorno de desarrollo y producción debe ser lo más similar posible. Los procesos que se utilizan, las tecnologías y la infraestructura deben ser los mismos. Esto lo ayudará de manera que cualquier error que pueda ocurrir con el tiempo ocurrirá en la etapa de desarrollo en lugar de ocurrir sorprendentemente en la producción. Esto ayuda en la implementación continua de nuestra aplicación y también reduce el tiempo y los esfuerzos de desarrollo.
11. Registros
Trate los registros como flujos de eventos. Los registros son muy esenciales para comprender el funcionamiento interno de la aplicación y pueden ser de diferentes niveles y generalmente se almacenan en un archivo llamado «archivo de registro» en el almacenamiento. Idealmente, nuestra aplicación de doce factores no debe preocuparse por el almacenamiento de los registros. Cada vez que ingresa una solicitud al sistema, se realizan los registros correspondientes y se tratan como una secuencia de eventos que se pueden usar para depurar cuando ocurre algún problema.
12. Procesos de administración
Ejecute tareas de administración/gestión como procesos únicos. La mayoría de las aplicaciones requieren que se ejecuten algunas tareas únicas antes de que comience el flujo real de la aplicación. Estas tareas no se requieren con mucha frecuencia y, por lo tanto, generalmente creamos un script para ello que ejecutamos desde algún otro entorno. Por otro lado, la metodología de doce factores dice que dichos scripts deben formar parte de nuestra base de código administrada en el sistema de control de versiones. Estas tareas también deben seguir los principios de los doce factores.