Get it on Google Play
Tu partner Freelance para tus proyectos IT

Microservicios con Spring Framework | Service Discovery y Comunicación

20-08-2020
Spring Framework  + Hashicorp Consul + Apache Kafka

Spring Framework + Hashicorp Consul + Apache Kafka

En el vídeo de hoy hemos implementado, usando Spring Framework y Java, varios de los conceptos y patrones que hemos visto hasta ahora en la serie de vídeos de microservicios. También hemos visto os fácil que es integrarse con aplicaciones como Hashicorp Consul y Apache Kafka con este Framework.

Después de crear un nuevo proyecto Maven en Eclipse hemos hecho lo siguiente:

Implementación de aplicación Spring Boot

Hemos creado nuestra aplicación con tres ficheros muy básicos:

El primer fichero ha sido el de configuración Maven(Es la herramienta para soporte a dependencias y compilación, etc.). El fichero se crea en la raíz del proyecto y se llama ‘pom.xml’:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.lostsys.youtube</groupId>
  <artifactId>Web1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.0.RELEASE</version>
	</parent>
  
    <dependencies>
    	<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>
    </dependencies>
    
	<build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
    </build> 
</project>

También hemos creado un fichero de configuración llamado ‘application.properties’ en la carpeta ‘src/main/resources’. En este caso solo le hemos configurado dos cosas, el nombre de la aplicación(o microservicio) y el puerto(En este caso 0 para que arranque en un puerto aleatorio cada vez):

spring.application.name=Spring1
server.port=0

Y finalmente hemos creado la classe principal, y única, de nuestra aplicación:

package com.lostsys.spring;

import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Controller;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@SpringBootApplication
@Controller
public class Hello1 {
	
	@RequestMapping("/")
	@ResponseBody
	public String home( HttpServletRequest request ) {
		StringBuilder sb=new StringBuilder();
		
		sb.append( "<h1>Hello World</h1>" );
		
		return sb.toString();
		}
	
}

Finalmente para arrancar, hemos ejecutado esto en el terminal:

mvn spring-boot:run

Integrar Spring con Hashicorp Consul

La integración de Hashicorp Consul con Spring Framework ha sido tan sencilla como empezar añadiendo las siguientes dependencias en el fichero pom de maven:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
        	<artifactId>spring-cloud-starter-consul-discovery</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

También hemos añadido la siguiente configuración al fichero ‘application.properties’ para configurar la conexión al Consul:

spring.cloud.consul.host=127.0.0.1
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.health-check-path=/
spring.cloud.consul.discovery.instance-id=Spring1-${random.uuid}

Y finalmente, gracias a la magia de Spring Framework se nos ha inyectado los objetos ‘discoveryClient’ y ‘loadBalancer’ para gestionar la conectividad de los microservicios como hemos explicado:

	@Autowired
    	private DiscoveryClient discoveryClient;
	
	@Autowired
	private LoadBalancerClient loadBalancer;
	
	@RequestMapping("/")
	@ResponseBody
	public String home( HttpServletRequest request ) {
		StringBuilder sb=new StringBuilder();
		
		sb.append( "<h1>Hello World</h1>" );
		
		/* Service Discovery */
		if (loadBalancer.choose("Spring1")!=null) sb.append( "<p>load balancer: "+loadBalancer.choose("Spring1").getInstanceId()+"</p>" );
		if (discoveryClient.getInstances("Spring1")!=null) sb.append( "<p>instances: "+discoveryClient.getInstances("Spring1").size()+"</p>" );
			
		return sb.toString();
		}

Integración de Spring Framework con Apache Kafka

La integración de Apache Kafka con Spring Framework ha sido tan sencilla(Igual que con Consul) como empezar añadiendo las siguientes dependencias en el fichero pom de maven:

       <dependency>
            <groupId>org.springframework.kafka</groupId>
        	<artifactId>spring-kafka</artifactId>
        </dependency>

También hemos añadido la siguiente configuración al fichero ‘application.properties’ para configurar la conexión al Kafka:

spring.kafka.bootstrap-servers=127.0.0.1:9092

Y finalmente, gracias a la magia de Spring Framework se nos ha inyectado el objeto ‘kafkaTemplate’ para enviar mensajes a los topics de Kafka. Además, hemos creado una función para recibir los mensajes que llegan a una lista/topic de Kafka:

	@Autowired
	private KafkaTemplate<String, String> kafkaTemplate;	
	
	private static ArrayList<String> kafkamsgs=new ArrayList<String>();
	
	@RequestMapping("/")
	@ResponseBody
	public String home( HttpServletRequest request ) {
		StringBuilder sb=new StringBuilder();
		
		sb.append( "<h1>Hello World</h1>" );
		
		/* Service Discovery */
		if (loadBalancer.choose("Spring1")!=null) sb.append( "<p>load balancer: "+loadBalancer.choose("Spring1").getInstanceId()+"</p>" );
		if (discoveryClient.getInstances("Spring1")!=null) sb.append( "<p>instances: "+discoveryClient.getInstances("Spring1").size()+"</p>" );
		
		/* Events */
		if ( request.getParameter("kafkamsg")!=null ) {
			ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send("test",  request.getParameter("kafkamsg"));
	    	
			future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
				public void onSuccess(SendResult<String, String> result) { System.out.println( result ); }
				public void onFailure(Throwable ex) { ex.printStackTrace(); }
				});   
			}
		sb.append( "<p>msgs: "+kafkamsgs+"</p>" );
		sb.append( "<p><form method='post' action='/'><input name='kafkamsg' /><input type='submit' value='Enviar'/></form></p>" );
		
		return sb.toString();
		}

	@KafkaListener(topics = "test", groupId = "grupo1")
	public void listenTopic2(String message) {
		kafkamsgs.add( message );
		} 

Y esto es todo amigos, espero que os haya gustado y os espero en futuros artículos y vídeos.

Si te ha servido, por favor comparte
 

Leave a Reply