Polish Liveness and Readiness support
This commit moves the core Liveness and Readiness support to its own `availability` package. We've made this a core concept independent of Kubernetes. Spring Boot now produces `LivenessStateChanged` and `ReadinessStateChanged` events as part of the typical application lifecycle. Liveness and Readiness Probes (`HealthIndicator` components and health groups) are still configured only when deployed on Kubernetes. This commit also improves the documentation around Probes best practices and container lifecycle considerations. See gh-19593
This commit is contained in:
@@ -191,6 +191,90 @@ NOTE: There are some restrictions when creating an `ApplicationContext` hierarch
|
||||
For example, Web components *must* be contained within the child context, and the same `Environment` is used for both parent and child contexts.
|
||||
See the {spring-boot-module-api}/builder/SpringApplicationBuilder.html[`SpringApplicationBuilder` Javadoc] for full details.
|
||||
|
||||
[[boot-features-application-availability-state]]
|
||||
== Application Availability State
|
||||
When deployed on plaftorms, applications can provide information about their availability to the platform using infrastructure like https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/[Kubernetes Probes].
|
||||
Spring Boot manages this application state with the `ApplicationAvailabilityProvider` and makes it available to application components and the platform itself.
|
||||
|
||||
|
||||
[[boot-features-application-availability-liveness]]
|
||||
=== Liveness State
|
||||
The "Liveness" state of an application tells whether its internal state allows it to work correctly, or recover by itself if it's currently failing.
|
||||
An invalid "Liveness" state means that the application is in a broken state and cannot recover from it; the infrastructure should then restart the application to mitigate that problem.
|
||||
|
||||
NOTE: In general, the "Liveness" state should not be based on external checks, such as <<production-ready-features.adoc#production-ready-health, Health checks>>.
|
||||
If it did, a failing external system (a database, a Web API, an external cache) would trigger massive restarts and cascading failures across the platform.
|
||||
|
||||
The internal state of Spring Boot applications is mostly represented by the Spring application context.
|
||||
If the application context has started successfully, Spring Boot assumes that the application is in a valid state.
|
||||
An application is considered live as soon as the context has been refreshed, see <<boot-features-application-events-and-listeners, Spring Boot application lifecycle and related Application Events>>.
|
||||
|
||||
[[boot-features-application-availability-readiness]]
|
||||
=== Readiness State
|
||||
The "Readiness" state of an application tells whether the application is ready to handle traffic.
|
||||
A failing "Readiness" state tells the platform that it should not route traffic to the application for now.
|
||||
This typically happens during startup, while `CommandLineRunner` and `ApplicationRunner` components are being processed, or at any time if the application decides that it's too busy for additional traffic.
|
||||
|
||||
An application is considered ready as soon as application and command-line runners have been called, see <<boot-features-application-events-and-listeners, Spring Boot application lifecycle and related Application Events>>.
|
||||
|
||||
TIP: Tasks expected to run during startup should be executed by `CommandLineRunner` and `ApplicationRunner` components instead of using Spring component lifecycle callbacks such as `@PostConstruct`.
|
||||
|
||||
|
||||
|
||||
[[boot-features-managing-application-availability]]
|
||||
=== Managing the Application Availability State
|
||||
Application components can retrieve the current availability state at any time, by injecting the `ApplicationAvailabilityProvider` and calling methods on it.
|
||||
More often, applications will want to listen to state updates or update the state of the application.
|
||||
|
||||
For example, we can export the "Readiness" state of the application to a file so that a Kubernetes "exec Probe" can look at this file:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Component
|
||||
public class ReadinessStateExporter implements ApplicationListener<LivenessStateChangedEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(LivenessStateChangedEvent event) {
|
||||
switch (event.getReadinessState().getStatus()) {
|
||||
case READY:
|
||||
// create file /tmp/healthy
|
||||
break;
|
||||
case UNREADY:
|
||||
// remove file /tmp/healthy
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
We can also update the state of the application, when the application breaks and cannot recover:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Component
|
||||
public class LocalCacheVerifier {
|
||||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public LocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
public void checkLocalCache() {
|
||||
try {
|
||||
//...
|
||||
}
|
||||
catch (CacheCompletelyBrokenException ex) {
|
||||
this.eventPublisher.publishEvent(LivenessStateChangedEvent.broken(ex));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Spring Boot provides <<production-ready-features.adoc#production-ready-kubernetes-probes,Kubernetes HTTP probes for "Liveness" and "Readiness" with Actuator Health Endpoints>>.
|
||||
You can get more guidance about <<deployment.adoc#cloud-deployment-kubernetes,deploying Spring Boot applications on Kubernetes in the dedicated section>>.
|
||||
|
||||
|
||||
[[boot-features-application-events-and-listeners]]
|
||||
@@ -218,8 +302,9 @@ Application events are sent in the following order, as your application runs:
|
||||
. An `ApplicationContextInitializedEvent` is sent when the `ApplicationContext` is prepared and ApplicationContextInitializers have been called but before any bean definitions are loaded.
|
||||
. An `ApplicationPreparedEvent` is sent just before the refresh is started but after bean definitions have been loaded.
|
||||
. An `ApplicationStartedEvent` is sent after the context has been refreshed but before any application and command-line runners have been called.
|
||||
. An `LivenessStateChangedEvent` is sent right after to indicate that the application is considered as live.
|
||||
. An `ApplicationReadyEvent` is sent after any application and command-line runners have been called.
|
||||
It indicates that the application is ready to service requests.
|
||||
. An `ReadinessStateChangedEvent` is sent right after to indicate that the application is ready to service requests.
|
||||
. An `ApplicationFailedEvent` is sent if there is an exception on startup.
|
||||
|
||||
The above list only includes ``SpringApplicationEvent``s that are tied to a `SpringApplication`.
|
||||
@@ -6013,91 +6098,6 @@ For instance, it is possible to customize the name of the table for the JDBC sto
|
||||
For setting the timeout of the session you can use the configprop:spring.session.timeout[] property.
|
||||
If that property is not set, the auto-configuration falls back to the value of configprop:server.servlet.session.timeout[].
|
||||
|
||||
[[boot-features-kubernetes-application-state]]
|
||||
== Kubernetes Application State
|
||||
When deployed on Kubernetes, applications can provide information about their state to the platform using https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/[Kubernetes Probes].
|
||||
Spring Boot manages this application state with the `ApplicationStateProvider` and makes it available to application components and the cloud platform itself.
|
||||
This feature is only enabled when the application is running on Kubernetes.
|
||||
|
||||
TIP: The cloud platform detection relies on platform-specific environment variables, but you can override this detection with the configprop:spring.main.cloud-platform[] configuration property.
|
||||
|
||||
[[boot-features-kubernetes-liveness-state]]
|
||||
=== Liveness State
|
||||
The "Liveness" state of an application tells whether its internal state allows it to work correctly, or recover by itself if it's currently failing.
|
||||
An invalid "Liveness" state means that the application is in a broken state and cannot recover from it; the infrastructure should then restart the application to mitigate that problem.
|
||||
|
||||
NOTE: In general, the "Liveness" state should not be based external checks, such as <<production-ready-features.adoc#production-ready-health, Health checks>>.
|
||||
If it did, a failing external system (a database, a Web API, an external cache) would trigger massive restarts and cascading failures across the platform.
|
||||
|
||||
The internal state of Spring Boot applications is mostly represented by the Spring application context.
|
||||
If the application context has started successfully, Spring Boot assumes that the application is in a valid state.
|
||||
An application is considered live as soon as the `ApplicationStartedEvent` has been published, see <<boot-features-application-events-and-listeners, Spring Boot application lifecycle and related Application Events>>.
|
||||
|
||||
[[boot-features-kubernetes-readiness-state]]
|
||||
=== Readiness State
|
||||
The "Readiness" state of an application tells whether the application is ready to handle traffic.
|
||||
A failing "Readiness" state tells Kubernetes that it should not route traffic to the application for now.
|
||||
This typically happens during startup, while `CommandLineRunner` and `ApplicationRunner` components are being processed, or at any time if the application decides that it's too busy for additional traffic.
|
||||
|
||||
An application is considered ready as soon as the `ApplicationReadyEvent` has been published, see <<boot-features-application-events-and-listeners, Spring Boot application lifecycle and related Application Events>>.
|
||||
|
||||
TIP: Tasks expected to run during startup should be executed by `CommandLineRunner` and `ApplicationRunner` components instead of using Spring component lifecycle callbacks such as `@PostConstruct`.
|
||||
|
||||
[[boot-features-kubernetes-managing-state]]
|
||||
=== Managing Kubernetes Application State
|
||||
Application components can retrieve the current application state at any time, by injecting the `ApplicationStateProvider` and calling methods on it.
|
||||
More often, applications will want to listen to state updates or update the state of the application.
|
||||
|
||||
For example, we can export the "Readiness" state of the application to a file so that a Kubernetes "exec Probe" can look at this file:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Component
|
||||
public class LivenessStateExporter implements ApplicationListener<LivenessStateChangedEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(LivenessStateChangedEvent event) {
|
||||
switch (event.getLivenessState().getStatus()) {
|
||||
case LIVE:
|
||||
// create file /tmp/healthy
|
||||
break;
|
||||
case BROKEN:
|
||||
// remove file /tmp/healthy
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
We can also update the state of the application, when the application breaks and cannot recover:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Component
|
||||
public class LocalCacheVerifier {
|
||||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public LocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
public void checkLocalCache() {
|
||||
try {
|
||||
//...
|
||||
}
|
||||
catch (CacheCompletelyBroken ex) {
|
||||
this.eventPublisher.publishEvent(LivenessStateChangedEvent.broken(ex));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Spring Boot provides <<production-ready-features.adoc#production-ready-kubernetes-probes,Kubernetes HTTP probes for "Liveness" and "Readiness" with Actuator Health Endpoints>>.
|
||||
You can get more guidance about <<deployment.adoc#cloud-deployment-kubernetes,deploying Spring Boot applications on Kubernetes in the dedicated section>>.
|
||||
|
||||
|
||||
[[boot-features-jmx]]
|
||||
== Monitoring and Management over JMX
|
||||
|
||||
Reference in New Issue
Block a user