Lazy Initialisierung in Spring Boot 2.2


Von einem Übersetzer: Da das Spring Framework eines der wichtigsten Frameworks ist, auf denen wir CUBA aufbauen, bleiben Nachrichten über neue Spring-Funktionen für uns nicht unbemerkt. Eine verzögerte Initialisierung ist eine Möglichkeit, die erste Startzeit der Anwendung zu verkürzen, was in unserer Zeit der weit verbreiteten Verwendung von Microservices eine wichtige Messgröße ist. Für diejenigen, die lieber Videos lesen möchten, gibt es eine 10-minütige Präsentation von Josh Long zum Thema des Artikels.


Die kürzlich angekündigte erste Meilensteinversion von Spring Boot 2.2 bietet Unterstützung für die verzögerte Initialisierung. In diesem Artikel werden wir uns neue Funktionen ansehen und erklären, wie sie aktiviert werden.


Was bedeutet es, faul zu sein?


Das Spring Framework unterstützt die verzögerte Initialisierung, seit sein Quellcode vor elf Jahren auf Git umgestellt wurde. Wenn der Anwendungskontext aktualisiert wird, wird standardmäßig jede Bean neu erstellt und ihre Abhängigkeiten implementiert. Wenn ein Bin dagegen für die verzögerte Initialisierung konfiguriert ist, wird er nicht erstellt und seine Abhängigkeiten werden erst dann gelöscht, wenn dies erforderlich ist.


Aktivieren der verzögerten Initialisierung


In jeder Version von Spring Boot ist es möglich, die verzögerte Initialisierung zu aktivieren, wenn es Ihnen nichts ausmacht, sich mit BeanFactoryPostProcessor die Hände schmutzig zu BeanFactoryPostProcessor . Spring Boot 2.2 vereinfacht diesen Prozess einfach durch die Einführung einer neuen Eigenschaft - spring.main.lazy-initialization (es gibt auch äquivalente Methoden in SpringApplication und SpringApplicationBuilder ). Wenn diese Eigenschaft auf true , werden Application Beans für die verzögerte Initialisierung konfiguriert.


Die Vorteile einer verzögerten Initialisierung


Eine verzögerte Initialisierung kann die Startzeit Ihrer Anwendung erheblich verkürzen, da zu diesem Zeitpunkt weniger Klassen geladen und weniger Bins erstellt werden. Beispielsweise startet eine kleine Webanwendung, die Actuator und Spring Security verwendet, normalerweise 2,5 Sekunden. Bei verzögerter Initialisierung dauert dieser Vorgang 2 Sekunden. Die genauen Beschleunigungswerte variieren von Anwendung zu Anwendung, abhängig von der Struktur des Abhängigkeitsgraphen des Behälters.


Anmerkung des Übersetzers: Ich habe dieses Beispiel ausgeführt und Spring Boot 2.2 in den Abhängigkeiten geschrieben. Die Startzeit mit verzögerter Initialisierung betrug 3 Sekunden und ohne diese 4. Ich denke, dass bei schwerwiegenderen Anwendungen die Startzeit aufgrund der Verwendung der verzögerten Initialisierung erheblich verlängert wird wir werden nicht sehen. Aktualisieren: Auf Anraten von alek_sys wurde die Validierung und Aktualisierung des Datenbankschemas deaktiviert und die verzögerte JPA-Initialisierung für beide Fälle Started WebApplication in... Es stellte sich heraus, dass 2,7 und 3,7 Sekunden vor der Started WebApplication in...


Was ist mit DevTools?


Spring Boot DevTools bietet eine erhebliche Entwicklungsbeschleunigung. Anstatt die JVM und die Anwendung jedes Mal neu zu starten, wenn Sie etwas ändern, führen DevTools einen „Hot-Neustart“ der Anwendung in derselben JVM durch. Ein wesentlicher Vorteil eines solchen Neustarts besteht darin, dass JIT die Möglichkeit hat, den Code zu optimieren, der beim Start der Anwendung ausgeführt wird. Nach mehreren Neustarts verringert sich die Anfangszeit von 2,5 Sekunden um fast 80% auf 500 ms. Mit der verzögerten Initialisierung sind die Dinge noch besser. Durch Festlegen der Eigenschaft spring.main.lazy-initialization wird die Neustartzeit direkt in der IDE gleich 400 ms spring.main.lazy-initialization .


Die Kehrseite der faulen Initialisierung


Wie oben gezeigt, kann die Einbeziehung der verzögerten Initialisierung die Startzeit der Anwendung erheblich verkürzen. Und vielleicht haben Sie den unwiderstehlichen Wunsch, dies ständig zu verwenden, oder Sie werden sich zumindest fragen, warum die verzögerte Initialisierung nicht standardmäßig aktiviert ist. Es gibt mehrere mögliche negative Auswirkungen, die am besten sofort geklärt werden können.


Die Tatsache, dass Klassen nicht geladen und Bins erst erstellt werden, wenn sie benötigt werden, kann Probleme maskieren, die möglicherweise bereits beim Start der Anwendung erkannt wurden. Dies kann beispielsweise das Fehlen der erforderlichen Klasse, ein Speicherüberlauf oder ein Fehler sein, der mit der falschen Konfiguration verbunden ist.


In Webanwendungen können verzögerte Konfigurationen die Latenz von HTTP-Anforderungen erhöhen, die eine Bin-Initialisierung verursachen. Dies ist normalerweise die erste Anforderung, es können jedoch zusätzliche unerwünschte Auswirkungen auf den Lastausgleich oder die automatische Skalierung auftreten.


Ist das Ding enthalten?


Wenn Sie nicht sicher sind, wie genau sich die verzögerte Initialisierung auf Ihre Anwendung auswirkt, oder wenn Sie überprüfen möchten, ob andere Aspekte des Frameworks für Sie geeignet sind und das tun, was Sie benötigen, ist es hilfreich, einen Debugger zu verwenden. Durch Festlegen eines Haltepunkts im Bin-Konstruktor können Sie sehen, zu welchem ​​genauen Zeitpunkt der Bin initialisiert wird. In einer in Spring Boot geschriebenen Webanwendung mit aktivierter verzögerter Initialisierung können Sie beispielsweise sehen, dass mit @Controller Annotation gekennzeichnete @Controller erst bei der ersten Anforderung an DispatcerServlet Spring MVC oder an DispatchHandler Spring WebFlux erstellt werden.


Wann muss die verzögerte Initialisierung aktiviert werden?


Wie wir oben gesehen haben, bietet die verzögerte Initialisierung beim Start der Anwendung bemerkenswerte Verbesserungen, es gibt jedoch auch Nachteile. Daher müssen Sie diese Funktion sehr sorgfältig verwenden.


Ein Bereich, in dem sich eine verzögerte Initialisierung auszahlen kann (fast ohne Overhead), ist der Anwendungsentwicklungsprozess. Während Sie eine Anwendung schreiben, können Sie durch die reduzierte Neustartzeit, die durch die verzögerte Initialisierung in Kombination mit DevTools bereitgestellt wird, viel Zeit sparen.


Wo sonst können Sie die Vorteile der verzögerten Initialisierung nutzen - dies erfolgt in Integrationstests. Möglicherweise verwenden Sie bereits "Slicing" -Tests , um die Ausführungszeit zu verkürzen, indem Sie die Anzahl der initialisierten Beans in einigen Testtypen begrenzen. Die verzögerte Initialisierung bietet eine alternative Möglichkeit, das gleiche Ergebnis zu erzielen. Wenn Sie in der falschen Position sind, um die Struktur der Anwendung für "Slicing" -Tests zu ändern, oder wenn es für Ihre spezifischen Tests kein geeignetes "Slicing" gibt, wird durch die Einbeziehung der verzögerten Initialisierung die Anzahl der Bins auf diejenigen begrenzt, die nur in Ihrem Test verwendet werden. Dies reduziert die Testausführungszeit, insbesondere wenn sie während der Entwicklung in einer isolierten Umgebung ausgeführt werden.


Aktivieren Sie zuletzt die verzögerte Initialisierung auf dem Produkt. Und wenn Sie sich dazu entschließen, tun Sie dies mit Vorsicht. Bei Webanwendungen kann sich der Containermanager auf den Einstiegspunkt /health , der normalerweise relativ schnell reagiert. Beachten Sie jedoch, dass die ersten Aufrufe möglicherweise länger als gewöhnlich dauern können. Sie müssen sich auch die der JVM zugewiesene Speichergröße merken, damit bei der Initialisierung aller Komponenten kein Überlauf auftritt.

Source: https://habr.com/ru/post/de445592/


All Articles