Recientemente escribimos sobre cómo trabajan los arquitectos de TI , y ahora le contaremos los detalles sobre uno de nuestros casos y le mostraremos el esquema del sistema. En este proyecto, ayudamos a reemplazar una aplicación bancaria de "caja" con un RBS de microservicio, al tiempo que establecimos una publicación rápida de versiones, en promedio, una vez a la semana.
: , , -. NDA – , , , -.
«»
Entre las empresas medianas y pequeñas, hay una demanda de soluciones de TI listas para usar, que se pueden personalizar y lanzar con su propio logotipo. Contras: las funciones de las aplicaciones "listas para usar" son limitadas y, a menudo, las actualizaciones deben realizarse durante mucho tiempo y exclusivamente a través del proveedor.
Uno de nuestros clientes utilizó un sistema de "caja" de servicios bancarios remotos (RBS). El banco en línea era una aplicación monolítica con un conjunto de funciones bastante reducido.
Para no ser inferior a la competencia, el banco tuvo que introducir constantemente mejoras y nuevas funciones. Sin embargo, incluso para simplemente mover los botones en la aplicación, tenía que ponerse en contacto con el proveedor. Las actualizaciones se publicaron en promedio una vez al trimestre.
Por lo tanto, fue difícil desarrollar el producto debido a una serie de restricciones:
- , «» .
- - «» -.
- , .
- , . .
- , .
- - , , , .
Como resultado, el banco tomó la decisión de abandonar gradualmente la "caja" y desarrollar su propio sistema de banca remota, con una arquitectura de microservicio, con el fin de acelerar el desarrollo de funciones y brindar comodidad y seguridad a los usuarios.
Donde empezamos
La creación de un banco en línea comenzó con el diseño de la arquitectura de alto nivel, la contratación de desarrolladores y la conexión de nuestro equipo dedicado. Al mismo tiempo, la arquitectura debía colocarse con un margen de seguridad, contando con futuras ampliaciones.
Al principio, nuestro equipo de desarrollo de Backend estaba involucrado en la implementación de ciertas funciones básicas: por ejemplo, transferencias de dinero. Sin embargo, teníamos mucha experiencia trabajando con bancos en línea, uno de nuestros proyectos en ese momento entró en la clasificación de la industria de Markswebb, por lo que le ofrecimos asistencia bancaria en diseño arquitectónico y recibimos luz verde.
Arquitectura
Junto con el propietario del producto, decidimos utilizar Spring Cloud, que proporciona todas las funciones necesarias para implementar una arquitectura de microservicio: esto es Service discovery - Eureka, Api Gateway - Zuul, Config server y mucho más. Se eligió OpenShift como el sistema contenedor para las imágenes de Docker, porque la infraestructura del banco se mejoró para esta herramienta.
También analizamos qué características de la antigua "caja" pueden complicar el trabajo de los usuarios. Uno de los principales inconvenientes era que el sistema funcionaba sincrónicamente a través del bus de datos y cada acción del usuario provocaba un acceso al bus. Debido a las cargas pesadas, el bus a menudo fallaba y toda la aplicación dejaba de funcionar. Además, como en muchos productos bancarios antiguos, el legado se ha acumulado: "legado" en la forma del antiguo y pesado CORE ABS, que sería difícil y costoso de reescribir.
Hemos propuesto una serie de mejoras:
- Control de versiones
Anteriormente, la "caja" solo admitía una versión, pero en el nuevo banco en línea propusimos una nueva arquitectura que nos permitirá admitir varias versiones diferentes al mismo tiempo y reemplazarlas si es necesario.
El esquema de control de versiones es el siguiente: si la versión secundaria del servicio ha cambiado, el servicio se reconstruye e implementa automáticamente, reemplazando la versión obsoleta. Si ponemos la versión principal, entonces se implementa una nueva copia del servicio con la nueva versión. Así, el desarrollo de nuevas funciones con un cambio en la API del servicio no afecta a la aplicación móvil, mientras que se reduce el tiempo de prueba. Este sistema hizo posible brindar soporte incluso para versiones desactualizadas de la aplicación móvil si el usuario no tiene la oportunidad de actualizar.
- Asincronía
Hemos implementado una biblioteca que se puede utilizar en servicios que requieren trabajo asincrónico. La biblioteca implementa la ejecución de tareas asincrónicas, es adecuada para su uso en cualquier número de copias de servicios y no interfieren entre sí. La sincronización entre diferentes copias se realiza mediante la cola de mensajes de Kafka.
Esta solución ayudó a mejorar la estabilidad de la aplicación. La aplicación móvil ahora es independiente del bus, duplicamos los datos necesarios para el usuario en nuestros servicios y los actualizamos en segundo plano cuando hay acceso al bus del banco. Todas las acciones del usuario se ponen en cola para su ejecución, tan pronto como están listas, se reciben notificaciones PUSH sobre los resultados.
- Almacenamiento en caché
Para acelerar la aplicación y reducir la carga de los recursos bancarios internos, se organiza el almacenamiento en caché de datos mediante Redis. KeyDB sirve como caché, que muestra buenos resultados y es compatible con muchos sistemas que usan Redis. Los datos se almacenan en caché no después de una solicitud del usuario, sino cuando los datos del usuario cambian, lo que permite el acceso a ellos independientemente de los sistemas bancarios internos.
Que ha cambiado en el sistema
Como se señaló anteriormente, en el antiguo banco en línea, el backend se implementó en una arquitectura monolítica, la aplicación se implementó en una máquina separada. A medida que aumentó la carga, se tuvieron que implementar nuevos servidores. Cuando el servidor falló, la aplicación móvil no funcionó para algunos usuarios.
La nueva solución utiliza una arquitectura de microservicio, que le permite implementar tantas copias de servicios como sea necesario para una funcionalidad en particular. Hemos agregado almacenamiento en caché de datos basado en KeyDB no solo para aumentar la velocidad de recuperación de información, sino también para reducir la carga en la base de datos.
Veamos un ejemplo de obtención de datos sobre cuentas de usuario en la nueva arquitectura. La solicitud del usuario desde la aplicación móvil pasa por el balanceador al Gateway, que comprende a cuál de los servicios enviar la solicitud. A continuación, llegamos a la API de servicio de cuenta. El servicio primero verifica si hay datos reales del usuario en la caché. Si tiene éxito, devuelve los datos; de lo contrario, envía una solicitud al servicio de cuenta de Middle.
La actualización de datos en el servicio puede ocurrir en varios casos. Por ejemplo, a petición directa del usuario, el servicio crea una tarea de actualización de datos que se ejecuta de forma asincrónica y se actualizan los datos recibidos del ESB. El servicio también recibe mensajes de la cola de mensajes y los responde. Por ejemplo, un servicio recibe un mensaje sobre un usuario que inicia sesión en una aplicación y actualiza inmediatamente los datos de la cuenta, recibe datos sobre las transacciones de la cuenta de otros servicios y actualiza sus datos. Por lo tanto, el usuario siempre ve datos actualizados en sus cuentas.
Entre los cambios más importantes se encuentran los siguientes:
- Flexibilidad de escala
Para aumentar la tolerancia a fallas del sistema, los servicios se distribuyen en diferentes servidores. Esto le permite mantener el sistema en funcionamiento en caso de caída de uno de ellos. Para una respuesta oportuna a situaciones no estándar, introdujimos un sistema de monitoreo que ayudó, si era necesario, a ampliar los servicios a tiempo. Conectamos DevOps para configurar CI / CD desde cero en los servidores del cliente, construimos procesos de implementación y soporte para la futura aplicación en múltiples servidores.
- Aceleración de lanzamientos debido al control de versiones
Anteriormente, al actualizar la versión móvil, algunos usuarios ya aplicaban la nueva versión, mientras que otros no, pero el número de esta última era mínimo. Al desarrollar una nueva RBS, implementamos el control de versiones y la capacidad de lanzar versiones sin el riesgo de que la aplicación deje de funcionar para una gran parte de los clientes. Ahora, al implementar funcionalidades individuales en nuevas versiones, no rompemos las versiones antiguas, lo que significa que no hay necesidad de retroceder. Esto ayudó a acelerar la frecuencia de lanzamiento al menos 15 veces; ahora los lanzamientos se lanzan en promedio una vez a la semana. Los equipos de backend y móviles pueden trabajar de forma simultánea e independiente en nuevas funciones.
Resumiendo
En este ejemplo, hablamos sobre el diseño de una arquitectura de microservicio para un banco, que reemplazó a la solución monolítica "en caja". Un equipo distribuido trabajó en este proyecto, que incluyó tanto a desarrolladores internos como a subcontratistas.
Al desarrollar un banco en línea, intentamos implementar el mismo alcance de funciones en la nueva aplicación que en una caja, y desarrollarlo gradualmente.
Para evitar la pérdida de clientes, era necesario establecer un funcionamiento sin problemas de la aplicación, sin fallas ni tiempo de inactividad, y la publicación periódica de lanzamientos y actualizaciones. Esto se hizo gracias a mejoras en la arquitectura. En particular, luego de reducir la carga en la base de datos, logramos una disponibilidad constante de la aplicación, y debido al versionado, redujimos el tiempo de prueba, aseguramos la posibilidad de trabajo independiente en la funcionalidad y lanzamiento de lanzamientos una vez por semana.
La arquitectura de la aplicación se basa en un mayor crecimiento del producto y las herramientas de desarrollo utilizadas por el equipo interno de la banca para que el propietario del producto pueda realizar de forma independiente cualquier mejora en el RBS. Los términos de desarrollo activo de la versión alfa fueron de aproximadamente un año, después de otros 3 meses se lanzó la versión beta para todos los usuarios.
Esperamos que el esquema de trabajo descrito pueda ser útil a la hora de crear otros productos fintech.
¡Gracias por su atención!