1.1 Arquitectura de la aplicación

Este curso está diseñado para principiantes, porque no estarás diseñando la arquitectura de una aplicación seria durante mucho tiempo. Pero no se preocupe, la buena arquitectura es la excepción y no la regla. Es muy difícil elegir la arquitectura de aplicación correcta antes de construir la aplicación.

Ejemplos de arquitecturas populares para aplicaciones de servidores grandes:

  • Arquitectura en capas (Layered Architecture).
  • Arquitectura escalonada.
  • Arquitectura Orientada a Servicios (SOA).
  • Arquitectura de microservicios (Microservice Architecture).

Cada uno de ellos tiene sus pros y sus contras. Pero estudiarlos no te aportará nada. La arquitectura es la respuesta a la pregunta "cómo organizar la interacción de miles de objetos dentro del sistema" . Y hasta que experimente toda la complejidad del problema, no podrá comprender toda la versatilidad de la solución.

Todas las aplicaciones usan algún tipo de arquitectura, o al menos pretenden hacerlo. Por lo tanto, el conocimiento de los enfoques populares para el diseño de aplicaciones le permitirá comprender mejor y de manera rápida cómo funciona la aplicación. Y eso significa hacer cambios exactamente donde los necesita.

¿Qué significa “hacer cambios donde sea necesario”? ¿Hay lugares donde no es necesario hacer cambios? Exactamente.

Para ser específicos, supongamos que está trabajando en un proyecto de back-end medio . Ha sido escrito durante 5 años por un equipo de 20 personas. El proyecto tomó 100 años-hombre y contiene alrededor de 100 mil líneas de código. En total consta de dos mil clases, las cuales se dividen en 10 módulos de diferentes tamaños.

Y añade una dura realidad. La lógica de algunas tareas se distribuye en varios módulos. Además, la lógica empresarial puede estar en la interfaz (escrita en JavaScript) y/o escrita como un procedimiento almacenado directamente en la base de datos. ¿Todavía está seguro de que puede determinar de inmediato el lugar donde exactamente hacer cambios ?

Esta no es una pesadilla que inventé para asustarte. Este es un proyecto típico. Sucede aún peor. ¿Por qué está pasando esto? Puede haber varias razones, pero casi siempre las hay:

  • Mucha gente trabaja en el proyecto, cada uno de ellos lo ve un poco diferente.
  • Durante 5 años, 10 personas han cambiado en el proyecto, los recién llegados no lo entendieron mucho.
  • La creación de software es una constante realización de cambios que cambian constantemente todo.
  • Hace cinco años, cuando nos decidimos por la arquitectura, la idea del proyecto era algo diferente.

Pero lo principal es que, independientemente de la arquitectura del proyecto, todos los programadores que trabajaron en él se adhirieron a la misma comprensión de cómo funciona este proyecto. Comencemos con el concepto más simple: la arquitectura cliente-servidor.

1.2 El concepto de interacción cliente-servidor

Ahora entenderemos el concepto que subyace en la arquitectura cliente-servidor y te permitirá comprender mejor cómo se organiza la interacción de millones de programas en Internet.

Como su nombre lo indica, este concepto involucra dos partes: cliente y servidor . Aquí todo es como en la vida: el cliente es el cliente de este o aquel servicio, y el servidor es el proveedor del servicio. El cliente y el servidor son programas físicos , por ejemplo, un cliente típico es un navegador .

Los siguientes ejemplos se pueden dar como un servidor:

  • Servidores web como Tomcat.
  • Servidores de bases de datos como MySQL.
  • Pasarelas de pago como Stripe.

El cliente y el servidor se comunican habitualmente a través de Internet (aunque pueden trabajar en la misma red de área local y en general en cualquier otro tipo de redes). La comunicación tiene lugar a través de protocolos estándar como HTTP, FTP o protocolos de nivel inferior como TCP o UDP.

El protocolo suele elegirse de acuerdo con el tipo de servicio que brindan los servidores. Por ejemplo, si se trata de una videollamada, generalmente se usa UDP.

¿Recuerdas cómo funcionan Tomcat y sus servlets? El servidor recibe un mensaje HTTP, lo desempaqueta, extrae toda la información necesaria de allí y la pasa al servlet para su procesamiento. Luego, el resultado del procesamiento se vuelve a empaquetar en una respuesta HTTP y se envía al cliente.

Esta es la típica interacción cliente-servidor. El navegador es el cliente web y Tomcat es el servidor web. Tomcat incluso se llama servidor web.

Pero si lo piensas bien, no es el nombre lo importante, sino la esencia: la distribución de roles entre programas. Su secuencia de comandos JS que se ejecuta en una página HTML bien podría denominarse cliente , y su servlet, servidor . Al fin y al cabo, trabajan por parejas en el marco del concepto cliente-servidor .

1.3 Un matiz importante

También vale la pena señalar que la interacción cliente-servidor se basa en el principio de que dicha interacción la inicia el cliente : el servidor solo responde al cliente e informa si puede proporcionar el servicio al cliente y, de ser así, en qué condiciones. .

No importa dónde se encuentra físicamente el cliente y dónde está el servidor. El software del cliente y el software del servidor generalmente se instalan en diferentes máquinas, pero también pueden ejecutarse en la misma computadora.

Este concepto fue desarrollado como un primer paso hacia la simplificación de un sistema complejo. Ella tiene estas fortalezas:

  • Simplificación de la lógica : el servidor no sabe nada sobre el cliente y cómo utilizará sus datos en el futuro.
  • Puede haber clientes débiles : todas las tareas que consumen muchos recursos se pueden transferir al servidor.
  • Desarrollo independiente de código cliente y código servidor.
  • Muchos clientes diferentes, por ejemplo, Tomcat y diferentes navegadores.

La versión más básica de la interacción entre el cliente y el servidor se muestra en la imagen:

Servidor de cliente

Es importante señalar aquí dos detalles. Primero, la imagen muestra que muchos clientes pueden acceder a un servidor. En segundo lugar, pueden acceder a él al mismo tiempo. Esta es también una parte importante del servidor.

Un cliente generalmente interactúa con un usuario, por lo que a menudo ni siquiera se necesita autorización allí. Sin embargo, el servidor procesa solicitudes de miles de clientes y, al desarrollar código para él, debe poder distinguir entre autorización y autenticación.

También es importante que el servidor procese miles de solicitudes en paralelo. Y esto significa que al desarrollar el código de back-end, deberá pensar constantemente en la tarea de acceso simultáneo a los recursos. Además, el código del servidor tiene una probabilidad muy alta de condición de carrera (carrera de subprocesos), interbloqueo (bloqueo mutuo de subprocesos).

El ciclo de vida de los objetos importantes debe ser monitoreado:

No puede simplemente iniciar un nuevo hilo en el servidor a través de new Thread().start(). En su lugar, debe tener un ThreadPool que se compartirá entre todos los subprocesos de servicio.

Además, no puede simplemente iniciar una tarea asíncrona, porque también se ejecutan en subprocesos separados. Al crear una tarea de este tipo, siempre debe saber qué grupo de subprocesos la está ejecutando y qué sucederá si dicho grupo se desborda.

Todo el trabajo con archivos y directorios debe realizarse a través de try-with-resources. Si en una aplicación normal olvidó cerrar una transmisión o un archivo, ¿es eso un problema? Se cerrará solo cuando salga del programa. Pero si olvidó cerrar un archivo en el servidor en algún lugar del código, y su servidor ha estado funcionando durante meses ... Pronto, se acumularán miles de archivos no cerrados y el sistema operativo dejará de abrir nuevos archivos para leer (trabajar con archivos es controlado por el sistema operativo). Teamlead no te dará palmaditas en la cabeza...

1.4 Arquitectura cliente-servidor

otro punto importante. La arquitectura cliente-servidor define solo los principios generales de interacción entre computadoras , los detalles de la interacción están determinados por varios protocolos.

Este concepto (cliente-servidor) nos dice que debemos dividir las máquinas de la red en máquinas cliente, que siempre necesitan algo, y máquinas servidor, que dan lo que necesitan. En este caso, el cliente siempre inicia la interacción y el protocolo describe las reglas por las que se produce la interacción.

Hay dos tipos de arquitectura de interacción cliente-servidor: la primera se denomina arquitectura cliente-servidor de dos niveles, la segunda es la arquitectura cliente-servidor de varios niveles (a veces denominada arquitectura de tres niveles o arquitectura de tres niveles). pero este es un caso especial).

El principio de funcionamiento de la arquitectura de dos niveles de interacción cliente-servidor es que el procesamiento de una solicitud ocurre en un servidor sin referirse a otros servidores en el proceso de este procesamiento.

El modelo de interacción cliente-servidor de dos niveles se puede dibujar como un diagrama simple.

arquitectura cliente-servidor de dos niveles

Aquí puede ver que el primer nivel es todo lo que concierne al cliente, y el segundo nivel es todo lo que concierne al servidor.