¿Cómo ha mejorado la eficiencia de su proyecto mientras consulta / trabaja para una empresa de TI?

Esta es mi experiencia personal.

Estaba trabajando en algún motor, cuyo propósito era generar facturas. La especificación del cliente establece que deberíamos ser capaces de generar 12000-15000 facturas por hora, mientras que el sistema generaba solo 1000 por hora.

Eso significa que necesitamos aumentar el rendimiento en más del 120%.

Estaba en el entorno de producción cuando me dieron esta tarea.

Dividí el funcionamiento del motor lógicamente en fases de acuerdo a mí mismo, y puse el código de medición de tiempo en cada fase. (Hora de inicio y hora de finalización).

Lo hice en el servidor de ensayo y ejecuté el mismo ejercicio repetido para 1000 registros. Sin embargo, el resultado fue demasiado frustrante. Hice un sobresaliente y noté el tiempo de ejecución de cada fase, para el registro de 1K, todo parecía normal y el tiempo necesario para completar el ciclo fue en segundos. No tenía sentido y, en general, solo tenemos una ejecución de producción cuando se generan facturas reales, y el ciclo de facturación de este mes también se estaba acercando.

Por lo tanto, seguí adelante para obtener un mayor récord. Esta vez en la puesta en escena, volví a generar facturas del mes pasado para todos los registros. Se inician algunas actualizaciones en la base de datos, validación de datos y el motor de facturación. Seguía funcionando de noche y a la mañana siguiente cuando llegué a la oficina, seguía funcionando. Se facturaron 12 horas y ni siquiera 12,000 consumidores. Por el contrario, solo 7000 consumidores. Pero luego obtuve datos en bruto. Suficiente de ellos.

Entonces supimos que el principal culpable de nuestro problema era la base de datos.
Las consultas simplemente fueron optimizadas.
Los índices no se construyeron en tablas.

Le pedí a mi gerente un sitio de DBA dedicado pero sabemos cómo funciona en India para compañías más pequeñas.

Por lo tanto, tuve que crear un script, crear índices, consultas optimizadas, leer muchas publicaciones de blog sobre la optimización.

La noche siguiente, 2000 consumidores por hora y se mantuvo estable.
Ejecutas el motor en cualquier momento, el rendimiento fue estable.
Lo suficientemente satisfactorio para mí, pero no para nadie más. Ni al equipo del proyecto ni al cliente ni a mis superiores.

Entonces, ¿qué sigue? Comenzando el análisis desde el principio, y esta vez el énfasis estaba en el código . Creé algunas reglas básicas:

1) Cualquier cosa que se ejecute dentro del bucle debe optimizarse, lo que significa que no hay declaración variable en el bucle, hasta que sea posible, no hay cálculo en el bucle.
2) Cadenas para ser reemplazadas por el generador de cadenas.
3) Hubo algunos cálculos repetidos hechos dentro del código en cada método. Por ejemplo, para calcular facturas se generará durante cuántos días, se realizó un cálculo de multiplicar por mes y días. Parecía que alguien era lo suficientemente inteligente como para escribir 1 código de línea para calcularlo y otros eran lo suficientemente tontos como para copiar y pegar esta línea en cada método escrito. (El motor era complejo y había al menos 50 de estos métodos que tenían un propósito diferente de calcular algo) e incluso dentro de cada método, esta línea se usaba dentro del bucle, y en ocasiones más de una vez.
Se hicieron más cálculos similares en diferentes lugares.
Definí una variable de nivel de clase, calculé este número de días una vez antes de cualquier llamada de método o bucle y lo reemplacé cada vez que se calculó este valor.
4) Más optimizaciones similares con respecto a la minimización de cálculos repetidos.
5) Ajuste de parámetros de JVM Sí, lo has leído bien, recolección de basura, configuración de xms y xmx, parámetro de optimización de cadena, etc … no se pudieron recuperar más. ¡En este momento me volví paranoico y literalmente me quemé 10 días y noche generando facturas una y otra vez con cambios de parámetros definidos o cambios de sus valores y sentí que hice un documento para cada parámetro de JVM ~!
6) BufferedWriter en lugar de FileWriter simple y, por lo tanto, E / S con buffer
7) Reducción de código duplicado
8) Minimización de las comparaciones (hasta donde sea posible).
9) Más cambios pero no los recuerdo ahora … 🙁

Y voilla, ahora tengo una construcción lista para ser probada, con los dedos cruzados programé una construcción al final del día después de verificar cada cosa y esperé, esta vez el rendimiento será como al menos 5K facturas por hora, estaba lo suficientemente seguro que mañana seré un héroe.

Sin embargo, algún extraño problema de conexión de db y el motor no funcionaron.
Decepcionado de ver, pero antes de que pudiera volver a poner en marcha el motor, me reuní por la mañana y hubo algunas personas nuevas junto con mi gerente y otras personas mayores.

Se decidió que para lograr algo significativo, necesitamos generar facturas en paralelo .
Simple, genera facturas de una ciudad a la vez en el centro de datos, solo genera facturas de dos o tres ciudades a la vez. Su eficiencia es de 2000 facturas por hora, pero eso la cambiará a 6000 facturas por hora.
Nadie ha pensado en eso y hecho eso.
El motor es complejo y de los miembros de mi propio equipo y gerente, el concepto se opuso. La renuencia y solo un motor de pensamiento es complejo, lee y escribe en tablas de bases de datos, cómo se puede ejecutar en paralelo.
Pero me golpeó! He conocido las fases y, si bien la fase de ahorro de datos no puede ejecutarse en paralelo, ¡todas las demás cosas, como la obtención de datos y los cálculos, pueden hacerse en paralelo!
Apoyé la idea de la persona externa y me comprometí a dar una compilación capaz de generar facturas en paralelo y capaz de ejecutarse en el servidor de producción en una semana.
Esto también significa que el equipo de prueba se asegurará de que yo trabaje en las noches también porque la nueva construcción en la producción ahora significa nuevos errores que, aunque ocurrieron en la producción desde hace mucho tiempo, pero deben corregirse, ya que estoy trabajando ahora. ¡El choque de requisitos de proyecto de v / s de rendimiento en el que simplemente quería trabajar solo en la parte de rendimiento!

Como los cambios en el código en mi prueba construida fueron significativos y no estaba seguro de ello (nunca se ejecutó hasta ahora), y cambié mucho por mi cuenta, no lo usé.

El trabajo del concepto de facturación paralela comenzó y encontramos otro problema mientras trabajábamos en él.

Cada método abre su propia conexión y la cierra.
Maldición ! Es como cada vez que ejecuta una consulta se establece una nueva conexión.
No parecía correcto y cambiar aquí significa literalmente que cada pieza del motor de facturación debe ser alterada.
¡Ya he leído muchos artículos en Internet y era hora de introducir el patrón de diseño Singleton en el motor de facturación !
Se tardó 1 hora en cambiar el código de clase donde se realizó la conexión de la base de datos. Pero tomó 2 días completos para cambiar en todas partes donde se realizó la llamada de creación de conexión de base de datos.
¡Los próximos 2 días, el concepto de subprocesamiento múltiple se introdujo en el motor de facturación!
Cosas simples, crear hilo e iniciar la ejecución, Hilo 1, hacer la fase 1, fase 2, y continuar … Hilo 2, hacer la fase 1, fase 2 y continuar …

¡El método de guardado final que estaba insertando o actualizando tablas se sincronizó!

¡El construido fue probado y ahora soy un héroe!
¡De alguna manera podemos comprometernos con el cliente de que la aplicación es capaz de generar 12000 facturas por hora!

Pero no estaba contento, esto no fue a lo que me comprometí.

Simplemente no tiene sentido.

Java es escalable y rápido. ¿Cómo es que una aplicación no puede generar un número tan alto de facturas dado que estamos usando un servidor de configuración de alta gama?

Estaba de vuelta con mi equipo ahora (desde el sitio).

Tomé la compilación de los cambios de código y volví a hacer los cambios en la copia de trabajo.
Ahora también tenemos 2 DBA experimentados dedicados en el sitio que realizan muchas optimizaciones al final de la base de datos y también cambian la consulta / SP de tiempo de ejecución prolongado.
Después de 2 meses, se realizó la construcción final y se incorporan todos los cambios que se han realizado hasta ahora. También hay correcciones en la funcionalidad que el cliente ha dado, el equipo de prueba nos ha dado muchos dolores de cabeza en estos 2 meses y yo, como el líder del módulo se ha asegurado, sigo comprometido solo en la parte de rendimiento y en los requisitos de otros clientes y en la lucha entre el desarrollo y equipo de prueba, solo interfirió en momentos críticos. !

Nuevamente estuve en el sitio con esta construcción y esta vez no estaba seguro de cuánto entregaremos. Fue porque la compañía no tenía el mismo servidor que era la configuración del servidor de producción / preparación.

Y dado que el equipo de prueba ya nos ha retrasado, no tuvimos tiempo de ejecutar el servidor de almacenamiento integrado.
Estuve en el sitio a las 7 de la mañana. Por la noche, comenzamos a facturar, el total de consumidores era de 12800. Después de 15 minutos leí el registro: Los consumidores facturaron 2000, restantes 10800.
Guauu ! Bastante emocionante
Llegó la llamada de la cena, salimos a cenar y no había compartido noticias con otras personas de que 2000 consumidores fueron facturados en 15 minutos, estaba muy contento pero contenía mis emociones. ¡La cena tomó 30 minutos, seguida de una caminata con mis amigos que necesitaban fumar! Otros 30 minutos.
Regresamos, vi en pantalla ¡ Facturación completada !
Pensé que WTF es esto, debe haber algún error dentro. Registros marcados, no, no a las … líneas bla bla bla …
Al instante, algunas consultas se dispararon en DB, sí, la facturación ya está hecha. Wow, eso es grandioso . Cuánto tiempo tardó, verifiquemos ahora.
¡Whaaaat …… La aplicación generó facturas de 12800 consumidores en solo 45 minutos!
Maldición, no creía en mis ojos. ! Pero todos del equipo del proyecto estaban contentos.
Tuvieron que pasar toda la noche en el centro de datos esperando que la aplicación termine de facturar, ¡pero ahora se hizo en una hora!
¡La noche siguiente, 15000 consumidores en 55 minutos!
¡Después de esa noche, la ciudad más grande, 21000 consumidores en 45 minutos!

Parecía que no había conexión entre el número de consumidores y el tiempo necesario, pero una cosa era segura. ¡He entregado lo que quería!

El momento más feliz de toda mi pequeña carrera hasta ahora.

Editar:
Esto sucedió antes de hace 2 años y he cambiado de compañía, así que no puedo recordar más cambios de código, pero toda la experiencia está en mi mente como primer amor. ¡Nunca lo olvidaré!

Aprende cómo hacer que los proyectos sean más seguros mediante el uso de ciertos marcos, etc. Eso es lo principal.

Luego, aprende cómo superponer adecuadamente sus datos para ocultarlos al usuario final. Además, también aprende cómo organizar su código. Estas son las cosas importantes que he aprendido después de unirme.