Ich habe eine Spring Boot-Anwendung. Ich habe viele Abhängigkeiten hinzugefügt (leider brauche ich alle) und die Startzeit ist ziemlich hoch. Nur ein SpringApplication.run(source, args)
dauert 10 Sekunden.
Das ist zwar nicht viel im Vergleich zu dem, was "gewohnt" ist, aber ich bin unglücklich, dass es so viel kostet, vor allem, weil es den Entwicklungsfluss unterbricht. Die Anwendung selbst ist zu diesem Zeitpunkt eher klein, daher gehe ich davon aus, dass die meiste Zeit mit den hinzugefügten Abhängigkeiten zusammenhängt, nicht mit den App-Klassen selbst.
Ich gehe davon aus, dass das Problem das Scannen von Klassenpfaden ist, bin mir aber nicht sicher, wie:
- Bestätigen Sie, dass dies das Problem ist (dh wie Sie Spring Boot "debuggen").
- Wenn es wirklich die Ursache ist, wie kann ich es begrenzen, damit es schneller wird? Wenn ich zum Beispiel weiß, dass eine Abhängigkeit oder ein Paket nichts enthält, was Spring scannen sollte, gibt es eine Möglichkeit, dies einzuschränken?
Ich gehe davon aus, dass die Erweiterung von Spring auf eine parallele Bean-Initialisierung während des Startvorgangs die Dinge beschleunigen würde, aber diese Erweiterungsanforderung ist seit 2011 ohne Fortschritte geöffnet. Ich sehe einige andere Bemühungen in Spring Boot selbst, wie z. B. die Verbesserung der Geschwindigkeit von Tomcat JarScanning untersuchen , aber das ist Tomcat-spezifisch und wurde aufgegeben.
Dieser Beitrag:
Obwohl auf Integrationstests ausgerichtet, schlägt die Verwendung vor lazy-init=true
, aber ich weiß nicht, wie ich dies auf alle Beans in Spring Boot unter Verwendung der Java-Konfiguration anwenden soll - irgendwelche Hinweise hier?
Alle (anderen) Vorschläge wären willkommen.
quelle
@ComponentScan
, werden diese ebenfalls gescannt. Eine andere Sache ist, sicherzustellen, dass Sie die Debug- oder Trace-Protokollierung nicht aktiviert haben, da die Protokollierung im Allgemeinen langsam, sehr langsam ist.Antworten:
Spring Boot führt viele automatische Konfigurationen durch, die möglicherweise nicht benötigt werden. Daher möchten Sie möglicherweise nur die für Ihre App erforderliche automatische Konfiguration eingrenzen. Um die vollständige Liste der enthaltenen automatischen Konfigurationen anzuzeigen, führen Sie einfach die Protokollierung
org.springframework.boot.autoconfigure
im DEBUG-Modus (logging.level.org.springframework.boot.autoconfigure=DEBUG
inapplication.properties
) aus. Eine weitere Option ist das Ausführen der Spring Boot-Anwendung mit der folgenden--debug
Option:java -jar myproject-0.0.1-SNAPSHOT.jar --debug
Es würde so etwas in der Ausgabe geben:
Überprüfen Sie diese Liste und geben Sie nur die erforderlichen Autokonfigurationen an:
Code wurde aus diesem Blog-Beitrag kopiert .
quelle
Die bisher am häufigsten gewählte Antwort ist nicht falsch, geht aber nicht in die Tiefe, die ich gerne sehe, und liefert keine wissenschaftlichen Beweise. Das Spring Boot-Team hat eine Übung zur Verkürzung der Startzeit für Boot 2.0 durchgeführt, und Ticket 11226 enthält viele nützliche Informationen. Es gibt auch ein Ticket 7939, das zum Hinzufügen von Zeitinformationen zur Zustandsbewertung geöffnet ist, aber es scheint keine spezifische ETA zu haben.
Der nützlichste und methodischste Ansatz zum Debuggen des Boot-Starts wurde von Dave Syer durchgeführt. https://github.com/dsyer/spring-boot-startup-bench
Ich hatte auch einen ähnlichen Anwendungsfall, also nahm ich Daves Ansatz des Mikro-Benchmarking mit JMH und lief damit. Das Ergebnis ist das Boot-Benchmark- Projekt. Ich habe es so konzipiert, dass es zum Messen der Startzeit für jede Spring Boot-Anwendung verwendet werden kann, indem das ausführbare JAR verwendet wird, das von der Gradle-Task
bootJar
(zuvorbootRepackage
in Boot 1.5 genannt) erstellt wurde. Fühlen Sie sich frei, es zu verwenden und Feedback zu geben.Meine Ergebnisse sind wie folgt:
-XX:TieredStopAtLevel=1
würde wahrscheinlich Ihre erste Anfrage verlangsamen.quelle
minimal
oder kann das Glas einfach geliefert werden? Ich habe versucht, das erstere zu tun, bin aber nicht weit gekommen.-Xverify:none
in der Produktion, da dies die Codeüberprüfung unterbricht und Sie auf Probleme stoßen können.-XX:TieredStopAtLevel=1
ist in Ordnung, wenn Sie eine Anwendung für eine kurze Dauer (einige Sekunden) ausführen, da sie sonst weniger produktiv ist, da die JVM über einen längeren Zeitraum optimiert wird.Use of -Xverify:none is unsupported.
was es bedeutet.Spring Boot 2.2.M1 hat eine Funktion hinzugefügt, die die verzögerte Initialisierung in Spring Boot unterstützt.
Wenn ein Anwendungskontext aktualisiert wird, wird standardmäßig jede Bean im Kontext erstellt und ihre Abhängigkeiten eingefügt. Im Gegensatz dazu wird eine Bean-Definition, die so konfiguriert ist, dass sie träge initialisiert wird, nicht erstellt und ihre Abhängigkeiten werden erst eingefügt, wenn sie benötigt werden.
Aktivieren Verzögerte Initialisierung Set
spring.main.lazy-initialization
zu wahrenWann die verzögerte Initialisierung aktiviert werden kann Die verzögerte Initialisierung kann die Startzeit erheblich verbessern, es gibt jedoch auch einige bemerkenswerte Nachteile, und es ist wichtig, sie sorgfältig zu aktivieren
Weitere Informationen finden Sie in Doc
quelle
Wie in dieser Frage / Antwort beschrieben, ist es meiner Meinung nach der beste Ansatz, anstatt nur diejenigen hinzuzufügen, die Sie für nötig halten, die Abhängigkeiten auszuschließen, von denen Sie wissen, dass Sie sie nicht benötigen.
Siehe: Startzeit des Spring Boot minimieren
Zusammenfassend:
Sie können sehen, was unter der Decke vor sich geht, und die Debug-Protokollierung aktivieren, indem Sie einfach --debug angeben, wenn Sie die Anwendung über die Befehlszeile starten. Sie können debug = true auch in Ihrer application.properties angeben.
Sie können die Protokollierungsstufe in application.properties auch so einfach festlegen wie:
logging.level.org.springframework.web: DEBUG logging.level.org.hibernate: ERROR
Wenn Sie ein automatisch konfiguriertes Modul erkennen, das Sie nicht möchten, kann es deaktiviert werden. Die Dokumente dazu finden Sie hier: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration
Ein Beispiel würde aussehen wie:
quelle
Nun, es gibt eine vollständige Liste möglicher Aktionen, die hier beschrieben werden: https://spring.io/blog/2018/12/12/how-fast-is-spring
Ich werde die wichtigsten Noten von der Frühlingsseite setzen (ein wenig angepasst):
spring.config.location
(Befehlszeilenargument oder Systemeigenschaft usw.). Beispiel zum Testen in IDE :spring.config.location=file://./src/main/resources/application.properties
.spring.jmx.enabled=false
(dies ist die Standardeinstellung in Spring Boot 2.2).spring.main.lazy-initialization=true
In Spring Boot 2.2 gibt es eine neue Flagge (LazyInitBeanFactoryPostProcessor
für ältere Spring verwenden).-noverify
. Berücksichtigen Sie auch-XX:TieredStopAtLevel=1
(dies verlangsamt die JIT später auf Kosten der gespeicherten Startzeit).Die genannten
LazyInitBeanFactoryPostProcessor
(Sie können es für Spring 1.5 verwenden, wenn Sie dasspring.main.lazy-initialization=true
ab Spring 2.2 verfügbare Flag nicht anwenden können ):Sie können auch etwas verwenden (oder Ihr eigenes schreiben - es ist einfach), um die Initialisierungszeit von Beans zu analysieren: https://github.com/lwaddicor/spring-startup-analysis
Ich hoffe es hilft!
quelle
In meinem Fall gab es zu viele Haltepunkte. Als ich auf "Haltepunkte stumm schalten" klickte und die Anwendung im Debug-Modus neu startete, wurde die Anwendung zehnmal schneller gestartet.
quelle
Wenn Sie versuchen, die Entwicklungsabwicklung für manuelle Tests zu optimieren, empfehle ich dringend die Verwendung von devtools .
Einfach neu kompilieren - und der Server startet sich selbst neu (für Groovy müssen Sie nur die Quelldatei aktualisieren). Wenn Sie eine IDE verwenden (z. B. 'vscode'), werden Ihre Java-Dateien möglicherweise automatisch kompiliert. Wenn Sie also nur eine Java-Datei speichern, kann indirekt ein Neustart des Servers eingeleitet werden - und Java wird in dieser Hinsicht genauso nahtlos wie Groovy.
Das Schöne an diesem Ansatz ist, dass der inkrementelle Neustart einige der Startschritte von Grund auf kurzschließt - so dass Ihr Dienst viel schneller wieder betriebsbereit ist!
Leider hilft dies nicht bei Startzeiten für die Bereitstellung oder automatisierten Komponententests.
quelle
WARNUNG: Wenn Sie Hibernate DDL nicht für die automatische Generierung von DB-Schemas verwenden und keinen L2-Cache verwenden, gilt diese Antwort NICHT für Sie. Scrollen Sie weiter.
Mein Ergebnis ist, dass der Ruhezustand den Start der Anwendung erheblich verlängert. Das Deaktivieren der L2-Cache- und Datenbankinitialisierung führt zu einem schnelleren Start der Spring Boot-App. Lassen Sie den Cache für die Produktion eingeschaltet und deaktivieren Sie ihn für Ihre Entwicklungsumgebung.
application.yml:
Testergebnisse:
L2-Cache ist eingeschaltet und
ddl-auto: update
L2 Cache ist AUS und
ddl-auto: none
Jetzt frage ich mich, was ich mit all dieser Freizeit anfangen soll
quelle
Ich finde es seltsam, dass noch niemand diese Optimierungen vorgeschlagen hat. Hier sind einige allgemeine Tipps zur Optimierung der Projekterstellung und des Starts bei der Entwicklung:
WARNHINWEISE
quelle
Für mich klingt es so, als würden Sie eine falsche Konfigurationseinstellung verwenden. Überprüfen Sie zunächst myContainer und mögliche Konflikte. Um festzustellen, wer die meisten Ressourcen verwendet, müssen Sie die Speicherzuordnungen (siehe Datenmenge!) Für jede Abhängigkeit gleichzeitig überprüfen - und das nimmt auch viel Zeit in Anspruch ... (und SUDO-Berechtigungen). Übrigens: Testen Sie den Code normalerweise anhand der Abhängigkeiten?
quelle