web-dev-qa-db-fra.com

Accélérer le démarrage de Spring Spring

J'ai une application Spring Boot. J'ai ajouté beaucoup de dépendances (malheureusement, il me faut toutes les apparences) et le temps de démarrage a pas mal augmenté. Il suffit de 10 secondes pour faire SpringApplication.run(source, args)

Bien que cela ne soit peut-être pas beaucoup comparé à ce qui est "habitué", je suis malheureux que cela prenne autant, surtout parce que cela interrompt le flux de développement. L'application elle-même est plutôt petite à ce stade. Je suppose donc que la plupart du temps est liée aux dépendances ajoutées, pas aux classes d'application elles-mêmes.

Je suppose que le problème est le balayage de classpath, mais je ne sais pas comment:

  • Confirmez le problème (par exemple, comment "déboguer" Spring Boot)
  • Si c'est vraiment la cause, comment puis-je la limiter pour que cela devienne plus rapide? Par exemple, si je sais qu’une dépendance ou un package ne contient aucun élément que Spring devrait analyser, existe-t-il un moyen de le limiter? 

Je suppose ceci:

accélérerait les choses, mais ce n'est même pas trié à ce stade. Je vois d'autres efforts dans Spring Boot lui-même, par exemple:

mais cela semble spécifique à Tomcat.

Cet article:

bien que visant à des tests d'intégration, suggère d'utiliser lazy-init=true, cependant, je ne sais pas comment appliquer cela à tous les beans de Spring Boot en utilisant la configuration Java - des pointeurs ici?

Toute suggestion (autre) serait la bienvenue.

58
steady rain

Spring Boot effectue une grande partie de la configuration automatique qui peut ne pas être nécessaire. Vous voudrez peut-être limiter uniquement la configuration automatique nécessaire à votre application. Pour voir la liste complète de la configuration automatique incluse, il suffit de lancer la journalisation de org.springframework.boot.autoconfigure en mode DEBUG (logging.level.org.springframework.boot.autoconfigure=DEBUG dans application.properties). Une autre option consiste à exécuter l’application Spring Boot avec l’option --debug: Java -jar myproject-0.0.1-SNAPSHOT.jar --debug 

Il y aurait quelque chose comme ça en sortie:

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

Examinez cette liste et n'incluez que les configurations automatiques dont vous avez besoin:

@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 {

Le code a été copié à partir de cet article de blog .

36
luboskrnac

La réponse la plus votée à ce jour n’est pas fausse, mais elle n’entre pas dans la profondeur que j’aime voir et ne fournit aucune preuve scientifique. L’équipe Spring Boot a effectué un exercice visant à réduire le temps de démarrage de Boot 2.0. Le ticket 11226 contient de nombreuses informations utiles. Il existe également un ticket 7939 ouvert à l’ajout d’informations de synchronisation pour l’évaluation de condition, mais il ne semble pas avoir d’ETA spécifique.

L'approche la plus utile et la plus méthodique pour le débogage Le démarrage du démarrage a été effectué par Dave Syer. https://github.com/dsyer/spring-boot-startup-bench

J'avais aussi un cas d'utilisation similaire, alors j'ai adopté l'approche de Dave en matière de micro-analyse comparative avec JMH et je l'ai utilisée. Le résultat est le boot-benchmark project. Je l'ai conçue de telle sorte qu'elle puisse être utilisée pour mesurer le temps de démarrage de n'importe quelle application Spring Boot, à l'aide du fichier jar exécutable généré par bootJar (précédemment appelée bootRepackage dans Boot 1.5). N'hésitez pas à l'utiliser et à donner votre avis.

Mes conclusions sont les suivantes:

  1. La CPU compte. Beaucoup. 
  2. Le démarrage de la machine virtuelle avec -Xverify: none aide considérablement.
  3. L'exclusion des configurations automatiques inutiles aide.
  4. Dave a recommandé l'argument JVM -XX: TieredStopAtLevel = 1 , mais mes tests n'ont pas montré d'amélioration significative avec cela. De plus, -XX:TieredStopAtLevel=1 ralentirait probablement votre première demande.
  5. Il y a eu rapports de la résolution lente du nom d'hôte, mais je n'ai pas trouvé que c'était un problème pour les applications que j'ai testées.
14
Abhijit Sarkar

Comme décrit dans cette question/réponse, je pense que la meilleure approche consiste à exclure les dépendances dont vous savez que vous n’avez pas besoin, au lieu d’ajouter uniquement celles dont vous pensez avoir besoin.

Voir: Minimize Spring Boot Startup Time

En résumé:

Vous pouvez voir ce qui se passe sous les couvertures et activer la journalisation de débogage aussi simple que de spécifier --debug lors du démarrage de l'application à partir de la ligne de commande. Vous pouvez également spécifier debug = true dans votre application.properties.

En outre, vous pouvez définir le niveau de journalisation dans application.properties aussi simplement que:

logging.level.org.springframework.web: DEBUG logging.level.org.hibernate: ERREUR

Si vous détectez un module auto-configuré que vous ne voulez pas, vous pouvez le désactiver. Les docs pour ceci peuvent être trouvés ici: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration

Un exemple ressemblerait à ceci:

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

Spring Boot 2.2.M1 a ajouté une fonctionnalité permettant de prendre en charge l’initialisation différée dans Spring Boot.

Par défaut, lorsqu'un contexte d'application est actualisé, chaque bean du contexte est créé et ses dépendances sont injectées. En revanche, quand une définition de bean est configurée pour être initialisée paresseusement, elle ne sera pas créée et ses dépendances ne seront pas injectées avant d’être utilisées.

Activation de l'initialisation différée Définissez spring.main.lazy-initialization sur true

Pour plus de détails, veuillez vérifier Doc

4
Niraj Sonawane

Si vous essayez d'optimiser les délais de développement pour les tests manuels, je vous recommande vivement d'utiliser devtools .

Les applications qui utilisent spring-boot-devtools vont automatiquement redémarrer chaque fois que les fichiers du classpath changent.

Recompilez simplement - et le serveur redémarrera tout seul (pour Groovy, il vous suffit de mettre à jour le fichier source). si vous utilisez un IDE (par exemple, 'vscode'), il peut compiler automatiquement vos fichiers Java. Il suffit donc de sauvegarder un fichier Java pour déclencher un redémarrage du serveur, indirectement - et Java devient aussi transparent que Groovy Ceci concerne.

La beauté de cette approche réside dans le fait que le redémarrage incrémentiel court-circuite certaines des étapes de démarrage à partir de zéro - votre service sera donc de nouveau opérationnel plus rapidement!


Malheureusement, cela n’aide en rien les délais de démarrage du déploiement ou des tests unitaires automatisés.

0
nobar