Recomendaciones para el rendimiento de los microservicios

El desarrollo de software hace necesario buscar un equilibrio entre las ventajas y desventajas de distintas opciones, y los microservicios no son una excepción. Lo que ganas en la implementación de código y en la independencia de las operaciones lo pagas en sobrecarga de rendimiento. Esta sección proporciona algunas recomendaciones sobre los pasos que puedes seguir para minimizar este impacto.

Convierte operaciones CRUD en microservicios

Los microservicios son especialmente adecuados para las entidades a las que se accede con el patrón crear, recuperar, actualizar, borrar (CRUD). Cuando trabajas con entidades de este tipo, normalmente usas solo una entidad a la vez, como un usuario, y normalmente realizas solo una de las acciones de CRUD a la vez. Por lo tanto, solo necesitas una llamada de microservicio para la operación. Busca entidades que tengan operaciones CRUD más un conjunto de métodos comerciales que podrían utilizarse en muchas partes de tu aplicación. Estas entidades son buenos candidatos para los microservicios.

Proporciona API por lotes

Además de las API de estilo CRUD, también puedes proporcionar un buen rendimiento de microservicios para grupos de entidad si proporcionas API por lotes. Por ejemplo, en lugar de exponer solo un método de la API GET que recupera un solo usuario, proporciona una API que tome un conjunto de ID de usuario y muestre un diccionario de usuarios correspondientes:

Solicitud:

/user-service/v1/?userId=ABC123&userId=DEF456&userId=GHI789

Respuesta:

{
  "ABC123": {
    "userId": "ABC123",
    "firstName": "Jake",
    … },
  "DEF456": {
    "userId": "DEF456",
    "firstName": "Sue",
    … },
  "GHI789": {
    "userId": "GHI789",
    "firstName": "Ted",
    … }
}

El SDK de App Engine admite muchas API por lotes, como la capacidad de recuperar muchas entidades del Cloud Datastore a través de una sola RPC, por lo que el servicio de estos tipos de API por lotes puede ser muy eficiente.

Utiliza solicitudes asíncronas

A menudo, necesitarás interactuar con varios microservicios para generar una respuesta. Por ejemplo, es posible que necesites recuperar las preferencias del usuario que accedió, así como los detalles de su empresa. Habitualmente, estos datos no dependen uno del otro y puedes recuperarlos en paralelo. La biblioteca Urlfetch en el SDK de App Engine admite solicitudes asíncronas, lo que te permite llamar microservicios en paralelo.

Utiliza la ruta más corta

Según cómo invoques Urlfetch, puedes hacer que se usen distintas infraestructuras y rutas. Para usar la ruta con mejor rendimiento, considera las siguientes recomendaciones:

Usa *.appspot.com, no un dominio personalizado
Un dominio personalizado hace que se use una ruta diferente cuando se enruta a través de la infraestructura de Google. Dado que tus llamadas de microservicios son internas, es más fácil y funciona mejor si usas tu nombre de host my-app.appspot.com.
Configura FollowRedirects en False
Configura explícitamente FollowRedirects=False cuando llames a Urlfetch. Esto te evita un servicio de peso más grande diseñado para seguir redireccionamientos. Los extremos de tu API no deberían necesitar redireccionar a los clientes, ya que son tus propios microservicios, y los extremos solo deben mostrar las respuestas de las series HTTP 200, 400 y 500.
Es mejor usar servicios dentro de un proyecto y no en varios proyectos
Existen buenas razones para usar varios proyectos cuando compilas una aplicación basada en microservicios, pero si tu objetivo principal es el rendimiento, usa servicios dentro de un solo proyecto. Los servicios de un proyecto se alojan en un mismo centro de datos y, si bien la capacidad de procesamiento en la red que conecta los centros de datos de Google es excelente, las llamadas locales son más rápidas.

Evita las conversaciones durante la aplicación de la seguridad

Es malo para el rendimiento utilizar mecanismos de seguridad que implican muchas comunicaciones para autenticar la API de llamada. Por ejemplo, si tu microservicio necesita validar un ticket de tu aplicación llamando a la aplicación, generarás una serie de idas y vueltas para obtener tus datos.

Una implementación de OAuth2 puede amortizar este costo a lo largo del tiempo mediante el uso de tokens de actualización y el almacenamiento en caché de un token de acceso entre invocaciones de Urlfetch. Sin embargo, si el token de acceso almacenado en caché se guarda en Memcache, necesitarás generar una sobrecarga de Memcache para recuperarlo. Para evitar esta sobrecarga, puedes almacenar en caché el token de acceso en una memoria de instancia, pero seguirás experimentando la actividad OAuth2 con frecuencia, ya que cada nueva instancia negocia un token de acceso; recuerda que las instancias de App Engine se activan y desactivan con frecuencia. Algunos híbridos de Memcache y la caché de instancia te ayudarán a mitigar este problema, pero aumentará la complejidad de tu solución.

Otro enfoque que funciona bien es compartir un token secreto entre los microservicios, por ejemplo, transmitido como un encabezado HTTP personalizado. En este enfoque, cada microservicio podría tener un token único para cada emisor. Por lo general, los secretos compartidos son una opción cuestionable para las implementaciones de seguridad, pero esto no constituye un problema importante si tenemos en cuenta las ganancias de rendimiento que se obtienen por tener todos los microservicios están en la misma aplicación. Con un secreto compartido, el microservicio solo necesita realizar una comparación de strings del secreto entrante con un diccionario probablemente en memoria, y la aplicación de la seguridad es muy ligera.

Si todos tus microservicios están en App Engine, también puedes inspeccionar el encabezado de X-Appengine-Inbound-Appid entrante. Este encabezado es agregado por la infraestructura de Urlfetch cuando se realiza una solicitud a otro proyecto de App Engine y no puede ser establecido por un tercero. Según los requisitos de seguridad, tus microservicios podrían inspeccionar este encabezado entrante para aplicar tu política de seguridad.

Realizar el seguimiento de las solicitudes de microservicio

A medida que compilas tu aplicación basada en microservicios, comienzas a acumular sobrecarga de llamadas sucesivas a Urlfetch. Cuando esto sucede, puedes usar Cloud Trace para comprender qué llamadas se están realizando y dónde se encuentra la sobrecarga. Es importante destacar que Cloud Trace también puede ayudar a identificar dónde se están invocando microservicios independientes en serie, para que puedas refactorizar tu código y realizar estas recuperaciones en paralelo.

Se activa una característica útil de Cloud Trace cuando usas varios servicios dentro de un solo proyecto. A medida que se realizan llamadas entre los servicios de microservicio en tu proyecto, Cloud Trace combina todas las llamadas en un solo grafo de llamadas para permitirte visualizar la solicitud completa de extremo a extremo como un solo registro.

Google Cloud Trace

Ten en cuenta que en el ejemplo anterior, las llamadas a pref-service y user-service se realizan en paralelo mediante el uso de un Urlfetch asíncrono, por lo que las RPC aparecen mezcladas en la visualización. Sin embargo, esta sigue siendo una herramienta valiosa para diagnosticar la latencia.

Pasos siguientes

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Entorno estándar de App Engine para Go