Mostrando las entradas con la etiqueta Microservices. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Microservices. Mostrar todas las entradas

viernes, 14 de octubre de 2022

[eBook] Microservices: From Design to Deployment

 

EBOOK

Ebook: Microservices: From Design to Deployment | Learn about building & deploying microservices

You probably already know that developing your apps using a microservices approach makes them more flexible, more stable, and faster. This eBook provides a useful set of resources to get started in your transition to microservices.

In this free eBook you will learn:

  • When and why it makes sense to adopt microservices
  • How to implement an API gateway to route traffic to microservices
  • Pros and cons of different service discovery patterns
  • Different strategies for refactoring a monolith to microservices

viernes, 16 de septiembre de 2022

Microservices Up and Running

 

EBOOK

[Full eBook] Microservices Up and Running

Hi Emanuel,

Microservices architectures offer faster functional updates, better scalability, and cleaner, evolvable system designs. But implementing your first microservices architecture is difficult. This eBook, compliments of NGINX and O'Reilly Media, provides step-by-step guidance for building an effective microservices architecture.

In this eBook you will learn:

  • How to design an effective and explicit microservices system end-to-end
  • About forming teams, assigning responsibilities, and working together
  • How to establish the right functional boundaries between the microservices that make up an application
  • About building a simple yet powerful CI/CD pipeline for infrastructure changes

jueves, 24 de febrero de 2022

Libros Gratuitos de Java code Geeks

 

Download IT Guides!

 

JPA Minibook

The basic Java framework to access the database is JDBC. Unfortunately, with JDBC, a lot of hand work is needed to convert a database query result into Java classes. Other disadvantages...

 
 

Microservices for Java Developers

Microservices are a software development technique – a variant of the service-oriented architecture (SOA) structural style – that arranges an application as a collection of loosely...

 
 

JMeter Tutorial

JMeter is an application that offers several possibilities to configure and execute load, performance and stress tests using different technologies and protocols. It allows simulating...

 
 

Java Design Patterns

A design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be...

 

martes, 18 de enero de 2022

La arquitectura del service discovery


Para comenzar nuestra discusión sobre la arquitectura de descubrimiento de servicios o service discovery, debemos comprender cuatro conceptos. Estos conceptos generales se comparten en todas las implementaciones de detección de servicios:

  • Registro de servicios: ¿Cómo se registra un servicio con el agente de detección de servicios?
  • Búsqueda del cliente de la dirección del servicio: ¿cuál es el medio por el cual un cliente del servicio busca información del servicio?
  • Información compartida: ¿Cómo se comparte la información del servicio entre los nodos?
  • Supervisión del estado: ¿cómo comunican los servicios su estado al agente de detección de servicios?

A medida que se inician las instancias de servicio, registrarán su ubicación física, ruta y puerto a los que se puede acceder con una o más instancias de detección de servicios. Si bien cada instancia de un servicio tendrá una dirección IP y un puerto únicos, cada instancia de servicio que surja se registrará con la misma ID de servicio. Un ID de servicio no es más que una clave que identifica de forma única a un grupo de las mismas instancias de servicio.

Por lo general, un servicio solo se registrará con una instancia de servicio de detección de servicios. La mayoría de las implementaciones de detección de servicios utilizan un modelo de propagación de datos de igual a igual en el que los datos de cada instancia de servicio se comunican a todos los demás nodos del clúster.

Dependiendo de la implementación del descubrimiento de servicios, el mecanismo de propagación podría usar una lista codificada de servicios para propagar o usar un protocolo de multidifusión. Como el protocolo "gossip" o "infection-style" para permitir que otros nodos "descubran" cambios en el clúster.

Finalmente, el servicio de detección de servicios empujará o sacará de su estado cada instancia de servicio. Cualquier servicio que no devuelva una buena verificación de estado se eliminará del conjunto de instancias de servicio disponibles.

Una vez que un servicio se ha registrado en un servicio de descubrimiento de servicios, está listo para ser utilizado por una aplicación o servicio que necesita usar sus capacidades. Existen diferentes modelos para que un cliente “descubra” un servicio. Un cliente puede confiar únicamente en el motor de descubrimiento de servicios para resolver las ubicaciones de los servicios cada vez que se llama a un servicio. Con este enfoque, el motor de detección de servicios se invocará cada vez que se realice una llamada a una instancia de microservicio registrada. Desafortunadamente, este enfoque es frágil porque el cliente del servicio depende completamente del motor de detección de servicios que se está ejecutando para encontrar e invocar un servicio.

Un enfoque más sólido es utilizar lo que se denomina balanceo de carga del lado del cliente. En este modelo, cuando un actor consumidor necesita invocar un servicio, se pondrá en contacto con el servicio de detección de servicios para todas las instancias de un servicio. El consumidor está solicitando y luego almacenar en caché los datos localmente en la máquina del consumidor del servicio.

Cada vez que un cliente desee llamar al servicio, el consumidor del servicio buscará la información de ubicación del servicio en la memoria caché. 

El almacenamiento en caché utilizará un algoritmo de balanceo de carga simple como el algoritmo de balanceo de carga "round-robin" para garantizar que las llamadas de servicio se distribuyan entre múltiples instancias de servicio.

Luego, el cliente se comunicará periódicamente con el servicio de descubrimiento de servicios y actualizará su caché de instancias de servicio. El caché del cliente finalmente es consistente, pero siempre existe el riesgo de que, entre el momento en que el cliente se pone en contacto con la instancia de detección de servicios para una actualización y se realicen las llamadas, las llamadas se dirijan a una instancia de servicio que no está en buen estado.

Si, durante el transcurso de la llamada a un servicio, la llamada de servicio falla, la memoria caché de detección de servicios local se invalida y el cliente de detección de servicios intentará actualizar sus entradas desde el agente de detección de servicios.

lunes, 17 de enero de 2022

Como tiene que ser el Service discovery en microservicios?


Ya vimos que no podemos utilizar un balanceador de carga tradicional para implementar el service discovery. Dado que la solución para un entorno de microservicios basado en la nube es usar un mecanismo de descubrimiento de servicios debe ser :

  • Altamente disponible: el descubrimiento de servicios debe ser compatible con un entorno de agrupación en clúster "caliente" donde las búsquedas de servicios se pueden compartir entre varios nodos en un clúster de descubrimiento de servicios. Si un nodo deja de estar disponible, otros nodos del clúster deberían poder reemplazarlo.
  • De igual a igual: cada nodo en el clúster de detección de servicios comparte el estado de una instancia de servicio.
  • Equilibrio de carga: el descubrimiento de servicios debe equilibrar dinámicamente la carga de solicitudes en todas las instancias de servicio para garantizar que las invocaciones de servicio se distribuyan en todas las instancias de servicio que gestiona. En muchos sentidos, el descubrimiento de servicios reemplaza a los balanceadores de carga más estáticos y administrados manualmente que se usaban en muchos de los primeras implementaciones de aplicaciones web.
  • Resiliente: el cliente del descubrimiento de servicios debe "almacenar en caché" la información del servicio localmente. El almacenamiento en caché local permite la degradación gradual del descubrimiento del servicio para que si el servicio de detección de servicios no está disponible, las aplicaciones aún pueden funcionar y ubicar los servicios en función de la información mantenida en su caché local.
  • Tolerante a fallas: el descubrimiento de servicios debe detectar cuándo una instancia de servicio no está en buen estado y eliminar la instancia de la lista de servicios disponibles que pueden tomar solicitudes de clientes. Debe detectar estas fallas con los servicios y tomar medidas sin intervención humana.

Podemos usar balanceadores de carga para implementar service discovery?


Hemos repasado los beneficios del descubrimiento de servicios, pero ¿cuál es el problema? Después de todo, ¿no podemos usar métodos probados y verdaderos como DNS (Servicio de nombres de dominio) o un balanceador de carga para ayudar a facilitar el descubrimiento de servicios? Analicemos por qué eso no funciona con una aplicación basada en microservicios, particularmente una que se ejecuta en la nube.

Siempre que tenga una aplicación que llama a recursos repartidos en varios servidores, necesita ubicar la ubicación física de esos recursos. En el mundo normal (no clud), esta resolución de ubicación de servicio a menudo se resolvía y se resuelve mediante una combinación de DNS y un balanceador de carga. 

Una aplicación si necesita invocar un servicio intenta invocar el servicio utilizando un nombre genérico junto con una ruta que representa de forma única el servicio que la aplicación intentaba invocar. El nombre DNS se resolvería en un balanceador de carga. 

El balanceador de carga, al recibir la solicitud del consumidor del servicio, ubica la entrada de la dirección física en una tabla de enrutamiento según la ruta a la que el usuario intentaba acceder. Esta entrada de la tabla de enrutamiento contiene una lista de uno o más servidores que alojan el servicio. Luego, el balanceador de carga elige uno de los servidores de la lista y reenvía la solicitud a ese servidor.

Cada instancia de un servicio se implementa en uno o más servidores de aplicaciones. La cantidad de estos servidores de aplicaciones a menudo era estática (por ejemplo, la cantidad de servidores de aplicaciones que alojaban un servicio no aumentaba ni disminuía) y persistente (por ejemplo, si fallaba un servidor que ejecutaba un servidor de aplicaciones, se restauraría al estado actual). mismo estado que tenía en el momento del bloqueo, y tendría la misma IP y configuración que tenía anteriormente).

Para lograr una forma de alta disponibilidad, un balanceador de carga secundario está inactivo y hace ping al balanceador de carga principal para ver si está activo. Si no está activo, el balanceador de carga secundario se activa, asumiendo la dirección IP del balanceador de carga principal y comenzando a atender las solicitudes.

Si bien este tipo de modelo funciona bien con aplicaciones que se ejecutan dentro de las cuatro paredes de un centro de datos corporativo y con una cantidad relativamente pequeña de servicios que se ejecutan en un grupo de servidores estáticos, no funciona bien para aplicaciones de microservicio basadas en la nube. Las razones para esto incluyen :

  • Punto único de falla: si bien el balanceador de carga puede tener una alta disponibilidad, es un punto único de falla para toda su infraestructura. Si el balanceador de carga se cae, todas las aplicaciones que dependen de él también se caen. Si bien puede hacer que un balanceador de carga esté altamente disponible, los balanceadores de carga tienden a ser cuellos de botella centralizados dentro de la infraestructura de la aplicación.
  • Escalabilidad horizontal limitada: al centralizar sus servicios en un solo grupo de balanceadores de carga, tiene una capacidad limitada para escalar horizontalmente su infraestructura de balanceo de carga en varios servidores. Muchos balanceadores de carga comerciales están limitados por dos cosas: su modelo de redundancia y los costos de licencia. La mayoría de los balanceadores de carga comerciales usan un modelo de intercambio en caliente para la redundancia, por lo que solo tiene un único servidor para manejar la carga, mientras que el balanceador de carga secundario está allí solo para la conmutación por error en el caso de una interrupción del balanceador de carga principal. Estás, en esencia, limitado por tu hardware. En segundo lugar, los balanceadores de carga comerciales también tienen modelos de licencia restrictivos orientados a una capacidad fija en lugar de un modelo más variable.
  • Gestionado estáticamente: la mayoría de los balanceadores de carga tradicionales no están diseñados para registrar y cancelar el registro de servicios rápidamente. Usan una base de datos centralizada para almacenar las rutas para las reglas y la única forma de agregar nuevas rutas es a menudo a través de la API (interfaz de programación de aplicaciones) propietaria del proveedor.
  • Complejo: debido a que un balanceador de carga actúa como un proxy para los servicios, las solicitudes de los consumidores de servicios deben tener sus solicitudes asignadas a los servicios físicos. Esta capa de traducción a menudo agregaba una capa de complejidad a su infraestructura de servicio porque las reglas de mapeo para el servicio deben definirse e implementarse a mano. En un escenario de balanceador de carga tradicional, este registro de nuevas instancias de servicio se realizaba a mano y no en el momento del inicio de una nueva instancia de servicio.

Estas cuatro razones no son una acusación general de los balanceadores de carga. Funcionan bien en un entorno corporativo donde el tamaño y la escala de la mayoría de las aplicaciones pueden manejarse a través de una infraestructura de red centralizada. Además, los balanceadores de carga aún tienen un papel que desempeñar en términos de centralizar la terminación SSL y administrar la seguridad del puerto del servicio. Un balanceador de carga puede bloquear el acceso al puerto de entrada (entrada) y salida (salida) a todos los servidores que se encuentran detrás de él. Este concepto de acceso mínimo a la red suele ser un componente crítico cuando se trata de cumplir con los requisitos de certificación estándar de la industria, como el cumplimiento de PCI (industria de tarjetas de pago).

Sin embargo, en la nube, donde tiene que lidiar con cantidades masivas de transacciones y redundancia, una pieza centralizada de infraestructura de red no funciona tan bien en última instancia porque no se escala de manera efectiva y no es rentable. 

viernes, 14 de enero de 2022

Que es service discovery?


En cualquier arquitectura distribuida, necesitamos encontrar la dirección física de donde se encuentra una máquina. Este concepto ha existido desde el comienzo de la computación distribuida y se conoce formalmente como descubrimiento de servicios. El descubrimiento de servicios puede ser algo tan simple como mantener un archivo de propiedades con las direcciones de todos los servicios remotos utilizados por una aplicación, o algo tan formalizado (y complicado) como un repositorio UDDI (Descripción Universal, Descubrimiento e Integración) El descubrimiento de servicios es crítico a aplicaciones de microservicio basadas en la nube por dos razones claves:

Ofrece al equipo de aplicaciones la capacidad de escalar horizontalmente rápidamente la cantidad de instancias de servicio que se ejecutan en un entorno. Los consumidores del servicio se abstraen de la ubicación física del servicio a través del descubrimiento del servicio. Debido a que los consumidores del servicio no conocen la ubicación física de las instancias de servicio reales, se pueden agregar o eliminar nuevas instancias de servicio del grupo de servicios disponibles. 

Esta capacidad de escalar rápidamente los servicios sin interrumpir a los consumidores del servicio es un concepto extremadamente poderoso, porque hace que un equipo de desarrollo acostumbrado a crear aplicaciones monolíticas deje de pensar en escalar solo en términos de agregar mayores , mejor hardware (escalado vertical) al enfoque más potente de escalado mediante la adición de más servidores (escalado horizontal). 

Un enfoque monolítico suele llevar a los equipos de desarrollo por el camino de sobrecomprar sus necesidades de capacidad. Los aumentos de capacidad vienen en grupos y picos y rara vez son un camino suave y constante. Los microservicios nos permiten escalar hacia arriba o hacia abajo nuevas instancias de servicio. El descubrimiento de servicios ayuda a abstraer que estas implementaciones ocurren lejos del consumidor del servicio.

El segundo beneficio del descubrimiento de servicios es que ayuda a aumentar la resistencia de las aplicaciones. Cuando una instancia de microservicio no está en buen estado o no está disponible, la mayoría de los motores de detección de servicios eliminarán esa instancia de su lista interna de servicios disponibles.

El daño causado por un servicio inactivo se minimizará porque el motor de descubrimiento de servicios enrutará los servicios alrededor del servicio no disponible.


jueves, 13 de enero de 2022

Consumir configuraciones de un servidor de configuración con Spring Cloud




Se acuerdan que en un post anterior hicimos un servidor de configuración con Spring Cloud. Ahora vamos a utilizarlo. 

Cuando el cliente se inicia por primera vez, pasará el perfil de Spring y el end point para comunicarse con el servicio de configuración de Spring Cloud. El valor del perfil Spring se asigna al entorno de las propiedades que se recuperan para el servicio Spring. El servicio Spring Cloud Config luego usará el repositorio de configuración de back-end configurado (sistema de archivos, Git, Consul, Eureka) para recuperar la información de configuración específica para el valor del perfil de Spring pasado en el URI. Spring Boot luego inyectará estos valores en las partes apropiadas de la aplicación.

Lo primero que debe hacer es agregar un par de entradas más al archivo Maven :

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-config-client</artifactId>

</dependency>

La dependencia, spring-cloud-config-client, contiene todas las clases necesarias para interactuar con el servidor de configuración de Spring Cloud.

Una vez definidas las dependencias de Maven, debe indicarle al servicio dónde ponerse en contacto con el servidor de configuración de Spring Cloud. En un servicio Spring Boot que usa Spring Cloud Config, la información de configuración se puede establecer en uno de dos archivos de configuración: bootstrap.yml y application.yml.

El archivo bootstrap.yml lee las propiedades de la aplicación antes de utilizar cualquier otra información de configuración. En general, el archivo bootstrap.yml contiene el nombre de la aplicación para el servicio, el perfil de la aplicación y el URI para conectarse a un servidor Spring Cloud Config.

Cualquier otra información de configuración que desee mantener local para el servicio (y no almacenada en Spring Cloud Config) se puede configurar localmente en los servicios en el archivo application.yml. Por lo general, la información que almacena en el archivo application.yml son datos de configuración que quizás desee tener disponibles para un servicio, incluso si el servicio Spring Cloud Config no está disponible. Los archivos bootstrap.yml y application.yml se almacenan en un directorio de proyectos src/main/resources.

Para que el cliente se comunique con su servicio Spring Cloud Config, debe agregar un archivo /src/main/resources/bootstrap.yml y configurar tres propiedades: spring.application.name, spring.profiles.active y spring.cloud.config.uri.

El archivo bootstrap.yml de los servicios de licencias se muestra en la siguiente lista.

spring.application.name es el nombre de su aplicación y debe asignarse directamente al nombre del directorio dentro de su servidor de configuración de Spring Cloud. Para el servicio de licencias, desea un directorio en el servidor de configuración de Spring Cloud llamado licenseservice.

La segunda propiedad, spring.profiles.active, se usa para decirle a Spring Boot con qué perfil debe ejecutarse la aplicación. Un perfil es un mecanismo para diferenciar los datos de configuración consumidos por la aplicación Spring Boot. Para el perfil del cliente, admitirá el entorno al que se asignará el servicio directamente en su entorno de configuración de la nube. Por ejemplo, al pasar dev como nuestro perfil, el servidor de configuración de Spring Cloud usará las propiedades dev. Si establece un perfil, el servicio de licencias utilizará el perfil predeterminado.
La tercera y última propiedad, spring.cloud.config.uri, es la ubicación donde el servicio de licencias debe buscar el servidor de configuración de Spring Cloud.

punto final. De forma predeterminada, el servicio de licencias buscará el servidor de configuración en http://localhost:8888. Más adelante en el capítulo, verá cómo anular las diferentes propiedades definidas en los archivos boostrap.yml y application.yml al iniciar la aplicación. Esto le permitirá decirle al microservicio de licencias en qué entorno se debe ejecutar.

Ahora, si abre el servicio de configuración de Spring Cloud, con la base de datos de Postgres correspondiente ejecutándose en su máquina local, puede iniciar el servicio de licencias utilizando su perfil predeterminado. Esto se hace cambiando al directorio de servicios de licencias y emitiendo los siguientes comandos:
 
 mvn spring-boot: ejecutar

Al ejecutar este comando sin establecer ninguna propiedad, el servidor de licencias intentará conectarse automáticamente al servidor de configuración de Spring Cloud utilizando el punto final (http://localhost:8888) y el perfil activo (predeterminado) definido en bootstrap.yml archivo del servicio de licencias.

Si desea anular estos valores predeterminados y apuntar a otro entorno, puede hacerlo compilando el proyecto de servicio de licencias en un JAR y luego ejecutar
el JAR con una anulación de propiedad del sistema -D. La siguiente llamada de línea de comando demuestra cómo iniciar el servicio de licencias con un perfil no predeterminado:

java -Dspring.cloud.config.uri=http://localhost:8888 \
-Dspring.profiles.active=dev \
-jar destino/servicio de licencias-0.0.1-SNAPSHOT.jar

Con la línea de comando anterior, está anulando los dos parámetros:
spring.cloud.config.uri y spring.profiles.active. Con la propiedad del sistema -Dspring.cloud.config.uri=http://localhost:8888, está apuntando a un servidor de configuración que se está ejecutando fuera de su caja local.

Con la propiedad del sistema –Dspring.profiles.active=dev, le indica al cliente que use el perfil de desarrollo (leído del servidor de configuración) 


domingo, 9 de enero de 2022

Construyendo nuestro servidor de configuración con Spring Cloud


El servidor de configuración de Spring Cloud es una aplicación basada en REST que está construida sobre Spring Boot. No viene como un servidor independiente. En su lugar, puede elegir embeberlo en una aplicación Spring Boot existente o iniciar un nuevo proyecto Spring Boot con el servidor embebido.

Vamos a hacer una nueva aplicación string boot como servidor de configuraciones. Yo voy a utilizar spring initializr pero podemos agregar estas dependencias en un nuevo proyecto o uno existente. 

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-config</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-config-server</artifactId>

</dependency>

</dependencies>

O con gradle sería así : 

implementation 'org.springframework.cloud:spring-cloud-starter-config'

implementation 'org.springframework.cloud:spring-cloud-config-server'


La primera dependencia es la dependencia spring-cloud-starter-config que utilizan todos los proyectos de Spring Cloud. La segunda dependencia es el proyecto de inicio spring-cloud-config-server. Esto contiene las bibliotecas centrales para spring-cloud-config-server.

Necesitamos configurar un archivo más para que el servidor de configuración central esté en funcionamiento. Este archivo es el archivo application.yml y lo debemos generar en el directorio src/main/resources. El archivo application.yml le dirá a su servicio de configuración de Spring Cloud qué puerto escuchar y dónde ubicar el back-end que entregará los datos de configuración. En mi caso el appication.yml es así : 

server:
port: 8888
spring:
profiles:
active: native
cloud:
config:
server:
native:
searchLocations: file:///{projectPath}/resources

Ojo que {projectPath} es donde esta el proyecto, la dirección por ejemplo el mio esta en /home/emanuel/misProyectos/application. 

En la configuración de Spring Cloud, todo funciona con una jerarquía. La configuración de la aplicación está representada por el nombre de la aplicación y luego un archivo de propiedades para cada entorno para el que se desea tener información de configuración. En cada uno de estos entornos, configurará dos propiedades de configuración. 

Vamos a suponer que tenemos 3 entornos uno de dev, otro de uat y otro de prod. Vamos a crear directorios para cada uno de los entornos en src/main/resources una carpeta por cada entorno. 

El mapeo de las carpetas y los archivos va a ser de la siguiente manera : 

/{application}/{profile}[/{label}]

/{application}-{profile}.yml

/{label}/{application}-{profile}.yml

/{application}-{profile}.properties

/{label}/{application}-{profile}.properties

Noten que el label es opcional. Por lo tanto si hacemos archivos application-dev.properties o application-uat.properties esto debería andar. 

Y por ultimo le decimos a spring que vamos a utilizar spring config con esta anotación : 


@SpringBootApplication
@EnableConfigServer
public class SettingsApplication {

Ahora levantamos el servidor y si necesitamos las configuraciones de uat deberíamos hacer : 

http://localhots:8888/application/uat

Tendremos este resultado : 

{"name":"demo","profiles":["uat"],"label":null,"version":null,"state":null,"propertySources":[{"name":"file:/home/emanuel/Projects/spring-cloud/settings/src/main/resources/demo-uat.yml","source":{"env":"dev"}},{"name":"file:/home/emanuel/Projects/spring-cloud/settings/src/main/resources/application.yml","source":{"server.port":8888,"spring.profiles.active":"native","spring.cloud.config.server.native.searchLocations":"file:///home/emanuel/Projects/spring-cloud/settings/src/main/resources"}}]}
Y listo, nos queda ver como podemos consumir estos settings. (pero eso es para otro post) 

Dejo link: https://cloud.spring.io/spring-cloud-config