web-dev-qa-db-ja.com

Spring Bootの起動時間を短縮

Spring Bootアプリケーションがあります。たくさんの依存関係を追加しました(残念ながら、私はそれらすべてを必要としているように見えます)。起動時間はかなり長くなりました。 SpringApplication.run(source, args)を実行するだけで10秒かかります。

これは「使用」されているものと比較してもそれほど多くないかもしれませんが、それがかかるのは不幸です。これは主に開発フローを中断するためです。この時点ではアプリケーション自体はかなり小さいので、ほとんどの場合、アプリクラス自体ではなく、追加された依存関係に関連していると思います。

問題はクラスパススキャンであると思いますが、次の方法がわかりません。

  • それが問題であることを確認します(つまり、Spring Bootを「デバッグ」する方法)
  • それが本当に原因である場合、どうすればそれを制限できますか?たとえば、依存関係またはパッケージにSpringがスキャンすべきものが含まれていないことがわかっている場合、それを制限する方法はありますか?

Springを起動して起動時に並列Beanの初期化を行う で速度が上がると思いますが、2011年以降、機能拡張のリクエストは何の進展もなく開かれています。 Tomcat JarScanning速度の改善を調査する など、Spring Boot自体に他の取り組みが見られますが、これはTomcat固有であり、放棄されています。

この記事:

統合テストを目的としていますが、lazy-init=trueの使用をお勧めしますが、Java構成を使用してSpring BootのすべてのBeanにこれを適用する方法がわかりません。

(その他の)提案は歓迎します。

83
steady rain

Spring Bootは、必要ではないかもしれない多くの自動設定を行います。そのため、アプリに必要な自動構成のみを絞り込むことができます。自動構成の完全なリストを表示するには、デバッグモードでorg.springframework.boot.autoconfigurelogging.level.org.springframework.boot.autoconfigure=DEBUGapplication.properties)のログを実行するだけです。別のオプションは、スプリングブートアプリケーションを--debugオプションで実行することです:Java -jar myproject-0.0.1-SNAPSHOT.jar --debug

出力には次のようなものがあります。

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

このリストを調べて、必要な自動構成のみを含めます。

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

コードは このブログ投稿 からコピーされました。

51
luboskrnac

これまでで最も投票された答えは間違っていませんが、私が見たいと思う深さには入らず、科学的な証拠を提供していません。 Spring Bootチームは、Boot 2.0の起動時間を短縮するための演習を行いました。チケット 11226 には多くの有用な情報が含まれています。チケットもあります 7939 条件評価にタイミング情報を追加できますが、特定のETAがないようです。

ブートスタートアップをデバッグするための最も便利で系統的なアプローチは、Dave Syerによって行われました。 https://github.com/dsyer/spring-boot-startup-bench

私も同様のユースケースを持っていたので、JMHでマイクロベンチマークのDaveのアプローチを取り、それで実行しました。結果は boot-benchmark プロジェクトです。 bootJar(Boot 1.5では以前bootRepackageと呼ばれていた)Gradleタスクによって生成された実行可能jarを使用して、Spring Bootアプリケーションの起動時間を測定できるように設計しました。気軽に使用してフィードバックをお寄せください。

私の調査結果は次のとおりです。

  1. CPUが重要です。たくさん。
  2. -Xverify:none でJVMを起動すると、非常に役立ちます。
  3. 不要な自動構成を除外すると役立ちます。
  4. DaveはJVM引数 -XX:TieredStopAtLevel = 1 を推奨しましたが、私のテストではそれによる大きな改善は見られませんでした。また、-XX:TieredStopAtLevel=1はおそらく最初の要求を遅くします。
  5. ホスト名の解決が遅い reports がありましたが、テストしたアプリの問題ではないことがわかりました。
28
Abhijit Sarkar

この質問/回答で説明されているように、必要だと思うものだけを追加するのではなく、不要だとわかっている依存関係を除外するのが最善のアプローチだと思います。

参照: Minimise Spring Boot Startup Time

要約すれば:

カバーの下で何が行われているのかを確認し、コマンドラインからアプリケーションを起動するときに--debugを指定するだけでデバッグロギングを有効にできます。 application.propertiesでdebug = trueを指定することもできます。

また、application.propertiesのログレベルを次のように簡単に設定できます。

logging.level.org.springframework.web:DEBUG logging.level.org.hibernate:エラー

不要な自動構成モジュールを検出した場合は、無効にすることができます。これに関するドキュメントはここにあります: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration

例は次のようになります。

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

Spring Boot 2.2.M1は、Spring BootでLazy Initializationをサポートする機能を追加しました。

デフォルトでは、アプリケーションコンテキストが更新されると、コンテキスト内のすべてのBeanが作成され、その依存関係が注入されます。対照的に、Bean定義が遅延初期化されるように構成されている場合、Bean定義は作成されず、その依存関係は必要になるまで注入されません。

遅延初期化の有効化spring.main.lazy-initializationtrueに設定

詳細については、 Doc を確認してください。

5
Niraj Sonawane

手動テストのために開発のターンアラウンドを最適化しようとしている場合、 devtools の使用を強くお勧めします。

Spring-boot-devtoolsを使用するアプリケーションは、クラスパス上のファイルが変更されるたびに自動的に再起動します。

再コンパイルするだけで、サーバーは自動的に再起動します(Groovyの場合は、ソースファイルを更新するだけです)。 IDE(例: 'vscode')を使用している場合、Javaファイルを自動的にコンパイルするため、Javaファイルを保存するだけでサーバーを起動できます。間接的に再起動し、Javaはこの点でGroovyと同じくらいシームレスになります。

このアプローチの利点は、インクリメンタルリスタートがゼロからの起動ステップの一部を短絡させることです-そのため、サービスがより迅速にバックアップされ実行されます!


残念ながら、これは展開または自動化された単体テストの起動時間には役立ちません。

0
nobar