Los que no lo hayan visto la primera entrada deberán inexcusablemente hacerlo, ya que para que lo que aquí compartimos funcione necesita de EUREKA, y es en dicha primera entrada donde se explica.
En la tercera desplegaremos todos los elementos en un entorno docker.
En la cuarta lo haremos sobre un entorno kubernetes.
El código de ambos micorservicios lo tenéis en microservicio1 y microservicio2.
Primer microservicio
Mostramos los detalles del primer microservicio, el que hará de "servidor" y recibirá peticiones del segundo.
pom.xml
Sólo mostramos la dependencia que nos permite registrarlo en EUREKA
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.yml
Este es su contenido:
spring:
application:
name: client-one-load-balancing
profiles:
active: des
eureka:
client:
enabled: true
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 1
Lo importante para esta entrada es la configuración de acceso a eureka.
Habilitamos la conexión, indicando la url del server.
Por defecto, cuando un microservicio se registra en eureka, cada 30 segundos lanza un ping para indicar que está activo. Eureka no se da por enterado del nuevo microservicio hasta tres pings, por tanto 90 segundos.
Con "leaseRenewalIntervalInSeconds: 1" indicamos que nos basta con uno para darlo por activo.
Igualmente, hasta que no pasan 3 intervalos de 30 segundos sin recibir ping del cliente, eureka no lo hace desaparecer del registro.
Con "leaseExpirationDurationInSeconds: 1" indicamos que con un intervalo basta para "des-registrarlo".
java
En la clase main, añadimos la anotación "@EnableEurekaClient" a la cabecera, juntamente con la habitual "@SpringBootApplication".
Para dar servicio hemos declarado un endpoint "/saludo" y otro para la raíz "/", dentro de la clase MainController (anotade la clase con "@RestController")
@Value("${server.port}")
String puerto;
@RequestMapping(value = "/saludo")
public String greet() {
log.info("Acceso /saludo");
List<String> greetings = Arrays.asList("Hola", "Saludos", "Saludos cordiales");
Random rand = new Random();
int randomNum = rand.nextInt(greetings.size());
String retorno = greetings.get(randomNum);
return retorno + ", desde puerto " + puerto;
}
@RequestMapping(value = "/")
public String home() {
log.info("Acceso /");
return "Hola!";
}
Arranque
Arrancaremos tres réplicas del mismo microservicio. Para hacerlo de la misma forma con los tres arranques los lanzaremos desde línea de comandos.
Abrimos cmd de windows y nos vamos al directorio raíz del proyecto, donde está ubicado el pom.xml. Nos aseguramos que el JAVA_HOME apunta al jdk 8 (echo %JAVA_HOME%). Si no es así deberemos setear dicha variable en cada una de las consolas (set JAVA_HOME=C:\XXXXXXXX). Por ejemplo en mi caso he de hacer
set JAVA_HOME=C:\Java\java8_131
Una vez hecho esto lanzamos los siguientes comandos, uno por cada consola
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8090
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8091
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8092
Ya tenemos nuestro primer microservicio levantado y respondiendo a los puertos 8090, 8091 y 8092.
Podemos validarlo a partir de la url
http://localhost:8090/saludo
http://localhost:8091/saludo
http://localhost:8092/saludo
Veremos que en cada una pone un literal al azar de cualquiera de estos
"Hola", "Saludos", "Saludos cordiales"
añadiendo el puerto activo.
Vemos en el dashboard de eureka nuestros tres microservicios
Los tres registados bajo el nombre "client-one-load-balancing". Este nombre es importante!!!!
Vamos con el segundo microservicio
Segundo microservicio
Estos son los detalles del segundo microservicio, el que hace de cliente.
pom.xml
Necesitamos las siguientes dependencias
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
La específica en este caso es la dependencia de ribbon. La de eureka cliente es como en el primer microservicio.
application.yml
Esta es nuestra configuración usando Ribbon con nombres de servicio suminstrados por Eureka:
server:
port: 9999
spring:
application:
name: client-two-load-balancing
profiles:
active: des
client-one-load-balancing:
ribbon:
#eureka:
#enabled: false
listOfServers: client-one-load-balancing:8090,client-one-load-balancing:8091,client-one-load-balancing:8092
#listOfServers: localhost:8090,localhost:8091,localhost:8092
#listOfServers: localhost:8090,localhost:8091,localhost:8092
ServerListRefreshInterval: 15000
eureka:
client:
enabled: true
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 1
Remarcamos en negrita lo específico de este segundo microservicio.
Vemos el nombre "client-one-load-balancing", que es el nombre de registro del microservicio uno. Vemos también la lista de servers "listOfServers" con los tres servicios levantados, cada uno con su puerto, y de nuevo, en lugar de dominio o ip, vemos el nombre de registro en eureka.
El atributo "ServerListRefreshInterval: 15000" indica, en milisegundos, el intervalo entre ping y ping lanzado desde el microservicio dos a los microservicios "unos".
NOTA:
Si quisiésemos trabajar sin EUREKA deberíamos quitar los comentarios de
eureka:
enabled: false
listOfServers: localhost:8090,localhost:8091,localhost:8092
listOfServers: localhost:8090,localhost:8091,localhost:8092
y comentar:
#listOfServers: client-one-load-balancing:8090,client-one-load-balancing:8091,client-one-load-balancing:8092
ya que en ese caso no habría ningún servidor de registro que habilite el descubrimiento de nombres.
Deberíamos también eliminar la configuración de EUREKA y la anotación "@EnableEurekaClient" del Application.java de ambos microservicios.
Asimismo deberíamos eliminar la dependencia siguiente de ambos microservicios.
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
java
En la parte java, usaremos la anotación "@EnableEurekaClient" de la misma forma que en el microservicio uno.
Añadimos una clase de configuración que nos exige ribbon para realizar el blanceo y los "pings". Podéis verla tras la descarga del código del gitlab.
El MainController tiene ciertas particularidades. Pego la clase completa
@RestController
@RibbonClient(name = "client-one-load-balancing", configuration = Configuration.class)
public class MainController {
private static Logger log = LoggerFactory.getLogger(MainController.class);
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
RestTemplate restTemplate;
@RequestMapping("/hola")
public String hi(@RequestParam(value = "nombre", defaultValue = "Rigoberto") String nombre) {
log.info("parametro recibido: " + nombre);
String saludo = this.restTemplate.getForObject("http://client-one-load-balancing/saludo", String.class);
return String.format("%s, %s!", saludo, nombre);
}
}
En negrita lo más importante. Se añade la anotación "@RibbonClient" apuntando al nombre del registro eureka del microservicio uno, indicando la clase de configuración comentada más arriba.
Se añade la antación "@LoadBalanced" al bean restTemplate para que haga balanceo a los microservicios declarados en la "listOfServers" del application.yml
Por último, se invoca al microservicio uno vía restTemplate, añadiendo a lo que devuelve aquel, el nombre recibido por parámteros.
Prueba
Arrancamos este segundo microservicio desde eclipse.
Lanzamos repetidamente la url "http://localhost:9999/hola?nombre=Antonio" (podéis cambiar el "nombre" a vuestro gusto. Obtendremos diferentes resultados. Por ejemplo
Como se puede observar, estamos invocando al microservicio uno, el cual mediante ribbon balancea las peticiones llamando a cualquiera de los microservicios uno. En las capturas se ve graficamente por el puerto de respuesta.
A nivel de logs veremos las diferentes peticiones como van llegando a cualquier consola
Acceso /saludo
Cada 15 segundos se verá en cada una de las consolas un log del ping, que se realiza a la raíz, dejando esta traza
Acceso /
Ahora podemos jugar.... paremos con "CTRL + C" cualquiera de los microservicios uno. Si lanzamos peticiones antes de los 15 segundos de intervalo entre ping's, es posible que alguna petición se dirija al mcroservicio parado dando un error de acceso. Si esperamos dichos 15 segundos veremos que ninguna petición llega al microservicio parado.
Paremos un segundo y hagamos lo mismo, ahora todas las peticiones se encamian al único microservicio uno activo.
Ahora hagamos al revés, id levantando uno a uno los microservicios uno parados, y pasado 15 segundos veremos que vuelve a estar activos, pudiendo recibir peticiones de forma correcta.
Y todo desde cliente.
Más info
Las páginas de Spring son un buen inicio.
Nuestro código
Entrada 2: https://gitlab.com/gincol-blog/client-one-load-balancing.git
https://gitlab.com/gincol-blog/client-two-load-balancing.git
https://gitlab.com/gincol-blog/client-two-load-balancing.git
No hay comentarios:
Publicar un comentario