Patrones de comunicación: Síncrono

Introducción

La comunicación entre microservicios prácticamente es la conexión con sistemas internos o externos tanto de forma síncrona o asíncrona, detallamos estos patrones de forma sencilla, resumida y con ejemplos.

Los patrones en los que en la mayoría se trabajará son patrones probados, definidos y usados en practica hoy en día, nos basaremos en el libro de Design Pattern for Cloud Native Application.

Patrones de mensajería síncrona

Patrón Request-Response

Concepto

Es un de los patrones utilizados comúnmente se tiene una fuente externa (un componente, sistema o un cliente) que realiza una solicitud hacía el microservicio, por ende genera un bloqueo hasta recibir la respuesta, manteniendo un canal de comunicación hasta que la fuente externa reciba la respuesta deseada.

Normalmente en este patrón el microservicio que envía la respuesta esta acoplado con otros microservicios, a medida que aumenta la cantidad de microservicios genera un cuello de botella y la generación de mayores canales de comunicación, aumentando considerablemente el tiempo de espera.

Existe un patrón relacionado de orquestación y delimitación de salida de servicios, llamado API Gateway.

Implementación

Para esta implementación seremos la fuente externa que deberá conectarse a un servicio que responda sobre una aproximación de donde estamos ubicados en base a la IP.

Este primer bloque define la implementación de consumo de un servicio externo.

@Path("")
@RegisterRestClient(configKey = "ipinfo")
public interface InformationService {
    @GET
    IpInformation getIP();
}

Ejecutando el código con la ruta localhost:8080/ip obtendremos la info de nuestra conexión IP.

Consideraciones para el uso de este patrón

  • Genera un mayor acoplamiento entre microservicios

  • Los servicios esperarán la respuesta del servicio invocado

  • Se puede utilizar para cantidades pequeñas de microservicios (menor a 10)

  • Utilizar cuando no tiene dependencias para traer la información a tiempo real

Patrón RPC

En realidad RPC (Remote Procedure Call), recordé de CORBA en su momento, no es un patrón correspondiente pero este tipo de comunicación gano popularidad hace un tiempo atrás y volvió a ganar la popularidad nuevamente cuando google hizo una implementación llamándola gRPC.

Entonces gRPC se usa por medio de HTTP2 y puede comunicarse sin ningún problema o limitación técnica.

Diferencias entre RPC y gRPC

Existen diferencias entre RPC y gRPC, la siguiente tabla muestra lo que considero más relevante para diferenciarlos.

RPCgRPC
se puede comunicar por: UDP/TCP/HTTPHTTP/2
El formato para serializarlo puede ser cualquiera, normalmente XML o JSONEl formato de conversión es un proto

Implementación

Implementamos un sayHello correspondiente, es decir el gRPC implementado como publicador

@GrpcService
public class HelloGrpcService implements HelloGrpc {
   @Override
   public Uni<HelloReply> sayHello(HelloRequest request) {
      return Uni.createFrom().item("Hello " + request.getName() + "!")
            .map(msg -> HelloReply.newBuilder().setMessage(msg).build());
   }
}

Un archivo importante para ello es el .proto con las instrucciones de donde debe de crearse la carpeta, que método y clases creará, en nuestro caso utilizamos el siguiente:

syntax = "proto3";

option java_multiple_files = true;
option java_package = "clp.coder";
option java_outer_classname = "HelloGrpcProto";

package hello;

service HelloGrpc {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Ejecutamos el código con el comando mvn quarkus:dev y veremos que mediante un puerto se establecerá la comunicación gRPC.

Utilizando un postman podemos hacer la consulta correspondiente enviando un nombre:

Igualmente en nuestras pruebas unitarias obtenemos resultados correspondientes haciendo invocación gRPC, el punto 1 muestra el despliegue correcto del servicio gRPC desplegado en el puerto asignado(9990), y el puerto de default 8081 para las pruebas en Quarkus

Consideraciones para el uso de este patrón

  • Comunicación entre microservicios, siempre y cuando alguna restricción tecnológica le impida hacer una implementación SOAP, RESTful, JSON u otro.

  • No es una buena opción si esta pensando en exponer a consumidores externos

  • Puede ser utilizado como un Service as Abstraction si es que tiene implementaciones nativas RPC

Recursos

  1. Repositorio: https://github.com/ChristianLoza/cloud-pattern.design

  2. Las imagenes expuestas son autoría mía con excepción de la portada del libro de patrones de diseño nativas en la nube.

Conclusiones

  1. Ningún patrón es mejor que otro, debe considerar el volumen de microservicios si es que quiere utilizar patrones síncronos.

  2. Se debe de considerar las limitaciones que ofrece una comunicación directa entre microservicios en base a cantidad.

Did you find this article valuable?

Support Christian Loza Peralta by becoming a sponsor. Any amount is appreciated!