Plataforma de Microservicios casi terminada

Abixen Platform es una plataforma de software basada en microservicios (microservices) para construir aplicaciones empresariales. El objetivo principal del proyecto es la creación de funcionalidades por medio de la creación de microservicios específicos o particulares y la integración por medio de CMS. También está disponible el API de Abixen Platform, que permite acelerar el proceso de creación de nuevos microservicios. Ve al enlace para mayor detalle:

  

Abixen Platform is a microservices based software platform...

 

- Te gustaría unirte a la comunidad de la plataforma Abixen y desarrollar para un proyecto de rápido crecimiento en GitHub?

- Eres bueno en Java y/o en tecnologías front-end como AngularJS, CSS, HTML?

- Tal vez eres un experto de UI/UX y estás dispuesto a mejorar el diseño y experiencia de usuario de la plataforma Abixen!.

- Te gustaría unirte a un grupo de geeks?

 

De ser cierta alguna o varias de las anteriores, estamos listos para darte un corto pero poderoso entrenamiento de la plataforma Abixen. Luego de tu entrenamiento serás capaz de desarrollar, en conjunto con nosotros, la plataforma Abixen. 

Por favor déjanos saber!!

 

Este es el link del proyecto en GitHub, dale una revisada.

 

 

 

 

Add a comment

Spring Boot - Microservicios de Descubrimiento, proxy y tolerancia a fallos (Eureka, Zuul, Ribbon y Histrix de Netflix)

- Agregamos un servidor de configuración totalmente independiente de todos los servicios a construir.

- Sabemos que los microservicios / microservices deben estar disponibles para comunicarse entre ellos y que debe ser por medio de algún servicio de descubrimiento como Eureka (de Netflix), ZooKeeper, etc. así que agreamos un servicio de descubrimiento.

- Trabajando con microservicios / microservices, tenemos tantas entradas (urls) como servicios tengamos programados. Si tenemos un módulo que entrega información de productos, usuarios, consumo, descripciones, etc. tendríamos al rededor de unos 60 microservicios (por poner un ejemplo) por lo tanto es necesario agregar un patrón conocido como Servicio Edge (que se subdivide en Micro-Proxy y API Gateway); para nuestra cápsula un micro-proxy bastará para tener un solo punto de entrada (single entry point) hacia los servicios que entregan la información mencionada.

Un MicroProxy concentra las llamadas, en un solo punto de entrada, y las distribuye de forma inteligente hacia los servicios en la parte de atrás; Por qué inteligente? porque agrega por defecto un balanceador de cargas que garantiza la disponibilidad balanceada entre los distintos servicios o entre la redundancia que de forma natural permite la arquitectura de microservicios.

Para nuestro ejemplo utilizaremos Zuul (de Netflix).

- Además para asegurar flujos de trabajo constantes y fluidos, tenemos que hacer nuestro sistema altamente tolerante a fallos. Para lo anterior agregamos Hystrix (también de Netflix).

 

 

- Prerequisitos

* Servidor de configuración, servidor de descubrimiento Eureka y Servicio que consulte productos.

* Servidor MicroProxy Zuul (a construir)

* Tolerancia a fallos con Hystrix (a construir)

 

Bonus, que es una librería para interpretar los resultados del servicio de consulta. HATEOAS.

 

ZUUL

1. Configuración MAVEN

<name>ledzedev-producto-cliente</name>
<description>Demo de Spring Boot de un Microproxy con Zuul y Tolerancia a fallos con Hystrix. Además del uso de la librería HATEOAS.</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

2. Configuración properties (local al servicio y el archivo por convención se debe llamar bootstrap.properties)

spring.application.name=producto-cliente
spring.cloud.config.uri=http://localhost:8888 # aquí es donde tenemos nuestro servidor de configuración

 

3. Configuración remota (producto-cliente.yml); en mi caso prefiero el formato YAML pero también puede ser properties.

Nota: El servidor Eureka sube por defecto en el puerto: 8761

server:
   port: 9999

eureka:
   client:
      serviceUrl:
         defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
   instance:
      preferIpAddress: true

 

3. Código Java

/**
* Código generado por Gerado Pucheta Figueroa
* Twitter: @ledzedev
* http://ledze.mx
* 01/Dic/2016.
*/
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class LedzedevProductoClienteApplication {

public static void main(String[] args) {
SpringApplication.run(LedzedevProductoClienteApplication.class, args);
}
}

 

4. Arrancamos nuestra aplicación y consultamos tal como lo definimos en el yaml en el navegador: http://localhost:9999/producto-service/productoes

y debemos ver el servicio pero por medio de nuestro single entry point y no directo a nuestro servidor:

 

 

 

Solo para comparar, este es el acceso del servidor que consulta los datos de los productos:

 

EUREKA

Es importante que la pantalla de monitoreo de Eureka se mantenga limpia, sin mensajes de error y debe mostrar los dos servicios registrados.

 

HYSTRIX

- Tolerancia a Fallos.

- Agregamos nuestro servicio RESTful que consulte únicamente los nombres de los productos, no necesitamos todo, así que lo agregamos e implementamos la tolerancia a fallos así como el método que nos permitirá consultar información de los productos con balanceo de cargas.

 

1. Configuración MAVEN (Solo hay que agregar la dependencia en nuestro mismo proyecto)

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

 

2. Código Java

Simplemente agregamos la anotación @EnableCircuitBreaker

@EnableCircuitBreaker
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class LedzedevProductoClienteApplication {
public static void main(String[] args) {
SpringApplication.run(LedzedevProductoClienteApplication.class, args);
}
}


Clase con el servicio RESTful que consulta información de los productos. Al método que consulta se le agrega la anotación @HystrixCommand y se le da la referencia del método que se ejecutará en caso de fallo.
/**
* Código generado por Gerado Pucheta Figueroa
* Twitter: @ledzedev
* http://ledze.mx
* 01/Dic/2016.
*/
@RestController
class ProductoApiGatewayRestController {

private static final Logger LOG = LoggerFactory.getLogger(ProductoApiGatewayRestController.class);

@Bean
@LoadBalanced
public RestTemplate restTemplate(){

return new RestTemplate();
};

@Autowired
RestTemplate restTemplate;


public Collection<String> getNombreProductosFallback(){
return Arrays.asList("Error al obtener los nombres de los productos en la tienda de la esquina.");
}

@HystrixCommand(fallbackMethod = "getNombreProductosFallback")
@RequestMapping(method = RequestMethod.GET, value = "/nomprod")
public Collection<String> getNombreProductos(){
LOG.info("Obteniendo nombre de productos");

ParameterizedTypeReference<Resources<Producto>> ptr =
new ParameterizedTypeReference<Resources<Producto>>() { };

ResponseEntity<Resources<Producto>> entity = this.restTemplate.exchange("http://producto-service/productoes", HttpMethod.GET, null, ptr);

return entity.getBody()
.getContent()
.stream()
.map(Producto::getNombreProducto)
.collect(Collectors.toList());
}
}

IMPORTANTE: Nótese que en el exchange, agregamos el id del servicio, no es un host.


Esta es solo una representación del objeto Producto original, podríamos agregar el jar que contiene el objeto original, pero eso sería ir en contra de nuestra arquitectura de microservicios.

/**
* Código generado por Gerado Pucheta Figueroa
* Twitter: @ledzedev
* http://ledze.mx
* 01/Dic/2016.
*/
class Producto {

private String nombreProducto;

public String getNombreProducto() {
return nombreProducto;
}
}

3. Consultamos en el navegador la dirección de nuestro cliente http://localhost:9999/nomprod.

 

 

4. Deliveradamente tiramos el servicio que consulta los productos y nuevamente consultamos nuestro cliente http://localhost:9999/nomprod.

 

 

CONCLUYENDO

Tenemos 2 servicios (que son totalmente independientes y que se comunican entre si) montados en una arquitectura de microservicios dividida de la siguiente manera:

1) Servidor de configuración

2) Servidor de descubrimiento (Eureka)

3) Servidor de consulta de productos.

4) Servidor Zuul (patrón Micro-Proxy) para enmascarar las llamadas en un solo punto de entrada.

5) Servicio REST que funciona como cliente y que consulta únicamente los nombres de los productos.

 

BONUS

6) Para poder obtener únicamente un aparte de la información se utiliza la librería de HATEOAS para poder utilizar una representación del objeto original.

 

 

Te puedes descargar mi código directamente del repositorio:

Ledzedev archivos de configuración -> github / formato zip

Ledzedev Servidor de configuración -> github / formato zip

Ledzedev Eureka Server -> github / formato zip

Ledzedev servicio RESTful de consulta de productos -> github / formato zip

Ledzedev Microservicios Zuul, Hystrix, RESTful cliente de consulta de nombres -> github / formato zip

 

 

Artículos Relacionados

- Spring Boot Microservicio de Mensajería en complemento con tolerancia a fallos.

 

 

 

 

 

 

Add a comment

Spring Boot Eureka (Netflix) Discovery Server - Microservicios/Microservices

En la arquitectura de Microservices o Microservicios, se define cada servicio como una unidad de procesamiento de una sola tarea simple y que se puedan comunicar con otros microservicios; básicamente siguiendo el mismo paradigma del sistema operativo unix (procesos que realicen una sola tarea simple, pero que la realicen bien y que se pueda comunicar con otros procesos iguales).

Dicho lo anterior, cada microservicio debe realizar una tarea simple y debe ser posible descubrir otros microservicios y ser descubierto por otros. Para lo anterior han salido unos cuantos servicios como Eureka, que escribió el equipo de Netflix para el balanceo de cargas y tolerancia a fallos en sus sistemas; afortunadamente para nosotros liberaron ese proyecto como Open Source y ahora lo podemos utilizar para descubrir servicios en la nube.

 

- Prerequisitos

Estar familiarizado con la construcción de proyectos simples con Spring Boot - Initializr

Un microservicio que se dedique a administrar la configuración en la nube.

* Spring Boot - Servicio de configuracion en la nube (github o svn) / Spring Cloud Config Server

Un microservicio que consulte productos (a construir)

Servidor Eureka para descubrir el microservicios de productos (a construir); Eureka de Netflix?

 

Servidor Eureka

- Generar el proyecto simple con Spring Boot Initializr

* spring-cloud-starter-config

* spring-cloud-starter-eureka-server

 

1. Configuración Maven

<groupId>com.ledzedev</groupId>
<artifactId>ledzedev-eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>ledzedev-eureka-server</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>

2. Properties de configuración.

Eliminar el archivo application.properties y crear uno nuevo que se llame bootstrap.properties (también puedes simplemente renombrarlo y listo). Por convención el archivo se debe llamar bootstrap.properties.

spring.application.name=eureka-service #agregamos el id del servidor, así buscará su configuración
spring.cloud.config.uri=http://localhost:8888 #asumimos que el servidor de configuración se levantó en el puerto 8888 (por convención ahí se levantan los servicios de configuración).

 

3. Código Java

Simplemente agregamos a la clase principal la anotación @EnableEurekaServer, para habilitar el servicio.

/**
* Código generado por Gerado Pucheta Figueroa
* Twitter: @ledzedev
* http://ledze.mx
* 24/Nov/2016.
*/
@SpringBootApplication
@EnableEurekaServer
public class LedzedevEurekaServerApplication {


public static void main(String[] args) {
SpringApplication.run(LedzedevEurekaServerApplication.class, args);
}
}

 

4. Levantando Eureka.

NOTA: En este momento ya debe estar levantado el Spring Boot - Servicio de configuracion en la nube (github o svn) / Spring Cloud Config Server

Ejecutamos la clase principal LedzedevEurekaServerApplication, comprobamos que levanta correctamente y que la herramienta está expuesta en su propio servidor.

 

 

Microservicio de consulta de productos

- Generar el proyecto simple con Spring Boot Initializr

* spring-cloud-starter-config

* spring-cloud-starter-eureka-server

* spring-boot-starter-actuator

* spring-cloud-starter-eureka

* spring-boot-starter-data-jpa

* spring-boot-starter-data-rest

* spring-boot-starter-web

* h2

1. Configuración Maven.

<groupId>com.ledzedev.demo</groupId>
<artifactId>ledzedev-microservice-spring-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>ledzedev-microservice-spring-cloud</name>
<description>Proyecto demo de un micro servicio con jpa, datarest, RESTful, Spring cloud config server y Eureka</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

2. Properties de configuración

Eliminar el archivo application.properties y crear uno nuevo que se llame bootstrap.properties (también puedes simplemente renombrarlo y listo). Por convención el archivo se debe llamar bootstrap.properties.

spring.application.name=producto-service
spring.cloud.config.uri=http://localhost:8888

3. Código Java

* Agregamos la entidad de Productos

/**
* Código generado por Gerado Pucheta Figueroa
* Twitter: @ledzedev
* http://ledze.mx
* 24/Nov/2016.
*/
@Entity
public class Producto {


@Id
@GeneratedValue
private Long id;


private String nombreProducto;

private Long cantidadExistente;

public Producto(String nombreProducto, Long cantidadExistente) {
this.nombreProducto = nombreProducto;
this.cantidadExistente = cantidadExistente;
}

public Producto() {//nadie sabe por qué, pero es requisito de JPA
}


public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getNombreProducto() {
return nombreProducto;
}

public void setNombreProducto(String nombreProducto) {
this.nombreProducto = nombreProducto;
}

public Long getCantidadExistente() {
return cantidadExistente;
}

public void setCantidadExistente(Long cantidadExistente) {
this.cantidadExistente = cantidadExistente;
}

@Override
public String toString() {

return "Producto{" +
"id=" + id +
", nombreProducto='" + nombreProducto + '\'' +
", cantidadExistente=" + cantidadExistente +
'}';
}
}

* Agregamos la interfaz que hable con la BD (h2 para el ejemplo pero puede ser cualquier otro manejador soportado por Spring)

/**
* Código generado por Gerado Pucheta Figueroa
* Twitter: @ledzedev
* http://ledze.mx
* 16/Nov/2016.
*/
@RepositoryRestResource
public interface RepositorioProductosDB extends JpaRepository<Producto, Long> {

@RestResource(path = "by-np")
Collection<Producto> findByNombreProducto(@Param("np") String nombreProd);

}

* Anotamos la clase principal como cliente de Eureka con @EnableEurekaClient y le agregamos una carga inicial de productos a la BD.

/**
* Código generado por Gerado Pucheta Figueroa
* Twitter: @ledzedev
* http://ledze.mx
* 24/Nov/2016.
*/
@EnableEurekaClient
@SpringBootApplication
public class LedzedevMicroserviceSpringCloudApplication {


private static final Logger log = LoggerFactory.getLogger(LedzedevMicroserviceSpringCloudApplication.class);

public static void main(String[] args) {
SpringApplication.run(LedzedevMicroserviceSpringCloudApplication.class, args);
}

@Bean
CommandLineRunner runner(RepositorioProductosDB db){

return args -> {
Arrays.asList(
new Producto("Queso Oaxaca", 50L),
new Producto("Queso Cotija", 4L),
new Producto("Queso Panela", 20L),
new Producto("Crema entera", 10L),
new Producto("Crema deslactosada", 18L),
new Producto("Gelatina", 7L),
new Producto("Yakult", 80L),
new Producto("Refresco", 12L)
)
.forEach(db::save);
log.info("Carga inicial terminada.");
};
}
}

4. Levantando el microservicio de consulta de productos

NOTA: En este momento ya debe estar levantado el Spring Boot - Servicio de configuracion en la nube (github o svn) / Spring Cloud Config Server

Ejecutamos la clase principal LedzedevMicroserviceSpringCloudApplication, comprobamos que levanta correctamente y que el servicio de consulta está expuesto en la red.

 

 

CONCLUYENDO

El servidor de Eureka registra automáticamente en la nube la aplicación con el Id dado en configuración, en este caso PRODUCTO-SERVICE. Esto hace nuestro microservicio en estado "descubrible", por lo que otros microservicios se podrán comunicar sin problemas para realizar una consulta de productos.

 

Al refrescar nuestra herramienta de Eureka, podemos observar que hay actualmente una instancia que se llama PRODUCTO-SERVICE que corresponde con el microservicio que acabamos de crear.

 

Te puedes descargar mi código directamente del repositorio:

Ledzedev Eureka Server     ->     github / formato zip

Ledzedev Microservicio Consulta de Productos     ->     github / formato zip

 

Artículos Relacionados

- Spring Boot Microservicio Proxy

- Spring Boot Microservicio Gateway

 

 

 

Add a comment