Spring Cloud: descubrimiento de servicios con Eureka

S

Visión general

En este artículo, nos presentaremos al descubrimiento de servicios del lado del cliente y al equilibrio de carga a través de Spring Cloud Netflix Eureka.

En una arquitectura de microservicio típica, tenemos muchas aplicaciones pequeñas implementadas por separado y, a menudo, necesitan comunicarse entre sí. Específicamente, cuando decimos servicio al cliente, nos referimos a un servicio que necesita realizar llamadas REST a algún otro servicio final.

El problema en este tipo de arquitectura es cómo el servicio al cliente encuentra todos sus servicios finales. Podríamos codificar el nombre de host / puerto en algún archivo de propiedad, pero esto no siempre es práctico o factible en un entorno de nube. Podría haber cualquier cantidad de microservicios, y es tiempo y requiere mucho tiempo codificarlos cuando hay una cantidad incierta de ellos y cuando sus ubicaciones pueden cambiar.

Para aumentar aún más la complejidad, los servicios podrían tener varias instancias de sí mismos (según la carga). Qué instancia realmente servirá para la respuesta podría ser un desafío, ya que queremos tener una distribución de carga equitativa.

Netflix Eureka

Netflix Eureka es un servidor de búsqueda (también llamado registro). Todos los microservicios del clúster se registran en este servidor.

Al realizar una llamada REST a otro servicio, en lugar de proporcionar un nombre de host y un puerto, solo proporcionan el nombre del servicio.

El enrutamiento real se realiza en tiempo de ejecución junto con la distribución equitativa de la carga entre los servicios finales. Hay otros clientes de descubrimiento de servicios como Cónsul, Zookeeper etc, pero usaremos Eureka en este artículo.

Para comprender este concepto, crearemos tres servicios en nuestro ejemplo:

  • Servidor Eureka: actúa como un registro de servicios.
  • Servicio de cine: un servicio REST simple que proporciona información sobre películas.
  • Servicio de recomendación: un servicio REST simple pero que llama internamente al Movie Service para completar sus solicitudes.

Configuración del servidor Eureka

La mejor manera de comenzar con un proyecto esqueleto es usar Spring Initializr. Seleccione su versión preferida de Spring Boot y agregue la dependencia “Eureka Server” y genere como un proyecto Maven:

Para crear un servidor Eureka, todo lo que necesitamos hacer es agregar el @EnableEurekaServer anotación a nuestra clase principal:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

Ejecutaremos el servidor en el puerto 8761, que es el puerto recomendado por el equipo de Spring. Entonces en application.properties agregaremos:

server.port = 8761

Para probar este punto final, navegue en su navegador hasta http: // localhost: 8761 /:

Finalizar la configuración del servicio (servicio de películas)

Nuevamente, estamos usando Spring Initializr para crear nuestro proyecto. Seleccione su versión preferida de Spring Boot y agregue las dependencias “Web” y “Eureka Discovery” y genere como un proyecto Maven:

Para convertirlo en un cliente, todo lo que tenemos que hacer es agregar el @EnableEurekaClient anotación a nivel de clase:

@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Como alternativa, podríamos utilizar el @EnableDiscoveryClient anotación, que proviene de spring-cloud-commons. Elige la implementación (Consul, Zookeeper, Eureka) de acuerdo con la ruta de clase. En nuestro caso, automáticamente elegiría Eureka.

Con eso fuera del camino, podemos definir nuestro Movie modelo:

public class Movie {
    private Integer id;

    private String name;

    private String synopsis;

    // getters and setters
}

Y finalmente, podemos definir un controlador:

@RestController
public class MovieController {

    private static List<Movie> movieList = new ArrayList<>();
    static {
        movieList.add(new Movie(1, "movie-1", "summary-1"));
        movieList.add(new Movie(2, "movie-2", "summary-2"));
        movieList.add(new Movie(3, "movie-3", "summary-3"));
    }

    @GetMapping("/movies")
    public ResponseEntity<?> getMovies() {
        return ResponseEntity.ok(movieList);
    }
}

Arriba, creamos un punto final simple que devuelve una lista de Movie objetos, simulando una llamada a una base de datos.

Tenemos el Eureka Discovery jar de cliente en este proyecto. Al ver esto en la ruta de clases, Spring intentará encontrar un servidor Spring Eureka en ejecución. Necesitamos especificar esto en el application.properties:

server.port = 8060
spring.application.name = movie-service
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/

Además de especificar la URL del servidor, también necesitamos especificar el nombre de la aplicación. Será este nombre el que utilizarán otros servicios para realizar llamadas REST.

Con eso, hemos registrado nuestro servicio en el servidor, y cualquier otro servicio registrado puede llamarlo usando spring.application.name.

Actualicemos el punto final del servidor Eureka:

Junto con el registro con el servidor Eureka, el jar del cliente Eureka también envía latidos periódicos al servidor Eureka para informarle que todavía está disponible.

Configuración del servicio de cliente (servicio de recomendación)

Ahora construyamos nuestro servicio al cliente que llamará movie-service. Una vez más, creemos un nuevo proyecto con Spring Initializr con las mismas dependencias que antes:

En su application.properties nuevamente tenemos que especificar el nombre de la aplicación y los detalles de Eureka:

server.port = 8050
spring.application.name = recommendation-service
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/

Luego anotamos la clase principal con @EnableEurekaClient:

@SpringBootApplication
@EnableEurekaClient
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

También necesitamos crear un RestTemplate frijol y marcarlo como @LoadBalanced. Esto le dice a Spring que queremos aprovechar el equilibrio de carga del lado del cliente, que en este caso lo hace Cinta.

El equilibrio de carga del lado del cliente decide a qué instancia (en caso de que se ejecuten varios servicios finales en el clúster al que el cliente puede llamar) llamar.

Ribbon fue desarrollado por Netflix y luego de código abierto. Su dependencia viene automáticamente con la dependencia de Eureka Discovery. Se integra automáticamente con Spring y distribuye cargas según el estado del servidor, el rendimiento, la región, etc.

No se nos pedirá que usemos Ribbon directamente, ya que se integra automáticamente RestTemplate, Zuul, Fingir, etc. Usando @LoadBalanced nosotros hicimos RestTemplate cinta consciente.

Vamos a escribir RecommendationController clase que llama internamente a nuestro servicio de películas:

@RestController
public class RecommendationController {
    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/recommendations", method = RequestMethod.GET)
    @ResponseBody
    public Movie[] recommendations() {
        Movie[] result = restTemplate.getForObject("http://movie-service/movies", Movie[].class);
        return result;
    }
}

Arriba, nosotros @Autowired la cinta habilitada RestTemplate y utilícelo para llamar al movie-service. Tenga en cuenta que no tenemos que especificar el nombre de host o el puerto en ninguna parte.

Lo que Spring hace internamente aquí es porque está registrado con el servidor Eureka, almacena la lista de todos los servicios y sus instancias en ejecución localmente. Cuando hicimos una llamada de REST al movie-service de esta manera (en lugar de proporcionar un nombre de host y un puerto), sustituye las URL de los extremos reales de la lista almacenada previamente y luego realiza la llamada REST.

Por supuesto, la lista de servicio almacenada junto con sus instancias en ejecución se actualiza periódicamente. La mejor parte de todo esto es que no tenemos que encargarnos de esto en absoluto y todas estas cosas son manejadas por Spring internamente.

Probemos el punto final de recomendación, navegue en su navegador (o usemos curl, cartero, etc.) para http: // localhost: 8050 / recomendaciones, verá una respuesta similar a:

Conclusión

En este artículo, hemos cubierto cómo usar Spring Cloud Eureka para el descubrimiento de servicios en el entorno de microservicios / nube. Creamos dos servicios REST simples que se comunican entre sí sin codificar ningún nombre de host / puerto mientras se realizan llamadas REST.

Como siempre, el código de los ejemplos utilizados en este artículo se puede encontrar en Github.

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad