Spring Bootアプリケーションのシャットダウン
1. 概要
Spring Boot Applicationのライフサイクルを管理することは、本番環境のシステムにとって非常に重要です。 Springコンテナは、ApplicationContext.を使用して、すべてのBeanの作成、初期化、および破棄を処理します。
この記事の強調点は、ライフサイクルの破壊段階です。 具体的には、SpringBootアプリケーションをシャットダウンするさまざまな方法を見ていきます。
Spring Bootを使用してプロジェクトをセットアップする方法の詳細については、Spring Boot Starterの記事を確認するか、Spring Boot Configurationを確認してください。
2. シャットダウンエンドポイント
デフォルトでは、/shutdownを除くすべてのエンドポイントがSpring BootApplicationで有効になっています。これは当然、Actuatorエンドポイントの一部です。
これらを設定するためのMavenの依存関係は次のとおりです。
org.springframework.boot
spring-boot-starter-actuator
また、セキュリティサポートも設定する場合は、次のものが必要です。
org.springframework.boot
spring-boot-starter-security
最後に、application.propertiesファイルでシャットダウンエンドポイントを有効にします。
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true
使用するアクチュエータエンドポイントも公開する必要があることに注意してください。 上記の例では、/shutdownエンドポイントを含むすべてのアクチュエータエンドポイントを公開しました。
To shut down the Spring Boot application, we simply call a POST method like this:
curl -X POST localhost:port/actuator/shutdown
この呼び出しでは、portはアクチュエータポートを表します。
3. アプリケーションコンテキストを閉じる
アプリケーションコンテキストを使用して、close()メソッドを直接呼び出すこともできます。
コンテキストを作成して閉じる例から始めましょう。
ConfigurableApplicationContext ctx = new
SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run();
System.out.println("Spring Boot application started");
ctx.getBean(TerminateBean.class);
ctx.close();
This destroys all the beans, releases the locks, then closes the bean factory。 アプリケーションのシャットダウンを確認するために、@PreDestroyアノテーションを付けたSpringの標準ライフサイクルコールバックを使用します。
public class TerminateBean {
@PreDestroy
public void onDestroy() throws Exception {
System.out.println("Spring Container is destroyed!");
}
}
また、このタイプのBeanを追加する必要があります。
@Configuration
public class ShutdownConfig {
@Bean
public TerminateBean getTerminateBean() {
return new TerminateBean();
}
}
この例を実行した後の出力は次のとおりです。
Spring Boot application started
Closing [email protected]
DefaultLifecycleProcessor - Stopping beans in phase 0
Unregistering JMX-exposed beans on shutdown
Spring Container is destroyed!
ここで覚えておくべき重要なこと:while closing the application context, the parent context isn’t affected due to separate lifecycles。
3.1. 現在のアプリケーションコンテキストを閉じる
上記の例では、子アプリケーションコンテキストを作成し、close()メソッドを使用してそれを破棄しました。
現在のコンテキストを閉じたい場合、1つの解決策は、アクチュエータの/shutdownエンドポイントを呼び出すことです。
ただし、独自のカスタムエンドポイントを作成することもできます。
@RestController
public class ShutdownController implements ApplicationContextAware {
private ApplicationContext context;
@PostMapping("/shutdownContext")
public void shutdownContext() {
((ConfigurableApplicationContext) context).close();
}
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
this.context = ctx;
}
}
ここでは、ApplicationContextAwareインターフェースを実装し、setterメソッドをオーバーライドして現在のアプリケーションコンテキストを取得するコントローラーを追加しました。 次に、マッピングメソッドでは、単にclose()メソッドを呼び出しています。
次に、新しいエンドポイントを呼び出して、現在のコンテキストをシャットダウンできます。
curl -X POST localhost:port/shutdownContext
もちろん、このようなエンドポイントを実際のアプリケーションに追加する場合は、それも保護する必要があります。
4. SpringApplicationを終了します
SpringApplicationはshutdownフックをJVMに登録して、アプリケーションが適切に終了することを確認します。
Beanは、特定のエラーコードを返すためにExitCodeGeneratorインターフェースを実装する場合があります。
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
.web(WebApplicationType.NONE).run();
int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
// return the error code
return 0;
}
});
System.exit(exitCode);
Java 8ラムダのアプリケーションと同じコード:
SpringApplication.exit(ctx, () -> 0);
After calling the System.exit(exitCode), the program terminates with a 0 return code:
Process finished with exit code 0
5. アプリプロセスを強制終了します
最後に、bashスクリプトを使用して、アプリケーションの外部からSpring Bootアプリケーションをシャットダウンすることもできます。 このオプションの最初のステップは、アプリケーションコンテキストにPIDをファイルに書き込むようにすることです。
SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class)
.web(WebApplicationType.NONE);
app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid"));
app.run();
次に、次の内容のshutdown.batファイルを作成します。
kill $(cat ./bin/shutdown.pid)
shutdown.batを実行すると、shutdown.pidファイルからプロセスIDが抽出され、killコマンドを使用してブートアプリケーションが終了します。
6. 結論
この簡単な記事では、実行中のSpringBootアプリケーションをシャットダウンするために使用できるいくつかの簡単な方法について説明しました。
適切な方法を選択するのは開発者次第ですが、これらの方法はすべて、設計上および意図的に使用する必要があります。
たとえば、エラーコードを別の環境(JVMなど)に渡す必要がある場合は、.exit()が推奨されます。 bashスクリプトを使用してApplication PID gives more flexibility, as we can also start or restart the applicationを使用する。
最後に、/shutdownは、terminate the applications externally via HTTPを可能にするためにここにあります。 他のすべての場合、.close()は完全に機能します。
いつものように、この記事の完全なコードはGitHub projectで入手できます。