Ich mache ein Projekt, bei dem alle API-Aufrufe weniger als 1 Sekunde dauern müssen, aber ich habe ein Problem mit dem ersten Aufruf jeder Route, die langsamer ist als die folgenden.
Derzeit dauert der erste Anruf bei / login 3,6 s und der nächste 170 ms und für alle anderen Routen gleich.
Ich fand heraus, -XX:+TraceClassLoading
dass beim ersten Aufruf die Klassen in den Speicher geladen wurden und dies das Leistungsproblem verursachte.
Ich habe jedoch keine einfache Möglichkeit gefunden, alle Klassen beim Start zu laden, und für jeden neuen Dienst muss ich einen Aufwärmaufruf in einem ApplicationRunner hinzufügen.
Hat jemand eine Lösung, um die Klassen einer SpringBoot-Anwendung automatisch zu laden oder alle Routen aufzuwärmen?
invokedynamic
und wir wissen, dass die Auflösung beim ersten Aufruf für diese langsam ist (wir haben Zehntausende solcher Aufrufe, die sich ohne diesen ersten Aufruf auf Zehntelsekunden summieren).Antworten:
Das Laden von Java-Klassen ist faul. Dies bedeutet, dass eine Klasse nur dann von der JVM geladen wird, wenn dies erforderlich ist und erforderlich ist.
Wenn Sie es erzwingen möchten, Klassen eifrig zu laden, müssen Sie sie nur referenzieren. Eine Möglichkeit besteht darin, den JAR-Inhalt oder die Klassendateien zu durchlaufen, um die Klassennamen abzurufen und sie dann zum Aufrufen zu verwenden
Class.forName(className)
.Wenn die Startzeit und die Leistung für Ihren Anwendungsfall sehr wichtig sind, sollten Sie sich vorab mit Kompilierungslösungen wie GraalVM befassen oder den JIT-Schwellenwert für die Kompilierung verringern (
-XX:CompileThreshold
).quelle
JIT
bei den ersten Aufrufen wirklich bedeutungslos .GraalVM
gut, aber bitte in GitHub hat einen Blick auf die Reihe von Fragen haben: sobald Sie von einem Sandbox - Projekt zu etwas gehen größer (ich bin auf der Suche Sie Reflexion, vor allem), können Sie in einem gewissen Schmerz sein wird, mindestens. Mein Punkt ist: Das Wechseln zu GraalVM ist kein einfaches Fingerschnippen.Für mich ist die einzige praktikable Option, die Sie haben
class data sharing
, über JEP 310 , JEP 341 und JEP 350 verteilt , aber dies erfordert höchstwahrscheinlich Java-13. Wir testen dies intern an meinem Arbeitsplatz (meistens zum Spaß, um nicht zu lügen) und die Ergebnisse sehen bisher gut aus.Die andere Option ist das Aufrufen Ihrer Endpunkte beim Start der Anwendung - sofern dies eine Option ist. Auch hier ist es ist für uns zum Beispiel: wir sie mit Dummy - Daten , die ein paar hundert Mal den Code , um sich aufzuwärmen nennen. Gleichzeitig haben wir aber Dienste, bei denen dies unmöglich wäre - deshalb auch das Erkunden von
CDS
.quelle