Vaya contra Excel en cientos de miles de filas

Este año ya escribimos en Habré sobre nuestro proyecto SmartCalls.io , un diseñador visual de llamadas creado para usuarios comerciales. El proyecto resuelve el problema comercial de las llamadas masivas de clientes: se crea un guión de llamada visual, se carga un archivo Excel con números de teléfono y luego se crea una campaña de llamadas. Se lanza la campaña: comienzan las llamadas a los clientes; en cualquier momento puede ver estadísticas, pausar la campaña, modificar la configuración. Los clientes quedaron satisfechos hasta que quedó claro que a veces es necesario llamar no solo a mucha gente, sino MUCHO, MUCHO. Debajo del corte está la esencia del problema y cómo lo vencimos usando el lenguaje de programación HYIP (no sin razón).


El problema


Inicialmente, el procesamiento de archivos se implementó en PHP 7.1; era una elección obvia, ya que toda la API de SmartCalls estaba escrita en él. El trabajo con listas de llamadas tenía una limitación: el archivo no debería contener más de 10 mil líneas llenas. Esta limitación fue desde el principio en SmartCalls y, sin embargo, no fue crítica. Hasta cierto punto.

Un gran banco necesitaba campañas telefónicas muy grandes: era necesario llamar a más de 10 mil usuarios. Por supuesto, nada evitó dividir archivos grandes en varios pequeños y descargarlos uno a la vez, pero hacer que los clientes sufran así no es nuestro método. Hablando de descargas alternativas: si nuestro cliente ya lanzó una campaña de llamadas y de repente quiere agregar usuarios, entonces puede hacerlo fácilmente. Esto es muy conveniente porque no necesita dejar de llamar o ejecutar una campaña separada para nuevos usuarios. Pero debe comprender que la posibilidad de recargar no fue concebida como una forma de cargar archivos grandes manualmente, en partes.

Entonces, el equipo tenía una tarea: implementar la carga de archivos grandes en la campaña para llamar por teléfono.

Solución


Somos muy competentes en el desarrollo de Java; por ejemplo, parcialmente, la API Voximplant se implementa en este lenguaje; también somos buenos en PHP (ver el ejemplo anterior, sugiere Captain Evidence). Es decir, podríamos cerrar rápidamente esta tarea usando uno de estos lenguajes, pero pensamos durante mucho tiempo expandir nuestra pila de tecnología, y aquí recordamos Go muy bien: es lo suficientemente rápido (funciona bien con la memoria), multiproceso y no necesita tiempo de ejecución porque Ir compila en un binario ejecutable. Además, podemos decir sobre el tamaño de los contenedores, pero más sobre eso más adelante ...

Como resultado, escribimos un microservicio en el lenguaje Go, que acepta hojas de gran tamaño (probadas hasta 300 mil líneas) y formato (xls, xlsx y todas sus variaciones). Ahora es el momento de los detalles.

Implementación


Cuando un cliente carga un archivo> 10 mil líneas en una campaña SmartCalls, se toma un microservicio para ello. Toma punteros de entrada:

  • a un archivo descargado al almacenamiento S3;
  • a la campaña en la que se debe cargar este archivo.

Luego, el microservicio recorre el archivo, lo golpea en fragmentos de 10 mil líneas (máximo para la plataforma) y carga cada fragmento como un archivo csv en el almacenamiento S3, tomando notas en la base de datos sobre cada fragmento (ruta al archivo, número de líneas). Cada fragmento se procesa y carga en una secuencia separada, lo que proporciona un aumento adicional en la velocidad de ejecución.

Para la lectura de archivos Excel se utilizaron bibliotecas de código abierto de tealeg y extrame . Es bueno que tengan no solo muchas estrellas, sino también nuevos compromisos :)

import ( "github.com/tealeg/xlsx" "github.com/extrame/xls" //   ) 

Y todo estaría bien, pero no sin sus matices. Durante el desarrollo, resultó que xlsx y xls, creados en diferentes editores, son muy diferentes en formatos y reglas para trabajar con ellos. Tuve que hacer muchas pruebas: OpenOffice, Excel de diferentes versiones, LibreOffice, Hojas de cálculo de Google, para enseñarle al microservicio a llevar los archivos a una sola forma: CSV. Después de que el microservicio "mastica" un archivo grande y lo convierte en un CSV, la API SmartCalls se activa y ya funciona con este archivo csv. Para el microservicio, dejamos un límite de 300 mil líneas, ya que cubre en gran medida las necesidades de los clientes, y no encontramos ninguna necesidad mayor.

Como resultado, la implementación mostró excelentes resultados en pruebas y preprod, después de lo cual lo implementamos en el prod.

Conclusión


Nuestro equipo siempre está tratando de implementar rápidamente nuevas características / mejoras, porque queremos que los clientes satisfechos permanezcan así. La tarea con archivos grandes no fue solo otro desafío para nosotros, sino también una buena razón para introducir Go en el proyecto, que hemos analizado durante mucho tiempo. Además del rápido desarrollo y la velocidad del trabajo, Go nos da una base para el futuro cuando comencemos a introducir contenedores (para hacer actualizaciones sin problemas y eso es todo), que este lenguaje es muy liviano. Escribiremos sobre los contenedores por separado, estad atentos :)

Source: https://habr.com/ru/post/es424697/


All Articles