De interfaces de usuario brillantes a servidores estables: nuestro viaje para garantizar el tiempo de actividad y la resiliencia
Cuando comenzamos Glassix, las nuevas funciones eran la máxima prioridad, por encima de casi todo. Nuestros primeros clientes no perdieron mucho el sueño por el SLA de tiempo de actividad; ¡Querían su nueva y brillante interfaz de usuario y la próxima integración de canales!
Cuando firmamos con nuestros primeros grandes clientes, sus prioridades eran diferentes. Si bien todavía se preocupaban por la funcionalidad, también se preocupaban por la resistencia; Un centro de atención al cliente con 40 agentes en un turno no podía permitirse el lujo de desconectarse porque teníamos un servidor diferido.
Luego, hace aproximadamente un año y medio (convenientemente casi al mismo tiempo que nació mi hija), nuestra plataforma comenzó a responder lentamente a varias solicitudes. Y por despacio, me refiero a unos 20 segundos de media. Como agente, era casi imposible trabajar de esta manera. Este problema (que más tarde descubrimos relacionado con una copia de seguridad oculta en nuestro proveedor de nube) ocurrió durante unos 20 largos minutos cada semana hasta que encontramos el problema.
Esta fue una llamada de atención para Glassix. La empresa, reconociendo el equilibrio crítico entre la innovación y la confiabilidad, comenzó a redirigir los recursos hacia el fortalecimiento de su infraestructura.
Nos dimos cuenta de que teníamos que actuar con rapidez en algunos de nuestros proyectos, así que también aprovechamos el poder de las soluciones de externalización y los autónomos, que nos ayudaron a alcanzar nuestros objetivos a tiempo.
Ahora, además de la lista de verificación habitual, como el almacenamiento en caché, el escalado horizontal y la CDN, también hicimos lo siguiente:
Modo sin conexión
Incluso con una pésima señal de red, aún puede abrir y ver mensajes en su aplicación WhatsApp . Incluso puede enviar mensajes, y una vez que esté en línea, se enviarán automáticamente. ¡Mágico!
Lo mismo con Glassix. Pruébelo ahora: Desconéctese y navegue hasta su espacio de trabajo de Glassix. Puede ver mensajes e imágenes (que antes se almacenaban en caché), enviar mensajes, ver respuestas predefinidas, cerrar tickets y asignar conversaciones. Todas estas acciones se ponen en cola y se sincronizarán una vez que vuelva a estar en línea. Es una de nuestras características de resiliencia de la que estoy más orgulloso. Utilizamos Workbox, que simplifica el proceso de creación de aplicaciones web sin conexión, lo que facilita la creación de experiencias de usuario confiables incluso cuando la red no es confiable.
Nuestro modo fuera de línea puede mitigar los problemas de red que nuestros clientes puedan experimentar.
Pares de servicios paralelos
Usamos tantas bases de datos y servicios que perdí la cuenta: MongoDB, SQL Server, Elastic Search, Redis, Ably, aplicaciones estáticas, funciones sin servidor y muchos más.
Los servicios cubiertos por un SLA con disponibilidad de cuatro nueves, o el 99,99%, podrían no estar disponibles 52 minutos y 36 segundos al año. La disponibilidad de tres nueves (99,9%) permite 8 horas y 46 minutos de tiempo de inactividad al año.
Digamos que cada uno de estos servicios principales está fuera de servicio durante 2 horas en total una vez al año. Significa que estaremos inactivos durante al menos 24 horas al año, ¡algo con lo que no podemos vivir!
Así que, por supuesto, todos los servicios en la nube vienen con una copia de seguridad, pero según nuestra amarga experiencia, se necesita más.
Nuestra costosa solución funciona bien: cada servicio principal tiene un servicio de redundancia.
un. El servicio de tablas de Azure se ejecuta con AWSdynamoDB.
b. SignalR con Ably.
c. Las aplicaciones estáticas se replican en 5 regiones y se almacenan en caché en el equilibrador de carga.
d. CDN de Fastly con Azure CDN.
e. Redis con Elasticache.
f. Múltiples dominios en caso de una interrupción del DNS: *.glassix.com y *.glassix.io
Y la lista sigue y sigue.
Ingeniería del caos
La ingeniería del caos es un enfoque disciplinado para identificar fallas antes de que se conviertan en interrupciones. Al probar de forma proactiva cómo responde un sistema bajo estrés, puede identificar y corregir las fallas antes de que terminen en las noticias. Básicamente, ¡significa empezar a romper cosas!
De esta manera, identificamos minuciosamente todos los puntos de asfixia en nuestra plataforma y los resolvimos (con otros servicios/lógicas diferentes).
¿Te encanta tu servicio Redis? Apágalo (o mejor aún, bloquea todas las IP; de esta manera, siempre alcanzarás el tiempo de espera máximo configurado para cada solicitud). Descubrimos que no puede iniciar sesión en nuestra aplicación si Redis está inactivo debido a nuestro token CSRF.
¿Tu CDN? Estropea sus registros DNS y mira qué pasa.
Descubrimos que sin la CDN, nuestra aplicación se bloquea. Así que implementamos una lógica de reintento en todas partes: primero, cargamos desde la CDN principal (Fastly); si falla, vamos al secundario (Azure CDN), y si falla, vamos al host actual.
Sacrifica a unos pocos para salvar a muchos
Este concepto en ingeniería de software se refiere a hacer concesiones o decisiones que pueden implicar sacrificar el rendimiento o los recursos de unos pocos componentes o procesos para mejorar la confiabilidad y estabilidad general de un sistema de software. Este concepto se aplica a menudo a situaciones con recursos limitados o en las que la optimización de todos los componentes no es factible o práctica.
En nuestro caso, hemos establecido tiempos de espera cortos para las solicitudes HTTP y SQL no críticas. Significa que serán los primeros en fallar una vez que SQL u otro servicio no funcione bien, pero hemos aligerado la carga sobre estos servicios al reducir rápidamente estas solicitudes no críticas.
Disyuntor
Fallar rápido es fundamental. Considere un ejemplo: muchos usuarios acceden a un servicio que está inactivo, como en una aplicación bancaria donde el servicio de cuenta falla y abruma otros servicios como la autenticación. Esto puede agotar los recursos, causando fallas generalizadas en el sistema. Los disyuntores de los microservicios evitan este tipo de fallos en cascada deteniendo rápidamente las operaciones para proteger el sistema. También implementamos un disyuntor en algunas de nuestras API HTTP no críticas. Una vez que un servidor detecta que está a punto de agotarse, rechaza automáticamente las solicitudes no críticas.
No ponga todos los huevos en un canasto
Los microservicios pueden mejorar la resiliencia general de la aplicación. Si se produce un error en un microservicio, no necesariamente se desactiva toda la aplicación. Esta contención de fallos es una ventaja significativa sobre las arquitecturas monolíticas, en las que un solo fallo puede afectar a todo el sistema.
¿Qué sigue?
Estos grandes cambios no ocurrieron de la noche a la mañana. Tuvimos que hacerlas poco a poco, ya que afectan al núcleo de nuestra plataforma. Continuaremos equilibrando la búsqueda de características innovadoras con la necesidad de una plataforma robusta y confiable. Esto significa que persistiremos en la introducción de características de vanguardia al tiempo que nos aseguraremos de que la plataforma central siga siendo sólida y confiable.