# Arquitectura Backend Plataforma de Pagos
<!--
Version del documento
-->
## Control de Versiones
| Versión | Fecha | Autor | Revisor | Descripción del Cambio |
|--|--|--|--|--|
|1.0|20210409|Sergio Ñ / Luis A|Jed Horne|Emisión|
## 1 Introduccion
<!--
párrafo corto que explica qué estas proponiendo
-->
El presente documento es una exploración de tecnologías que se van a usar en la plataforma de pagos. El objetivo es poder definir:
* Lenguaje a utilizar
* Protocolo de comunicación
* Framework, librería o tecnología de microservicios
* Orquestación de los microservicios
## 2 Motivación
<!--
¿qué motiva esta decisión y por qué es importante?
¿Por que construirlo?
el propósito de esta sección es articular de una manera sencilla el valor de la decision que vamos a tomar
-->
* Es uno de los primeros trabajos con microservicios en Mi Águila, y una buena selección de tecnologías nos permite no dar pasos en falsos, y tener que más adelante volver a construir nuevas plataformas
* En el equipo hay muchas ideas de cómo realizar este piloto de microservicios, pero no hay documento que permita analizar pros y contras, de tal manera, que se logre tomar una decisión objetiva.
## 2.1 Lluvia de Ideas
1. Para selección del lenguaje
* Python, Javascript: son lenguajes que la mayoría del equipo conoce
* Go: es un lenguaje con buen performance muy orientado a microservicios
* Validar un lenguaje más orientado a objetos
2. Protocolo de comunicación
Para los microservicios se pueden utilizar los siguientes protocolos de comunicación:
- API
- RPC: grpc, thrift
- Queues
4. Orquestación
- Kubernetes
5. Revisar la "Arquitectura de microservisios orientada al dominio" DOMA para la organización del código.
## 3 Propuesta de implementación
<!--
Este es el núcleo de tu propuesta, y su proposito es ayudarte a pensar en la solución. Esto debe ser un wireframe, no un documento perfecto con todos los detalles.
Escribir es pensar https://medium.learningbyshipping.com/writing-is-thinking-an-annotated-twitter-thread-2a75fe07fade
- usa diagramas para ilustrat tus ideas o flujos
- inluye ejemplos de código si estas proponiendo una interfaz o contrato de sistemsa nuevo
- agrega links con las especificaciones de proyectos
- Competidores e inspiración de productos
- Mockups
El proposito de esta sección se resume en:
"Esta es la dirección en la que nos voy a llevar, alguién ve huecos en mi propuesta o tiene comentarios sobre cómo mejorarla?
-->
### 3.1 Selección de Lenguaje
Para la selección del lenguaje vamos a colocar las alternativas y sus pro y contras para una selección mas clara y razonable.
#### 3.1.1 Golang:
<!--
* **Go kit** es un toolkit de programación para construir microservicios en Go. Fue creado para solucionar problemas comunes en sistemas distribuidos y aplicaciones y permitirle a los desarrolladores enfocarse en la parte comercial de la programación. Básicamente, es un grupo de paquetes relacionados que, en conjunto, crean un framework para construir grandes arquitecturas orientadas a servicios (SOA por sus siglas en inglés). Su principal capa de transporte es la llamada de procedimiento remoto (RPC por si siglas en inglés), pero también puede utilizar JSON por medio de HTTP y es fácil de integrar con los componentes infraestructurales más comunes, para reducir la fricción de despliegue y promover la interoperabilidad con sistemas existentes.
* **Gizmo** es una herramienta para Microservicios en Golang desarrollada y utilizada por The New York Times. Este kit proporciona paquetes para armar demonios de servidor y pubsub con las siguientes características:
* Configuración y registro estandarizados.
* Puntos finales de verificación de estado con estrategias configurables.
* Configuración para administrar puntos finales pprof y niveles de registro.
* Interfaces básicas para definir expectativas y vocabulario.
* Registro estructurado que contiene información de solicitud básica.
* Métricas útiles para endpoints.
* Cierres agraciados.
[Más detalle](https://github.com/nytimes/gizmo)
-->
Este lenguaje es uno de los más usandos en la arquitectura de microservicio donde el rendimiento es muy importante, ya que en comparación a otros es muy [rápido](https://www.toptal.com/back-end/server-side-io-performance-node-php-java-go) y sencillo de utilizar, tiene cada vez más auge y es implementado por empresas como Netflix, Amazon e Ebay.
**Pro:**
* Si el rendimiento es un aspecto crítico Go es el más recomendado dado a lo ligero y rápido.
* Una característica clave del lenguaje Go es que contiene su propio programador. En lugar de que cada subproceso de ejecución corresponda a un solo subproceso del sistema operativo, funciona con el concepto de "goroutines". Las gorutinas son funciones o métodos que se ejecutan en paralelo con otros métodos o procedimientos. Son livianos (el tamaño inicial es de 4 KB), en comparación con los subprocesos del sistema operativo que inicialmente son de 1 MB. Y el tiempo de ejecución de Go puede asignar una goroutine a un subproceso del sistema operativo y hacer que se ejecute, o suspenderlo y no asociarlo con un subproceso del sistema operativo, según lo que esté haciendo esa goroutine.
* Es un lenguaje Orientado a Objetos? la respuesta segun el [FAQ de Go](https://golang.org/doc/faq#Is_Go_an_object-oriented_language) es Si y No, A pesar de que Go tiene tipos, métodos y permite la programación orientada a objetos, no hay jerarquía de tipos. El concepto de “interfaz” en Go tiene una aproximación que creemos que es mucho más sencilla de usar y en algunos casos más general. También hay maneras de embeber tipos en otros tipos proporcionando la composición entre otros punto que podemos ver [acá](https://blog.friendsofgo.tech/posts/es_go_un_lenguaje_orientado_a_objetos/).
* Tiene una de las tasas más bajas de fallas y con diferencia mientas más alto sea el número de intentos de conexiones simultáneas mejor se comporta.
* Se pueden tener tiempos de scalling muy rápidos, haciendo que las imágenes de docker construidas sólo tengan el build de go, y no las dependencias. A su vez, ayuda en que en los contenedores no haya código fuente de la aplicación.
**Contra:**
* Es un lenguaje con un estilo propio y que en Mi Aguila pocos compañeros lo manejan.
* Las bibliotecas integradas de Go, aunque son mucho menos que en el caso de Python y Javascript, siguen cubriendo casi los mismos campos de uso.
* El Error Handling plantea dificultades para los desarrolladores de aplicaciones móviles. Es probable que [la próxima versión](https://github.com/golang/go/wiki/Go2) obtenga soporte adicional para el manejo de errores, valores de solo lectura y alguna forma de genéricos.
#### 3.1.2 Python:
Python es un lenguaje de alto nivel del que podemos aprovechar muchas de sus ventajas ya que es un lenguaje interpretado y de tipado dinámico.
**Pro:**
* Es el lenguaje más utilizado en Mi Águila y contamos con un nivel de expertice alto.
* Combina múltiples paradigmas de programación como el orientado a objetos y el funcional.
* Su sintaxis está orientada a escribir menos líneas de código pero más claras que otros lenguajes, lo que facilita enormemente su mantenimiento.
* La falta de procesos paralelos son útiles al escanear el código en busca de errores y errores.
* Excelente para aplicaciones grandes que requiere una estructura de proyecto probada y legible.
**Contra:**
* Con una sintaxis simple y solo un hilo ejecutándose a la vez, Python es relativamente lento en el procesamiento de datos.
#### 3.1.3 NodeJs:
Ideado como un entorno de ejecución de JavaScript orientado a eventos asíncronos, Node.js está diseñado para crear aplicaciones network escalables y puede atender muchas conexiones simultáneamente. Por cada conexión, se activa la devolución de llamada o callback, pero si no hay trabajo que hacer, Node.js se dormirá.
**Pros:**
* Casi ninguna función en Node.js realiza I/O directamente, por lo que el proceso nunca se bloquea. Por ello, es muy propicio desarrollar sistemas escalables en Node.js.
* Node.js es similar en diseño y está influenciado por sistemas como Event Machine de Ruby y Twisted de Python. Pero Node.js lleva el modelo de eventos un poco más allá. Incluye un bucle de eventos como runtime de ejecución en lugar de una biblioteca.
* Que Node.js esté diseñado para trabajar sin hilos no significa que no pueda aprovechar múltiples núcleos en su entorno.
* NodeJS se creó en 2009 y, en dos años, se lanzó la primera versión para compartir bibliotecas de código abierto. En la actualidad ofrece un amplio conjunto de bibliotecas que pueden simplificar el desarrollo de Node JS.
**Contra:**
* Como NodeJS es de un solo subproceso, a veces las tareas vinculadas a la CPU bloquean el ciclo de eventos y ralentizan su programa. Por lo tanto, resulta en una aplicación lenta y usuarios molestos.
* La función de ejecución de procesos paralelos de Node.js puede hacer que la búsqueda de errores y errores en el código sea un proceso tedioso.
### 3.2 Selección de protocolo de comunicación
Los siguientes son las opciones de protocolo de comunicación que tenemos en la mesa para seleccionar:
#### 3.2.1 Apache Thrift
Thrift es un proyecto que nació dentro de Facebook en la primera década del siglo. En 2007 Facebook decidió convertirlo en código abierto bajo la fundación Apache. Desde entonces se ha desarrollado de acuerdo con el modus operandi habitual en Apache: Open Source descentralizado, gestión basada en la meritocracia.
Es un stack completo de Remote Procedure Call con los ingredientes habituales del RPC:
* Lenguaje IDL (interface definition language) para definir interfaces de servicio y stubs de comunicación.
* Ofrece varios formatos para los mensajes, incluyendo los de tipo binario y comprimido.
* También tiene varios formatos de transporte (socket, por frames, ...). Son ad hoc, esto es, no corresponden a un protocolo de alto nivel como HTTP. Es dudoso que soporten transporte vía proxy.
* Los benchmark publicados le dan algo de ventaja sobre gRPC en cuanto a eficiencia.
* En cuanto a monitorización de carga, se puede usar Elastic Packetbeat, una herramienta de análisis de paquetes de red.
**Contras:**
* No ofrece ninguna solución para cachear respuestas idempotentes (Un servicio idempotente garantiza que cada solicitud se complete exactamente una vez, de manera que hacer múltiples solicitudes idénticas tiene el mismo efecto que hacer una solicitud única).
* Una desventaja es lo referente al balanceo de carga, no está documentado per se. Requiere que usemos herramientas externas para implementarlo.
* Es usual ver a usuarios del producto quejandose amargamente de la baja calidad de su documentación.
* Otra desventaja es la complejidad de utilizarlo en conjunto con kubernetes [[Link](https://engineering.saltside.se/our-failure-migrating-to-kubernetes-25c28e6dd604)].
Lenguajes soportados: C, Common Lisp, C++, C#, D, Delphi, Erlang, Go, Haxe, Haskell, Java, JavaScript, node.js, OCaml, Perl, PHP, Python, Ruby y SmallTalk.
#### 3.2.2 gRPC
Al igual que Apache Thrift, se compone de un IDL y un formato binario de mensajes serializados. Los [protocol buffers](https://github.com/protocolbuffers/protobuf) son los mensajes que el IDL gestionará para realizar las invocaciones remotas. Además hace uso del protocolo HTTP/2 para el transporte, con las ventajas que nos da el basarse en un estándar global que muchos servidores de aplicaciones ya soportan nativamente.
Los mensajes se transportan en el formato ad hoc protocol buffer, en binario y comprimidos, de modo que el tamaño es muy pequeño. El transporte de los mensajes se hace mediante el protocolo estándar HTTP/2.
Requiere el uso de **Linkerd** como balanceador de HTTP/2 si se usa con Kubernetes [[Link](https://kubernetes.io/blog/2018/11/07/grpc-load-balancing-on-kubernetes-without-tears/)].
Para la definción de servicios y mensajes utiliza archivos proto que tienen una sintaxis muy sencilla y son faciles de crear.
Se encuentra mucha documentación y la comunidad se ve bastante grande [[link](https://github.com/grpc-ecosystem/awesome-grpc#tools-test)].
Lenguajes soportados: El compilador es un ejecutable en C++. El runtime que se genera soporta una selección de los lenguajes más populares: Java (6+, Android API 14+), Python, Objective-C, C++, Go, Ruby,JavaScript, PHP, Dart y C#.
##### 3.2.2.1 Protocol Buffers
Los búferes de protocolo son el mecanismo extensible, neutral en cuanto al lenguaje y la plataforma, de Google para serializar datos estructurados; piense en XML, pero más pequeño, más rápido y más simple. Usted define cómo desea que se estructuren sus datos una vez, luego puede usar un código fuente generado especial para escribir y leer fácilmente sus datos estructurados hacia y desde una variedad de flujos de datos y usando una variedad de idiomas.
#### 3.2.3 REST sobre HTTP/2
Se trata de desarrollar o actualizar nuestra aplicación usando las prácticas ya conocidas para generar servicios REST (seguramente con JSON como formato). La diferencia estará en el protocolo de transporte, que será HTTP/2, lo cual aportará significativas ventajas en el rendimiento de modo casi del todo transparente.
HTTP/2 es un transporte que convierte los mensajes a binario comprimido, de modo que el JSON que generamos como petición/respuesta reduce su tamaño en gran medida antes de viajar por la red. La mejora es evidente, aunque ciertamente el formato de mensajes de Thrift y gRPC estén aún más optimizados.
El protocolo también soporta mantener un socket abierto con el servidor que enruta todos los mensajes, minimizando el overhead de negociación HTTP. Esto es otro big win a la hora de interconectar microservicios e incluso para gestionar la conexión desde el cliente al servidor.
Otra ventaja es el server push: se puede anticipar la siguiente petición e ir enviando la respuesta antes de que ésta se produzca. Esta optimización no sale gratis como las otras, y solo aplicará a casos muy específicos (generalmente para peticiones desde el cliente usuario).
La monitorización, cacheo y balanceo de carga están ya resueltas desde hace años para los servidores HTTP, así que no faltarán soluciones para estas necesidades.
### 3.3 Revisión de tecnologías
#### 3.3.2 Saga
Se podría definir Saga como una secuencia de transacciones locales, en la que cada transacción local actualiza mediante algún tipo de evento la siguiente transacción que se debe realizar.
#### 3.3.3 Patrón Saga con Coreografía
Tomando en cuenta el artículo [Patrón Saga en Arquitectura de Microservicios de Refactorizando](https://refactorizando.com/patron-saga-en-arquitectura-de-microservicios/), en una coreografía, cada bailarín funciona de manera independiente realizando una secuencia de pasos, que se encuentran enmarcados dentro de un sistema, para entre todos conseguir un objetivo. Con este símil podríamos definir una coreografía en Arquitectura de Software, en la que cada servicio o microservicio se comunicará con otros a través de eventos para decidir la siguiente acción a realizar.
A diferencia de una orquestación, aquí no tendremos una pieza central en la que se «orquestará» la siguiente acción o paso a realizar, sino que se enviarán eventos, que en este caso serán procesados por ejemplo **Kafka**.
Por lo anterior, vemos más conveniente trabajar con Coreografía ya que permite la utilización de patrones de diseño orientados a eventos como el Event Sourcing, o el patrón Command Query Responsability Segregation (**CQRS**) que veremos a continuación.
La desventaja de este patrón es que se mantiene sencillo de trabajar siempre y cuendo el flujo de pago tenga menos de 15 pasos, de lo contraria empezaría a ser complejo saber qué servicios van a escuchar o recibir qué eventos.
#### 3.3.4 Apache Kafka
Es una plataforma de transmisión de eventos distribuida de código abierto utilizada por miles de empresas para canalizaciones de datos de alto rendimiento, análisis de transmisión, integración de datos y aplicaciones de misión crítica.
#### 3.3.5 CQRS
Este patrón de diseño, cuyas siglas en inglés significan **Command Query Responsibility Segregation**, separa en responsabilidades de command y query sobre los datos. Ideado por Bertrand Meyer la idea que surge de este patrón es que cada microservicio debe realizar un comando que haga una acción o una consulta, pero no ambas. Se podría tener una base de datos para operaciones de lectura y otra para operaciones de escritura/actualizaciones.
#### 3.3.6 Event Sourcing
Este patrón de diseño es muy común encontrarlo integrado con CQRS. La utilización de este patrón funcionaría enviando mensajes de manera asíncrona entre los microservicios, por ejemplo haciendo uso de Kafka, para la comunicación entre ellos.
#### 3.3.7 Base de Datos por Servicio
En una arquitectura de microservicios, cada uno debe de estar lo más desacoplado posible. Es por ese motivo por el que tener una base de datos en común podría ser muy complicado y difícil de mantener. Diferentes bases de datos se podrán escalar de manera independiente en función de las necesidades, algunas operaciones deberán de realizarse tras consultar otras, por lo que habría que mantener su aislamiento; diferentes microservicios diferentes necesidades, de esta manera incluso se podrán utilizar bases de datos orientadas a columnas, de grafos, etc…
#### 3.3.8 Transaction log tailing
Este es otro patrón para ayudar a conseguir transacciones distribuidas, la idea detrás de este patrón es seguir el registro de transacciones en la base de datos, y cada cambio publicarlo como un evento.
### 3.4 Definición de orquestación
#### 3.4.1 Kubernetes
Kubernetes es una plataforma portable y extensible de código abierto para administrar cargas de trabajo y servicios. Kubernetes facilita la automatización y la configuración declarativa. Tiene un ecosistema grande y en rápido crecimiento. El soporte, las herramientas y los servicios para Kubernetes están ampliamente disponibles.
#### 3.4.2 Linkerd
Es una malla de servicios para Kubernetes. Hace que la ejecución de servicios sea más fácil y segura al brindarle depuración, observabilidad, confiabilidad y seguridad en tiempo de ejecución, todo sin requerir ningún cambio en su código. [[link](https://linkerd.io/2.10/overview/)]
#### 3.4.3 ISTIO
Proporciona puertas de enlace para administrar el tráfico que ingresa y sale de la malla de servicios. La puerta de enlace del balanceador de cargas interno (ILB) de Istio enruta el tráfico entrante de las fuentes en la red de VPC interna a los pods de Kubernetes en la malla de servicios. En esta arquitectura, el balanceo de cargas TCP/UDP interno de Google Cloud realiza el balanceo de cargas de la capa 4 (capa de transporte) en los nodos del clúster de GKE. La puerta de enlace del ILB de Istio recibe el tráfico y realiza el balanceo de cargas de la capa 7 (capa de aplicación) y distribuye el tráfico a los servicios en la malla de servicios de Istio mediante reglas definidas en servicios virtuales y reglas de destino.
### 3.5 Sobre DOMA
La “Arquitectura de microservicio orientada al dominio” se basa en gran medida en las formas establecidas de organizar el código, como el diseño dirigido por el dominio , la arquitectura limpia , la arquitectura orientada a servicios y los patrones de diseño orientados a objetos e interfaces. Creemos que DOMA es innovador solo en la medida en que es una forma relativamente novedosa de aprovechar los principios de diseño establecidos en grandes sistemas distribuidos en grandes organizaciones.
Los principios básicos y la terminología asociados con DOMA son los siguientes:
1. En lugar de orientarnos en torno a microservicios únicos, nos orientamos en torno a colecciones de microservicios relacionados. Llamamos a estos **dominios**.
2. Además, creamos colecciones de dominios que llamamos capas. La capa a la que pertenece el dominio establece qué dependencias pueden asumir los microservicios dentro de ese dominio. A esto lo llamamos **diseño de capa**.
3. Proporcionamos interfaces limpias para dominios que tratamos como un único punto de entrada a la colección. Llamamos a estas **puertas de enlace**.
4. Finalmente, establecemos que cada dominio debe ser agnóstico a otros dominios, es decir, un dominio no debe tener lógica relacionada con otro dominio codificado dentro de su base de código o modelos de datos. Dado que con frecuencia los equipos necesitan incluir lógica en el dominio de otro equipo (por ejemplo, lógica de validación personalizada o algún metacontexto en un modelo de datos), proporcionamos una **arquitectura de extensión** para admitir puntos de extensión bien definidos dentro del dominio.
## ~~4 Métricas~~
<!--
Que métricas debemos vamos a instrumentar, o monitorear para observar las implicaciónes de esta decisiòn?
Por ejemplo, cuando interactuamos con un sistema externo que tipo de latencia esperariamos o si agregamos una tabla nueva que tan rápido se llenaría?
-->
## 5 Riesgos e inconvenientes
<!--
¿Hay razones por las que no deberiamos hacer esto?
¿Qué riesgos estamos tomando? Por ejemplo, no tenemos experiencia con esta tecnología nueva o no entendemos la escala aún.
-->
En los últimos años la gente ha comenzado a condenar los microservicios por su tendencia a aumentar en gran medida la complejidad, lo que a veces dificulta la creación de características triviales.
Es por esto que en los últimos 2 años Uber ha intentado reducir la complejidad sin dejar de mantener los beneficios de una arquitectura de microservicios y para esto recomienda un enfoque generalizado llamado "Arquitectura de microservicios orientada al dominio" y sus siglas en Inglés DOMA.
Otros de los riesgos es la complejidad técnica de la arquitectura y del conjunto de tecnologías que requieren de un conocimiento y una curva de aprendizaje para lograr el objetivo de manera correcta.
## 6 Alternativas
<!--
¿Hay otras formas de resolver éste problema?
-->
La alternativa que se tiene es desarrollar este feature en la aplicación actual dentro del módulo de OrdersApi, la desventaja es una implementación monolítica como la que tenemos actualmente y como se ha visto hasta ahora, no es lo más recomendable, ya que crecería a un más la aplicación y se haría menos escalable y mantenible.
Otra alternativa es trabajar solo la arquitectura síncrona para todos los flujos, esta solución no implementaria algunas tecnologías pero no cubriríamos algunas funcionalidades que vemos aplican mejor de manera asíncronas.
## 7 Impacto potencial y dependencias
<!--
¿Qué otros sistemas se verán afectados con esta propuesta?
¿Qué consideraciones de seguridad debemos tener?¿Como pueden explotar esta parte del sistema?
¿Que impacto tiene esta decision sobre soporte al cliente?
Aquí buscamos ser concientes del ambiente en el que operamos y generar empatía hacia otros que pueden verse afectados por nuestra decisión.
-->
Como impacto potencial tenemos:
* Agilidad, dado que es más fácil implementar nuevas versiones de los microservicios con frecuencia.
* En cuanto a la seguridad, la utilización de Amazon EKS y Linkerd aportan esa capa importante, por lo que es necesario una buena configuración.
* Esta solución mejoraria la eficiencia y escalabilidad del modulo de checking de las ordenes.
* Se puede trabajar con equipos mas pequeños enfocados en servicios puntuales, aunque siempre es importante una buena comunicación y definición de alcances para evitar misma responsabilidades en más de un microservicio.
Las dependencias existentes en una arquitectura de microservicio son:
* La infraestructura, ya que se requiere de un conjunto de tecnologías cada una con una función y alcance por lo que si alguna falla, podría afectar a otras aguas abajo.
## ~~8 Preguntas sin resolver~~
<!--
¿ Qué preguntas no hemos resuelto?
-->
## ~~9 Ideas futuras~~
<!--
¿ Qué preguntas no hemos resuelto?
-->
## 10 Conclusión
Con una aplicación grande y monolítica, una organización se ve obligada a implementar o liberar todo su código a la vez. Cada nueva versión de una aplicación puede implicar numerosos cambios, por lo que las implementaciones se vuelven riesgosas (Cualquiera puede derribar todo el sistema) y requieren mucho tiempo.
Si bien en los últimos años ha sido popular criticar las arquitecturas de microservicios debido a desventajas como la complejidad que se genera al contar con cientos o miles de microservicios, pocas personas han abogado por un rechazo rotundo de esta arquitecturas.
Los beneficios operativos son demasiado importantes y parece que no hay alternativas o son limitadas. Por lo que existen maneras de reducir la complejidad general del sistema utilizando **DOMA** flexibilizando las arquitecturas de microservicios.
Es por lo anterior, que promonemos la **Arquitectura de Microservicio** como una mejora importante ya que tiene como ventajas la flexibilidad de las implementaciones y escalas independientes, propiedad clara, mejoras en la estabilidad del sistema y una mejor separación de preocupaciones.
A continuación indicamos nuestras definiciones con respecto a las tecnologías a utilizar:
### 10.1 Selección de Lenguaje: Golang
Seleccionamos el lenguaje **Golang** ya que es perfecto para proyectos y microservicios a escala empresarial que exigen cargas altas así como eficiente, escalable y productivo. Para el apartado sobre Programación Orientada a Objeto (OOP) si bien Golang no lo es 100%, tiene su enfoque particular para conseguirlo.
### 10.2 Selección de protocolo de comunicación: gRPC
**gRPC** se adapta mucho más a lo que queremos ya que es la opción para una optimización máxima y comunicación eficiente entre procesos en estructuras cliente-servidor distribuidas que busquen una latencia baja y un flujo elevado de datos y mensajes. Incluso, en soluciones mixtas en las que los servicios menos críticos usen **HTTP/2**, y se utilice gRPC para los puntos en los que sea necesario exprimir al máximo los tiempos de respuesta.
### 10.3 Selección de revisión de tecnología
En cuanto a la sección de revisión de tecnología, **Saga con Coreografía** es la mejor opción para separar y desacoplar la base de datos por servicio, en conjunto con **Kafka** para el manejo de eventos y **CQRF** para separación en responsabilidades de command y query sobre los datos.
También vemos una solución hibrida para las funcionalidades asíncronas como cambios de estado de la orden, confirmación de pago via webhook con los métodos de pago, si cambia el precio de la orden y si se cancela, o síncronas como validación del salgo en la cuenta, pagos síncronos, entre otros.
Para la orquestación **Kubernates** es la opción que vemos necesaria para este proyecto, en cuando a la malla de servicio nos decantamos por **Linkerd** porque [es más sencillo de implementar y en menos tiempo](https://thenewstack.io/istios-complexity-leads-some-users-to-linkerd/), adicionalmente se integra muy bien con **Grafana** que es una tecnología para supervisar y solucionar problemas de transacciones.
