Microservicios y gRPC en .NET

El poder de gRPC para servicios y microservicios.


Es probable que hayas escuchado que gRPC es un framework RPC y tipo de arquitectura de alta performance para comunicación entre servicios, creado por Google, que es Open Source y que hará que tu aplicación se ejecute como una bala.

gRPC ahora gobernado por la Cloud Native Computing Foundation es una implementación del modelo RPC (remote procedure call) o en español llamado a procedimientos remotos como si fueran funciones “locales” para el consumidor, lo cual trae capacidades muy interesantes al momento de implementar integraciones entre servicios.

Para los que somos de la vieja escuela, escuchar el término RPC nos recuerda a implementaciones como Java RMI ó implementaciones de comunicación de Microsoft como OLE, COM, DCOM y COM+ e incluso WCF con flujos de comunicación binaria y stream. La diferencia es que gRPC se presenta como una implementación de RPC agnóstica del lenguaje y plataforma, asegurando de esta manera la interoperabilidad con diferentes ecosistemas y tecnologías.

Si estas interesado en implementar gRPC en tus soluciones, pero sientes que no tienes un camino claro, en este post trato de tocar puntos que pueden servirte como guía en tu aventura.

  • A diferencia del patrón de arquitectura REST que esta basado en JSON, gRPC se basa en Protocol Buffers, en el formato Protobuf y en serialización binaria por defecto (aunque las últimas versiones soportan también otros tipos de serialización, incluso JSON) lo cual lo hace mucho más rápido para la transmisión de mensajes.
  • Se basa en un enfoque de conexión persistente y multiplexada basada en HTTP/2, lo cual permite flujos de comunicacion tipo stream bidireccional con multiples request por conexión. A diferencia de REST donde se tienen que usar los clásicos HTTP client con un request por conexión sin flujos bidireccionales. Esta diferencia de gRPC le permite lograr latencias muy bajas en comparación de REST.
  • REST maneja muchas convenciones para definir rutas, parametros dinámicos de consulta, metodos de acceso a recursos, y códigos de estado HTTP. gRPC en cambio al compilar produce rutas estáticas lo que lo hace mucho más eficiente, ya que no tiene que interpretar rutas y parámetros en rutas, ni metodos de acceso.
¿Cuáles son los desafios para poder implementar gRPC?
  • Existe una curva de aprendizaje para poder implementar gRPC, se debe aprender la sintaxis declarativa del formato Protobuf, manejo de errores, dependiendo del lenguaje que se use, se debe aprender del manejo de las bibliotecas oficiales para poder implementar gRPC. Dependiendo de la funcionalidad que se este implementando se debe aprender sobre manejo flujos de stream unidireccional/bidireccional.
  • Se debe usar plataformas que soporten los protocolos que exige gRPC, el uso de plataformas legacy como servidores de aplicaciones en versiones antiguas, no sera compatibles con los protocolos de base de gRPC, por lo tanto es recomendable usar plataformas modernas y servicios de nube como Azure Kubernetes Service, App Service, Azure Container Apps, entre otros.
  • El testing y la observabilidad se dificultan un poco. Para el testing no es lo mismo que probar una API Rest con Postman ó herramientas parecidas, existen alternativas como BloomRPC, grpcurl e incluso herramientas como Postman estan evolucionando para soportar gRPC, pero al ser muy diferente de API REST, esto representa un giro de 180 grados para los equipos de QA. Para el monitoreo se deben implementar interceptores y OpenTelemetry para poder interpretar las trazas que llegan a los servicios ya que al ser un formato binario es muy complicado interpretar las trazas en su estado “natural”.
  • Cambio de mindset, en un desarrollo basado en REST, la definición suele caer en roles de arquitectura por todas las convenciones que se tienen que respetar, por otro lado gRPC hace que la definición se paresca más a codificar por ende puede delegarse y enfocarse en la naturaleza del problema y el flujo de los datos.
¿Qué consideraciones se deben tener para la implementación en un escenario real?
  • gRPC es muy atractivo para consumo de servicios backend to backend, ya que al encontrarse en un contexto interno se facilita la implemenatción el cumplimiento de todas las condiciones que exige gRPC. No es imposible implementarlo para la Web (incluso existe el proyecto gRPC-web), pero la gestión de los contratos protobuf se dificulta enormemente y aún los navegadores estan en proceso de adopción. Si se quiere implementar para la web un camino más asequible, sería implementar llamadas a servicios desde una capa de BFF o backend para el frontend, asi es como lo implementan gigantes como Linkedin y Netflix. Es atractivo para invocaciones desde dispositivos móviles pero se debe tener estrategias para el manejo de versiones ante cambios.
  • El balanceo de carga de gRPC no es de capa 4 sino de capa 7, por ende los servicios se deben implementar en infraestructura compatible con el balanceo de capa 7. Si se usa kubernetes ya sea local en una nube como Azure, se puede implementar ingress Nginx para conectarse entres microservicios. Sino se usa kubernetes se puede optar por servicios como App Service para desplegar el servicio gRPC. Para el caso de OnPremise se puede implementar proxy inverso con Nginx. Otra alternativa es implemetar estrategias de balanceo desde el cliente.
  • gRPc exige un camino seguro, reforzado con SSL/TLS y relaciones de confianza entre servidores, resulta útil implementar mTLS para conexión entre servidores.
  • Versionado. Cualquier cambio en las definiciones del protobuf, ya sea campos, tipos o edición/eliminación de metodos van requerir la actualización de los consumidores, ante este escenario resulta importante implementar versionado de servicios, para ello se puede utilizar el especificador de paquete para implementar una nueva versión y garantizar retrocompatibilidad, así los consumidores puedan migrar progresivamente.

Con todo lo descrito, una arquitectura como la siguiente puede servirte de base si deseas implementar gRPC.

Diagrama de arquitectura gRPC en AKS

Si aún tienes dudas de las ganacias de performance que puede traerte gRPC, te dejo un ejemplo de comparación entre servicios REST y gRPC con .NET, la implementación es muy parecida a la arquitectura en referencia, pero sin ir a un sistema de log. Se puede apreciar como los servicios basados en gRPC mejoran en performance casi en la mitad.

VS de performance gRPC vs Servicios REST (Minimal API y Controllers) en .NET


Conclusiones
  1. El estandar de desarrollo para APIs aún se encuentra centrado en REST, pero tecnologías como gRPC representan un punto de ruptura para desafiar las integraciones backend to backend en la busqueda de mejoras de performance.
  2. Si te encuentras en el reto de implementar gRPC debes tener en cuentas muchas aristas, desde para que tipo de aplicación lo usaras, que tan moderno es tu stack, plataformas e infraestructura, asi como preparar a los equipos para la evolución de los servicios y/o microservicios.

Sígueme en Linkedin para estar al tanto de mis publicaciones y novedades

Referencias