Visión general
Contenido
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.
Te puede interesar:Spring Cloud: enrutamiento con Zuul y GatewayEl 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 /:
Te puede interesar:Spring Cloud: TurbinaFinalizar 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.
Te puede interesar:Patrones de diseño en JavaComo siempre, el código de los ejemplos utilizados en este artículo se puede encontrar en Github.