Diseño de Software as a Service: Los 12 factores.


Autor: M. en C.  Alejandro Cruz Rojas    Sígueme en LinkedIn

“Los doce factores” ¿Qué son?

¿En qué aspectos deberíamos enfocarnos si diseñamos una aplicación para ser desplegada como “software as a service”? Consideremos que cuando una aplicación es desplegada bajo este modelo tendrá que afrontar algunas condiciones especiales. Por ejemplo:

  • Típicamente será desplegada en una plataforma de nube.
  • Estará desplegada bajo un sistema operativo que puede tener modificaciones y actualizaciones fuera de nuestro control. Incluso podría cambiar de distribución sobre la marcha.
  • Coexistirán el desarrollo de nuevas funcionalidades y requerimientos, con la corrección de bugs. Esas tareas pueden incluso, ser atendidos por equipos de trabajo distintos.
  • Las ventanas de mantenimiento deben tener duraciones mínimas.
  • Se debería diseñar el software para que permita la sustitución de proveedores de servicios con el mínimo de esfuerzos (lo mismo una base de datos, que un proveedor de correo o un message broker).

En esta idea, la comunidad de Heroku (un reconocido proveedor de plataforma as a service) ha creado un compendio de principios denominado “The Twelve-Factor App”.

“The Twelve-Factor App” plantea 12 principios de diseño que se recomienda integrar en una aplicación que será desplegada como software as a service. Así, conseguiremos tener sistemas con las siguientes características:

CaracterísticaMeta
Uso de formatos declarativos para la automatización de la configuraciónMinimizar el tiempo y el costo de que nuevos desarrolladores se unan al proyecto
Contrato limpio con el sistema operativo subyacenteMaximizar la portabilidad entre entornos de ejecución
Adecuados para su implementación en plataformas modernas en la nubeReducir la necesidad de servidores y administración de sistemas
Minimizan la divergencia entre los ambientes de desarrollo y producciónFacilitar la integración continua y aumentar la agilidad
Usan mejores prácticas de diseño y arquitecturaEscalar verticalmente sin cambios significativos en herramientas, arquitectura o prácticas de desarrollo
Metas de 12-factors App

En la figura siguiente enumeramos cada uno de los doce factores:

Los doce factores

En el presente artículo abordaremos los primeros dos factores, mientras que el resto serán descritos en futuras entregas.

El factor 1: La base de código

Una base de código de una aplicación contiene todo el código fuente de esa aplicación.

Consideremos el hipotético caso de que se use un nuevo directorio o carpeta (de sistema operativo) cada vez que se quiera crear una nueva versión de la aplicación:

  • ¿Cómo podríamos saber el historial de cambios de determinada funcionalidad?
  • ¿Cómo podríamos relacionar los cambios hechos con los requerimientos atendidos en el tiempo?
  • ¿Cómo evitaríamos que se encime accidentalmente código, como producto de los cambios hechos simultáneamente por equipos distintos?

El factor 1 establece el principio de “Una sola base de código bajo revisión (es decir, bajo seguimiento) y muchos despliegues (copias subordinadas a la única base de código)”.

Conceptos

A la base de datos de seguimiento de cambios se le conoce como repositorio de código, a menudo abreviado como code repo o simplemente repo.

Una base de código, en un sistema de control de versiones descentralizado como Git, es el conjunto de repositorios que comparten un único repositorio raíz, que centraliza la base de datos de seguimiento de cambios. Consideremos que, en un momento en el tiempo, cada repositorio individual podría tener piezas que aún no existen en la raíz, pero que serán integradas a él tarde o temprano. De ahí que la base de código se considere distribuida.

Implementación del factor 1

Para implementar este principio debemos considerar los puntos que siguen:

  • Los cambios al código de una aplicación siempre deben ser manejados en un sistema de control de versiones, como Git o Subversion.
  • El control y seguimiento de los cambios queda centralizado: Existe una sola fuente de la verdad
  • Siempre hay una relación de uno a uno entre la base de código y la aplicación
    • Si hay varias bases de código, no es una aplicación, es un sistema distribuido. Cada componente de un sistema distribuido es una aplicación, y cada uno debe cumplir individualmente con los doce factores.
    • Varias aplicaciones compartiendo el mismo código representa una violación. La solución es factorizar el código compartido en librerías que se puedan incluir a través de un administrador de dependencias (como Maven, gradle, etc.).
  • Solo hay una base de código por aplicación, pero habrá muchos despliegues de esa misma aplicación.
    • Cada despliegue es una instancia, en ejecución, de la aplicación.
    • Pueden estar activas diferentes versiones en cada despliegue.
      • Por ejemplo, un desarrollador puede tener commits que aún no se han implementado en el ambiente de pruebas.
Una base de código, pero muchos deployments

El factor 2: Las dependencias

Las aplicaciones dependen de componentes externos a ellos. Esos componentes existen en distintas versiones. A su vez, esos componentes pueden depender de otros componentes.

Dependencias entre módulos y librerías de una aplicación

Así mismo:

  • Los ambientes existentes pueden tener diversas librerías ya instaladas. Librerías que pueden no existir o diferir de las del resto de los ambientes
  • Las diferencias son fuentes de conflicto
Ambientes con configuraciones distintas

Supongamos una aplicación usa una librería externa para el manejo de fechas, pero esta dependencia no está explícitamente declarada en ningún lugar de la aplicación.

  • Se importa la librería sin una declaración explícita (en vez de incluir esa dependencia en un archivo de configuración)
    • Si la biblioteca cambia o se actualiza, puede afectar la funcionalidad de la aplicación sin que los desarrolladores comprendan la razón.
    • Será difícil la configuración del entorno de desarrollo para desarrolladores que se integren al proyecto, al tener referencias rotas por la ausencia de la librería.

El factor 2 establece el principio “Declare y aísle las dependencias de forma explícita”.

Conceptos

La mayoría de las plataformas de programación tienen sistemas de empaquetado para integrar librerías:

  • Maven y Gradle para Java
  • npm para JavaScript
  • nuget para .NET

Las librerías instaladas a través de un sistema de empaquetado, dependiendo del producto, se pueden instalar a nivel sistema o a nivel del directorio de la aplicación.

  • El uso del nivel adecuado permite aislar dependencias.

El aislamiento se refiere a crear un entorno controlado y autónomo para la aplicación, de modo que sus dependencias no entren en conflicto con otras aplicaciones o con el sistema operativo subyacente.

Implementación del factor 2

Para implementar adecuadamente este factor, debemos considerar las premisas siguientes:

  • Una aplicación nunca debería asumir la existencia implícita de paquetes(librerías) a nivel ambiente.
  • La declaración de dependencias y el aislamiento siempre deben usarse juntos: solo uno u solo el otro, es insuficiente para satisfacer el factor dos.

En seguida:

  1. Se deben declarar todas las dependencias, completa y exactamente, a través de un manifiesto (en Maven es el archivo pom.xml, en npm es package.json).
  2. Se debería utilizar una herramienta de aislamiento de dependencias durante la ejecución, para garantizar que no se «filtren» accidentalmente dependencias al o desde sistemas circundantes. La mayoría de las herramientas de empaquetado ya soportan el aislamiento adecuado, incluso considerando las dependencias sobre la propia herramienta de empaquetado (como Maven wrapper para proyectos en Java).
  3. La especificación de las dependencias se debería aplicar del mismo modo en cualquier ambiente.
Lo que hacen los sistemas de empaquetado como maven, gradle, npm, etc.

Una de las ventajas de la declaración de dependencias es que se simplifica la configuración para los desarrolladores nuevos en la aplicación:

  • Pueden restaurar fácilmente el código base de la aplicación en su equipo de desarrollo, lo que solo requiere que el entorno de ejecución del lenguaje y el sistema de empaquetado estén instalados previamente.
  • Pueden configurar todo lo necesario para ejecutar el código de la aplicación con un comando de armado. Por ejemplo,
    • el comando mvn install en Maven 
    • el comando npm install en npm.

Sugerencias

Si te interesan los temas de Arquitectura y Diseño de software, puedes echar un vistazo al programa educativo siguiente:

Diplomado de formación de Arquitectos de software (DPARQ01)

Continuaremos con los otros factores en entregas futuras… No te las pierdas 🙂

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *