it-swarm.com.de

Beschleunigen Sie die Startzeit von Spring Boot

Ich habe eine Spring Boot-Anwendung. Ich habe viele Abhängigkeiten hinzugefügt (leider sieht es so aus, als ob ich alle brauche) und die Startzeit ist ziemlich viel länger geworden. Das Ausführen einer SpringApplication.run(source, args) dauert 10 Sekunden. 

Das mag zwar nicht viel im Vergleich zu dem sein, was "gewohnt" ist, aber ich bin unglücklich, dass es so viel kostet, hauptsächlich weil es den Entwicklungsfluss bricht. 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 und nicht mit den App-Klassen.

Ich gehe davon aus, dass das Problem das Scannen von Klassenpfaden ist, aber ich bin mir nicht sicher, wie man:

  • Bestätigen Sie, dass dies das Problem ist (d. H. 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, das Spring scannen sollte, gibt es eine Möglichkeit, dies einzuschränken? 

Ich gehe davon aus:

würde die Dinge beschleunigen, aber es ist an diesem Punkt nicht einmal triaged. Ich sehe einige andere Anstrengungen in Spring Boot selbst, z.

aber das sieht Tomcat-spezifisch aus.

Dieser Beitrag:

obwohl dies auf Integrationstests abzielt, schlägt lazy-init=true vor. Ich weiß jedoch nicht, wie ich dies auf alle Beans in Spring Boot mithilfe der Java-Konfiguration anwenden kann.

Alle (anderen) Vorschläge wären willkommen.

58
steady rain

Spring Boot führt viele Autokonfigurationen durch, die möglicherweise nicht benötigt werden. Möglicherweise möchten Sie nur die für Ihre App erforderliche Autokonfiguration eingrenzen. Um die vollständige Liste der automatischen Konfiguration anzuzeigen, führen Sie einfach die Protokollierung von org.springframework.boot.autoconfigure im DEBUG-Modus aus (logging.level.org.springframework.boot.autoconfigure=DEBUG in application.properties). Eine weitere Option ist, die Spring Boot-Anwendung mit der --debug-Option auszuführen: Java -jar myproject-0.0.1-SNAPSHOT.jar --debug 

Es würde so etwas in der Ausgabe geben:

=========================
AUTO-CONFIGURATION REPORT
=========================

Überprüfen Sie diese Liste und fügen Sie nur die erforderlichen Autokonfigurationen hinzu:

@Configuration
@Import({
        DispatcherServletAutoConfiguration.class,
        EmbeddedServletContainerAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        JacksonAutoConfiguration.class,
        ServerPropertiesAutoConfiguration.class,
        PropertyPlaceholderAutoConfiguration.class,
        ThymeleafAutoConfiguration.class,
        WebMvcAutoConfiguration.class,
        WebSocketAutoConfiguration.class,
})
public class SampleWebUiApplication {

Code wurde aus diesem Blogbeitrag kopiert.

36
luboskrnac

Die am meisten gewählte Antwort ist bisher nicht falsch, geht aber nicht in die Tiefe, die ich gerne sehe, und liefert keine wissenschaftlichen Beweise. Das Spring Boot-Team hat eine Übung durchlaufen, um die Startzeit für Boot 2.0 zu verkürzen. Ticket 11226 enthält viele nützliche Informationen. Es gibt auch ein Ticket 7939 , über das Sie Timing-Informationen zur Zustandsbewertung hinzufügen können, aber es scheint keine spezifische ETA zu geben.

Der nützlichste und methodischste Ansatz für das Debuggen beim Boot-Start wurde von Dave Syer ausgeführt. https://github.com/dsyer/spring-boot-startup-bench

Ich hatte auch einen ähnlichen Anwendungsfall, also nahm ich Daves Ansatz des Micro-Benchmarking mit JMH und lief damit. Das Ergebnis ist das Boot-Benchmark Projekt. Ich habe es so entworfen, dass es verwendet werden kann, um die Startzeit für jede Spring-Boot-Anwendung zu messen, wobei die ausführbare jar verwendet wird, die von bootJar (zuvor in Boot 1.5 bootRepackage) als Taskle-Task bezeichnet wird. Fühlen Sie sich frei, es zu verwenden und geben Sie Feedback.

Meine Erkenntnisse lauten wie folgt:

  1. CPU ist wichtig. Viel. 
  2. Das Starten der JVM mit -Xverify: none hilft erheblich.
  3. Das Ausschließen unnötiger Autokonfigurationen hilft.
  4. Dave empfahl das JVM-Argument -XX: TieredStopAtLevel = 1 , aber meine Tests zeigten keine signifikante Verbesserung. Außerdem würde -XX:TieredStopAtLevel=1 wahrscheinlich Ihre erste Anfrage verlangsamen.
  5. Es gab Berichte , dass die Auflösung des Hostnamens langsam war, aber ich fand es für die von mir getesteten Apps nicht problematisch.
14
Abhijit Sarkar

Wie in dieser Frage/Antwort beschrieben, denke ich, der beste Ansatz besteht darin, nicht nur diejenigen hinzuzufügen, die Sie für notwendig erachten, sondern die Abhängigkeiten auszuschließen, von denen Sie wissen, dass Sie sie nicht benötigen.

Siehe: Spring Startup Time minimieren

In Summe:

Sie können unter den Covers sehen, was los ist, und die Debug-Protokollierung aktivieren, indem Sie einfach --debug angeben, wenn Sie die Anwendung über die Befehlszeile starten. Sie können in Ihrer application.properties auch debug = true angeben.

Sie können den Protokolliergrad in application.properties auch so einfach festlegen:

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 so aussehen:

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
6
pczeus

Spring Boot 2.2.M1 unterstützt jetzt Lazy Initialization in Spring Boot.

Standardmäßig wird beim Aktualisieren eines Anwendungskontexts jede Bean im Kontext erstellt und ihre Abhängigkeiten werden injiziert. Wenn dagegen eine Bean-Definition so konfiguriert ist, dass sie verzögert initialisiert wird, wird sie nicht erstellt und ihre Abhängigkeiten werden erst dann injiziert, wenn sie benötigt wird.

Lazy Initialization aktivieren spring.main.lazy-initialization auf true setzen

Für weitere Informationen überprüfen Sie bitte Doc

4
Niraj Sonawane

Wenn Sie versuchen, die Entwicklungszeit für manuelle Tests zu optimieren, empfehle ich dringend die Verwendung von devtools .

Anwendungen, die Spring-Boot-Devtools verwenden, werden automatisch neu gestartet Immer wenn sich Dateien im Klassenpfad ändern.

Kompilieren Sie einfach - und der Server wird neu gestartet (für Groovy müssen Sie nur die Quelldatei aktualisieren). Wenn Sie eine IDE (z. B. 'vscode') verwenden, werden Ihre Java-Dateien möglicherweise automatisch kompiliert. Durch das Speichern einer Java-Datei kann ein Server-Neustart indirekt initiiert werden - und Java wird genauso nahtlos wie Groovy dieser Hinsicht.

Die Besonderheit dieses Ansatzes besteht darin, dass der inkrementelle Neustart einige der Startschritte von Grund auf kurzschließt - so dass Ihr Dienst schneller wieder einsatzbereit ist!


Leider hilft dies nicht bei Startzeiten für die Bereitstellung oder automatisierten Komponententests.

0
nobar