Cómo Postman Engineering maneja un millón de conexiones concurrentes

Publicado el

El equipo de Server Foundation en Postman comparte la historia de origen de la puerta de enlace websocket de Bifrost

(22 de diciembre de 2020)

En Marvel Cinematic Universe, Bifrost es el nombre del puente arcoíris que permite viajes instantáneos entre los reinos de dioses y humanidad. De manera similar, e igualmente mágicamente, nuestra puerta de enlace Bifrost websocket permite a los clientes de Postman conectarse instantáneamente a los servicios de Postman.

Foto de Toni Reed en Unsplash

Como he compartido anteriormente en (Cómo Postman Engineering hace microservicios), todas las arquitecturas de software son un trabajo continuo en proceso. Operar en el mundo real significa reevaluar ocasionalmente las viejas formas de pensar para adaptarse a las nuevas circunstancias. Esa es la evolución natural del diseño de software.

Aquí está la historia de cómo los ingenieros de Postman desarrollaron la puerta de enlace websocket de Bifrost al eliminar un servicio que creció demasiado.

Equipos de desarrollo en Postman

La mayoría de los equipos de desarrollo de Postman trabajan en equipos multifuncionales centrados en un dominio de un solo núcleo, como la documentación o el control de versiones . Guiados por los principios del diseño basado en dominios , cada equipo desarrolla microservicios internos y funciones de Postman para los usuarios de Postman.

Si bien la mayoría de los ingenieros trabajan en escuadrones, algunos trabajan en equipos funcionales que crean componentes compartidos en toda la organización de ingeniería. El equipo de Server Foundation es un ejemplo de un equipo funcional en Postman. Estos ingenieros crean las utilidades utilizadas por otros escuadrones para construir, enviar y observar sus propias características. En este equipo también residen los expertos residentes en infraestructura y AWS.

the Server Foundation team es un ejemplo de un equipo funcional en Postman que crea y administra cosas que se utilizan en toda la organización de ingeniería

La mayoría de los microservicios en Postman son vagos acoplados para que puedan evolucionar independientemente de otros equipos. Desafortunadamente, un servicio a veces puede crecer demasiado, proporcionando una variedad de servicios aparentemente no relacionados. Estos servicios le permiten al equipo iterar rápidamente, pero pueden comenzar a actuar más como un monolito hinchado, una gran bola de barro o como quieras llamar a estas criaturas difíciles de manejar.

Cuando esto sucede en Postman, muchos ingenieros en diferentes equipos terminan contribuyendo al código, lo que requiere una coordinación cuidadosa entre todos los equipos para todas y cada una de las actualizaciones.

El servicio monolítico de sincronización

Uno de los servicios de Postman que creció demasiado para administrarse de manera eficiente se llama Sync. Tiene la abrumadora tarea de sincronizar toda la actividad del cliente Postman en su máquina local con los servidores Postman. Cada acción del usuario en Postman da como resultado una serie de llamadas a la API que se manejan a través de conexiones websocket, siguiendo un patrón de publicación-suscripción , de modo que la información fluya en tiempo real entre los usuarios y en todos los equipos.

Por ejemplo, esto es lo que sucede cuando inicia sesión en Postman y actualiza una colección:

  1. Agrega un parámetro a la colección Postman.
  2. Postman mantiene un registro de la actualización en el control de versiones almacenado con su perfil.
  3. Postman muestra la información más reciente a los espectadores de la colección en tiempo real.

La sincronización fue originalmente pensada para manejar transacciones de bases de datos, como actualizar una colección. Sin embargo, en esta época del año pasado, Sync también administró actividades adicionales, como notificar y mostrar la última versión a todas las personas suscritas a la colección.

Sincronización bajo presión

Cuando construye un automóvil, el marco es la estructura de soporte principal a la que todos los demás Se adjuntan componentes. Una pequeña grieta en el marco puede no parecer gran cosa. Probablemente podría pasar desapercibido conduciendo a baja velocidad. Sin embargo, a velocidades más altas, hay un efecto dominó que aumenta las desalineaciones. La grieta aparentemente insignificante permite que las vibraciones se amplifiquen en el resto del vehículo hasta que se convierte en una ruina en llamas.

“Cosas que pasa desapercibido en sistemas más pequeños se vuelve ineludible en sistemas más complejos.”
Kunal Nagpal , gerente de ingeniería en Postman

Sync fue uno de los primeros servicios en Postman, y su arquitectura monolítica permitió al equipo distribuir funciones de Postman rápidamente. Con el tiempo, comenzó a manejar cada vez más responsabilidades. Hasta el día de hoy, el servicio Sync todavía tiene una influencia generalizada en toda la organización de ingeniería, y muchos ingenieros sienten dolor cuando Sync se comporta de manera inesperada o hay un tiempo de inactividad programado.

En 2019, Sync manejaba tanto las conexiones websocket como la base de datos actas. Con cada vez más colaboración entre nuestros 11 millones de usuarios en ese momento, Postman se acercaba al millón de conexiones simultáneas en la carga máxima.

Como base para prácticamente todos los microservicios en Postman, la tensión en la sincronización estaba creciendo.

  • Fallo en cascada debido a la contrapresión: Cada implementación de Sync da como resultado la desconexión de los clientes de Postman conectados sobre websockets. Cuando se vuelven a conectar un millón de sockets, los recursos del servidor se degradan, lo que puede provocar más desconexiones, lo que provoca un aumento predecible pero inevitable que puede tardar entre 6 y 8 horas en recuperarse.
  • Impactando la experiencia del usuario: Aunque no sucedió con frecuencia, las conexiones interrumpidas significaron un retraso ocasional para ver las últimas actualizaciones y la actividad en un área de trabajo en equipo.
  • Mayor costo de mantenimiento : dado que todos los equipos dependían de Sync, prácticamente todos los ingenieros de Postman tuvieron que aprender a manejar conexiones caídas, iniciar nuevas y luego reconciliar cualquier conflicto en los datos.

El equipo de Server Foundation sabía que querían aumentar la eficiencia de las conexiones websocket, y también manejarlas por separado del Servicio de sincronización. El destino estaba claro, pero el camino para llegar allí no lo estaba.

“Esta es la evolución natural del diseño de software. Los microservicios comienzan ágilmente, pero se acumulan y necesitan ser desglosados. Queríamos separar el manejo de sockets de Sync porque estábamos a punto de introducir muchas más funciones ”.
Yashish Dua , ingeniero de software en Cartero

algunos servicios internos crecen demasiado y requieren una coordinación cuidadosa entre los equipos

Esto es lo que sucedió

Paso 1: Conseguimos el apoyo de la organización

El primer desafío a abordar no fue técnico. Este no fue el primer lanzamiento ambicioso de Postman. La ingeniería había aprendido de los viajes anteriores para empezar con la gente. A partir de octubre de 2019, los ingenieros de Server Foundation llevaron a cabo una serie de revisiones dedicadas a comunicar el objetivo a la organización en general y a explicar el beneficio para todos los servicios dependientes.

Si este nuevo sistema tuvo éxito, manejar las conexiones caídas y lidiar con las secuelas ya no sería un lugar común. Este fue un incentivo real para que los otros equipos de ingeniería respaldaran y migraran al nuevo sistema. Esta comunicación y coordinación abiertas continuarían durante la duración de este proyecto.

Paso 2: identificamos las incógnitas desconocidas

Los ingenieros sabían la dirección en la que se dirigían. A pesar de eso, tomaron algo de tiempo para pensar en todos los escenarios y comprender mejor los conceptos subyacentes. Los ingenieros programaron sesiones exploratorias con otras partes interesadas para identificar incógnitas desconocidas, las condiciones imprevisibles que pueden representar un riesgo mayor que las conocidas.

Si bien la organización Postman está acostumbrada a investigar y planificar, esta parte del proceso tomó mucho más tiempo de lo normal debido a la naturaleza crítica de este cambio. Investigaron diferentes opciones, consideraron los requisitos auxiliares y elaboraron un plan en el transcurso de dos meses.

Paso 3: Construimos la puerta de enlace websocket Bifrost

El Bifrost se compone de dos partes:

  • Puerta de enlace pública : la puerta de enlace utiliza el marco web Fastify y Amazon AWS ElastiCache para Redis como un intermediario de mensajes central para administrar todas las conexiones de websocket.
  • API privada : la API también utiliza Fastify como un marco web de baja sobrecarga para enviar tráfico a otros servicios internos de Postman.
Bifrost se compone de dos partes: una puerta de enlace pública y una API privada

Paso 4: Probamos la nueva puerta de enlace

Cuando los ingenieros de Postman estén listos para enviar una función, se espera que prueben la función, junto con las funciones relacionadas. Dado que casi todas las funciones de Postman se basan en websockets, esto significaba que todas las funciones tenían que ser probadas para esta versión. Además, un marco para pruebas automatizadas de websockets no se había todavía configurado en Postman, por lo que todas las pruebas se completaron manualmente antes de Bifrost. podría usarse en producción.

Este fue un viaje arduo, pero a fines de enero de 2020, la ingeniería tenía una prueba de concepto funcional.

Paso 5: migramos a la nueva gateway

Todos los clientes de Postman, como la aplicación Electron o la Web, dependen de una llamada de arranque inicial a otro servicio central llamado Godserver. Este servidor determina el acceso y la configuración de los clientes, y es la forma en que la ingeniería controla los lanzamientos de productos incrementales. Debido a que todo esto estaba predeterminado y controlado por Godserver, la migración a la puerta de enlace Bifrost no requeriría una sola actualización del código de cliente Postman.

El equipo de Server Foundation describió los pasos de migración de los escuadrones, los cambios de código requeridos y la configuración Aplicar. En el transcurso de unas pocas semanas, los servicios dependientes comenzaron a pasar de depender de Sync al manejo basado en Bifrost de sus conexiones websocket. Godserver desviaba cada vez más tráfico a la nueva puerta de enlace websocket para ver cómo manejaba Bifrost la carga y respondía a los casos extremos.

“Es como cambiar el motor de un avión a mitad de camino vuelo ”.
Numaan Ashraf , director de ingeniería de Postman

Paso 6: escalado el servicio

¡La puerta de enlace Bifrost estaba funcionando!

Pero Postman había adquirido un millón de usuarios más o menos mientras la puerta de enlace estaba en planificación y desarrollo. Y los otros equipos de ingenieros no habían detenido su propio trabajo durante este tiempo. Se confiaron nuevas funciones de colaboración, como control de versiones y control de acceso basado en roles (RBAC) fuertemente en websockets para que la información se actualice en tiempo real. Hubo una avalancha de próximos lanzamientos de productos que realmente probarían la nueva puerta de enlace.

Bifrost estaba listo para soportar las crecientes demandas y escalar el manejo de websocket.

  • Escalado horizontal : la mayoría de las veces, los servicios de Postman manejan un mayor uso escalando a instancias de mayor capacidad o agregando más instancias de cómputo a la flota. Por lo tanto, los ingenieros de Postman generalmente escalan hasta un servicio aumentando el tamaño y la potencia informática de AWS EC2 instancias, por ejemplo, mediante AWS Elastic Beanstalk. Pero para Bifrost, el manejo de websocket escala hacia fuera usando más máquinas. Su eficiencia óptima se logra cuando se utilizan instancias de menor tamaño en grandes cantidades. Este tipo de escala hiperhorizontal funciona bien para Bifrost porque los clientes no requieren un alto rendimiento de la red y limitar cada máquina a menos conexiones limita el radio de explosión de fallas.
  • Nuevo factor de carga de CPU y memoria : la mayoría de los servicios Postman pueden escalar de manera efectiva con una única dimensión de métrica de escalado, como CPU, memoria o latencia. Sin embargo, para Bifrost, las cosas se vuelven un poco más matizadas porque tanto la memoria como el uso de la CPU tienen diferentes impactos en las operaciones en varios niveles de rendimiento. Para tener en cuenta eso, Bifrost utiliza una métrica de escala personalizada basada en el factor de carga. El factor de carga es un cálculo multidimensional que imparte un perfil de escala no lineal personalizado.

Profundicemos en las decisiones arquitectónicas y tecnológicas tomadas por Postman Engineering.

La arquitectura y tecnología Bifrost

El sistema Bifrost tiene dos componentes principales: una puerta de enlace y una API. Esta arquitectura de dos partes es la salsa secreta para la estabilidad y escalabilidad del sistema.

El Gateway actúa como el punto de terminación para todas las conexiones websocket. Aunque las puertas de enlace comerciales están disponibles para la compra, era importante preservar la lógica empresarial heredada acumulada durante años de optimización. Los ingenieros de Postman también querían controlar completamente cómo se manejan los websockets, por ejemplo, si querían aprovechar el protocolo de enlace. Para la puerta de enlace Bifrost, utilizaron Amazon ElastiCache para Redis, lo que les permitió consultar la caché de Redis mediante nodos de lectura y escritura.Dividir el tráfico en dos nodos para operaciones de lectura y escritura permite al equipo optimizar aún más el rendimiento.

“Bifrost es nuestra puerta de enlace para todas las conexiones de websocket. Es un proxy para todos los clientes de Postman y es responsable de manejar las operaciones de socket de bajo nivel para los servicios internos de Postman ”.
Mudit Mehta , ingeniero de software en Postman

La mayoría de los demás servicios de Postman utilizan Sails como marco MVC en tiempo real para Node.js . Sin embargo, para la puerta de enlace Bifrost, los ingenieros necesitaban un marco de backend de alto rendimiento capaz de manejar grandes volúmenes con velocidad y uso de memoria optimizado. Una vez más, querían profundizar en la capa de conexión, por debajo de las abstracciones de nivel superior proporcionadas por Sails. Así que recurrieron a Fastify y bifurcaron el middleware socketio-adapter para optimizarlo para su propio uso. casos.

la puerta de enlace Bifrost usó AWS, Redis y Fastify para manejar websockets

Además de la puerta de enlace, el otro componente de Bifrost es la API privada que envía el tráfico a otros servicios de Postman. Se basa en reglas de negocio flexibles, por lo que se reevalúa constantemente sobre cómo y dónde reenviar el tráfico entrante.

“Componentes simples. Lógica compleja ”.
Kunal Nagpal , gerente de ingeniería de Postman

Para ambos componentes, el equipo de ingenieros decidió hacer los suyos. Aunque la parte de puerta de enlace de Bifrost no se actualiza con frecuencia, el equipo tiene control total sobre lo que sucede en las capas más profundas del manejo de websocket. La parte API de Bifrost es el cerebro de la operación y convierte los mensajes entrantes en tiempo real en llamadas HTTP estándar. También se puede actualizar más rápidamente como un componente independiente de Sync y la puerta de enlace Bifrost.

¿Recuerdas esa salsa secreta? Desacoplar Bifrost en estos dos sistemas discretos permite que ambas partes se optimicen para sus propios objetivos.

El viaje está lejos de terminar

Como ocurre con todas las jugosas historias de ingeniería, este no es el final . Los dejo con algunos cliffhangers sobre lo que viene a continuación para la ingeniería de Postman.

  • Genere redundancia adicional : la caché de Redis es un agente central de mensajes . El manejo de Websocket aún se basa en un solo punto de falla, entonces, ¿qué sucede si la caché alguna vez se cae?
  • Aumente el ancho de banda y el rendimiento : La puerta de enlace actualmente es capaz de manejar una simultaneidad 10 veces mayor, pero la comunidad Postman está creciendo rápidamente y la ingeniería está desarrollando más funciones de colaboración. La necesidad de manejar más tráfico de websocket está surgiendo rápidamente.
  • Continúe descomponiendo el monolito: El El servicio de sincronización contiene una mezcla de otros servicios entrelazados dentro de su base de código. Desacoplar el manejo de sockets de Sync afloja su control sobre otros servicios, por lo que ahora otros servicios se pueden despegar más fácilmente.

Este fue otro vistazo entre bastidores a cómo opera la ingeniería de Postman. Estén atentos para más historias de las trincheras.

🙏🏼 Revisión técnica de Kunal Nagpal, Yashish Dua, Mudit Mehta y Shamasis Bhattacharya.

Publicado originalmente en https://blog.postman.com el 22 de diciembre de 2020.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *