Estoy haciendo un proyecto en el que necesito que todas las llamadas a la API tarden menos de 1s, pero tengo un problema con la primera llamada a cada ruta que es más lenta que las siguientes.
Actualmente, la primera llamada / inicio de sesión dura 3.6 segundos y las siguientes tardan 170 ms y lo mismo para todas las demás rutas.
Descubrí que usando -XX:+TraceClassLoading
eso en la primera llamada, las clases se cargaron en la memoria y eso causó el problema de rendimiento.
Sin embargo, no encontré una manera fácil de cargar todas las clases al inicio y para cada nuevo servicio, necesito agregar una llamada de calentamiento en un ApplicationRunner.
¿Alguien tiene una solución para cargar automáticamente las clases de una aplicación SpringBoot o calentar todas sus rutas?
invokedynamic
y sabemos que la resolución es lenta en la primera llamada para esas (tenemos decenas de miles de esas llamadas, que sin esta primera llamada se acumulan en decenas de segundos).Respuestas:
La carga de clases de Java es perezosa. Esto significa que JVM solo carga una clase cuando lo necesita y si lo necesita.
Si desea forzarlo a cargar clases ansiosamente, solo necesita hacer referencia a ellas. Una forma de hacerlo es recorrer el contenido del jar o los archivos de clase para obtener los nombres de clase y luego usarlos para llamar
Class.forName(className)
.Además, si el tiempo de inicio y el rendimiento son muy importantes para su caso de uso, es posible que desee buscar soluciones de compilación anticipadas como GraalVM , o reducir el umbral de compilación de JIT (
-XX:CompileThreshold
).fuente
JIT
tiene sentido en las primeras invocaciones, realmente.GraalVM
es bueno, pero eche un vistazo a la cantidad de problemas que tiene en Github: tan pronto como pase de un proyecto de caja de arena a algo más grande (estoy mirando su reflejo, principalmente), sentirá algo de dolor, al menos. mi punto es: cambiar a GraalVM no es un simple chasquido de dedos.Para mí, la única opción viable que tienes es
class data sharing
, distribuir entre JEP 310 , JEP 341 y JEP 350 , pero esto requiere java-13 muy probablemente. Estamos probando esto internamente en mi lugar de trabajo (principalmente por diversión, no para mentir) y los resultados se ven bien, hasta ahora.La otra opción es llamar a sus puntos finales cuando se inicia la aplicación, si esa es una opción. Nuevamente, es para nosotros, por ejemplo: los llamamos con datos ficticios un par de cientos de veces para calentar el código. Pero, al mismo tiempo, tenemos servicios donde esto sería imposible, es por eso que
CDS
también exploramos.fuente