聊聊springboot的liveness及readiness

编程入门 行业动态 更新时间:2024-10-22 17:25:48

聊聊<a href=https://www.elefans.com/category/jswz/34/1769943.html style=springboot的liveness及readiness"/>

聊聊springboot的liveness及readiness

本文主要研究一下springboot的liveness及readiness

使用

management:endpoints:web:exposure:include: '*'endpoint:health:probes:enabled: trueshow-details: alwayshealth:# /actuator/health/livenesslivenessState:enabled: true# /actuator/health/readinessreadinessState:enabled: true      

通过如上配置可以开启liveness及readiness,要求springboot版本在2.3.0及以上

ApplicationAvailabilityAutoConfiguration

org/springframework/boot/autoconfigure/availability/ApplicationAvailabilityAutoConfiguration.java

@Configuration(proxyBeanMethods = false)
public class ApplicationAvailabilityAutoConfiguration {@Beanpublic ApplicationAvailabilityBean applicationAvailability() {return new ApplicationAvailabilityBean();}}

ApplicationAvailabilityAutoConfiguration定义了ApplicationAvailabilityBean

ApplicationAvailabilityBean

org/springframework/boot/availability/ApplicationAvailabilityBean.java

public class ApplicationAvailabilityBeanimplements ApplicationAvailability, ApplicationListener<AvailabilityChangeEvent<?>> {private final Map<Class<? extends AvailabilityState>, AvailabilityChangeEvent<?>> events = new HashMap<>();@Overridepublic <S extends AvailabilityState> S getState(Class<S> stateType, S defaultState) {Assert.notNull(stateType, "StateType must not be null");Assert.notNull(defaultState, "DefaultState must not be null");S state = getState(stateType);return (state != null) ? state : defaultState;}@Overridepublic <S extends AvailabilityState> S getState(Class<S> stateType) {AvailabilityChangeEvent<S> event = getLastChangeEvent(stateType);return (event != null) ? event.getState() : null;}@Override@SuppressWarnings("unchecked")public <S extends AvailabilityState> AvailabilityChangeEvent<S> getLastChangeEvent(Class<S> stateType) {return (AvailabilityChangeEvent<S>) this.events.get(stateType);}@Overridepublic void onApplicationEvent(AvailabilityChangeEvent<?> event) {Class<? extends AvailabilityState> stateType = getStateType(event.getState());this.events.put(stateType, event);}@SuppressWarnings("unchecked")private Class<? extends AvailabilityState> getStateType(AvailabilityState state) {if (state instanceof Enum) {return (Class<? extends AvailabilityState>) ((Enum<?>) state).getDeclaringClass();}return state.getClass();}}

ApplicationAvailabilityBean实现了ApplicationAvailability、ApplicationListener接口,它接收AvailabilityChangeEvent事件,然后存储到events中,getState方法则从events中获取指定class类型的AvailabilityState

AvailabilityChangeEvent

org/springframework/boot/availability/AvailabilityChangeEvent.java

public class AvailabilityChangeEvent<S extends AvailabilityState> extends PayloadApplicationEvent<S> {/*** Create a new {@link AvailabilityChangeEvent} instance.* @param source the source of the event* @param state the availability state (never {@code null})*/public AvailabilityChangeEvent(Object source, S state) {super(source, state);}/*** Return the changed availability state.* @return the availability state*/public S getState() {return getPayload();}@Overridepublic ResolvableType getResolvableType() {return ResolvableType.forClassWithGenerics(getClass(), getStateType());}private Class<?> getStateType() {S state = getState();if (state instanceof Enum) {return ((Enum<?>) state).getDeclaringClass();}return state.getClass();}/*** Convenience method that can be used to publish an {@link AvailabilityChangeEvent}* to the given application context.* @param <S> the availability state type* @param context the context used to publish the event* @param state the changed availability state*/public static <S extends AvailabilityState> void publish(ApplicationContext context, S state) {Assert.notNull(context, "Context must not be null");publish(context, context, state);}/*** Convenience method that can be used to publish an {@link AvailabilityChangeEvent}* to the given application context.* @param <S> the availability state type* @param publisher the publisher used to publish the event* @param source the source of the event* @param state the changed availability state*/public static <S extends AvailabilityState> void publish(ApplicationEventPublisher publisher, Object source,S state) {Assert.notNull(publisher, "Publisher must not be null");publisher.publishEvent(new AvailabilityChangeEvent<>(source, state));}}

AvailabilityChangeEvent继承了PayloadApplicationEvent,它还定义了publish方法

AvailabilityHealthContributorAutoConfiguration

org/springframework/boot/actuate/autoconfigure/availability/AvailabilityHealthContributorAutoConfiguration.java

@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(ApplicationAvailabilityAutoConfiguration.class)
public class AvailabilityHealthContributorAutoConfiguration {@Bean@ConditionalOnMissingBean(name = "livenessStateHealthIndicator")@ConditionalOnProperty(prefix = "management.health.livenessstate", name = "enabled", havingValue = "true")public LivenessStateHealthIndicator livenessStateHealthIndicator(ApplicationAvailability applicationAvailability) {return new LivenessStateHealthIndicator(applicationAvailability);}@Bean@ConditionalOnMissingBean(name = "readinessStateHealthIndicator")@ConditionalOnProperty(prefix = "management.health.readinessstate", name = "enabled", havingValue = "true")public ReadinessStateHealthIndicator readinessStateHealthIndicator(ApplicationAvailability applicationAvailability) {return new ReadinessStateHealthIndicator(applicationAvailability);}}

AvailabilityHealthContributorAutoConfiguration定义了LivenessStateHealthIndicator、ReadinessStateHealthIndicator

AvailabilityStateHealthIndicator

org/springframework/boot/actuate/availability/AvailabilityStateHealthIndicator.java

public class AvailabilityStateHealthIndicator extends AbstractHealthIndicator {private final ApplicationAvailability applicationAvailability;private Class<? extends AvailabilityState> stateType;private final Map<AvailabilityState, Status> statusMappings = new HashMap<>();/*** Create a new {@link AvailabilityStateHealthIndicator} instance.* @param <S> the availability state type* @param applicationAvailability the application availability* @param stateType the availability state type* @param statusMappings consumer used to setup the status mappings*/public <S extends AvailabilityState> AvailabilityStateHealthIndicator(ApplicationAvailability applicationAvailability, Class<S> stateType,Consumer<StatusMappings<S>> statusMappings) {Assert.notNull(applicationAvailability, "ApplicationAvailability must not be null");Assert.notNull(stateType, "StateType must not be null");Assert.notNull(statusMappings, "StatusMappings must not be null");this.applicationAvailability = applicationAvailability;this.stateType = stateType;statusMappings.accept(this.statusMappings::put);assertAllEnumsMapped(stateType);}@SuppressWarnings({ "unchecked", "rawtypes" })private <S extends AvailabilityState> void assertAllEnumsMapped(Class<S> stateType) {if (!this.statusMappings.containsKey(null) && Enum.class.isAssignableFrom(stateType)) {EnumSet elements = EnumSet.allOf((Class) stateType);for (Object element : elements) {Assert.isTrue(this.statusMappings.containsKey(element),() -> "StatusMappings does not include " + element);}}}@Overrideprotected void doHealthCheck(Builder builder) throws Exception {AvailabilityState state = getState(this.applicationAvailability);Status status = this.statusMappings.get(state);if (status == null) {status = this.statusMappings.get(null);}Assert.state(status != null, () -> "No mapping provided for " + state);builder.status(status);}/*** Return the current availability state. Subclasses can override this method if a* different retrieval mechanism is needed.* @param applicationAvailability the application availability* @return the current availability state*/protected AvailabilityState getState(ApplicationAvailability applicationAvailability) {return applicationAvailability.getState(this.stateType);}/*** Callback used to add status mappings.** @param <S> the availability state type*/public interface StatusMappings<S extends AvailabilityState> {/*** Add the status that should be used if no explicit mapping is defined.* @param status the default status*/default void addDefaultStatus(Status status) {add(null, status);}/*** Add a new status mapping .* @param availabilityState the availability state* @param status the mapped status*/void add(S availabilityState, Status status);}}

AvailabilityStateHealthIndicator继承了AbstractHealthIndicator,它定义了statusMappings,key为AvailabilityState,value为Status,其doHealthCheck就是获取state,然后从statusMappings取出对应的status

LivenessStateHealthIndicator

org/springframework/boot/actuate/availability/LivenessStateHealthIndicator.java

public class LivenessStateHealthIndicator extends AvailabilityStateHealthIndicator {public LivenessStateHealthIndicator(ApplicationAvailability availability) {super(availability, LivenessState.class, (statusMappings) -> {statusMappings.add(LivenessState.CORRECT, Status.UP);statusMappings.add(LivenessState.BROKEN, Status.DOWN);});}@Overrideprotected AvailabilityState getState(ApplicationAvailability applicationAvailability) {return applicationAvailability.getLivenessState();}}

LivenessStateHealthIndicator继承了AvailabilityStateHealthIndicator,它建立了LivenessState.CORRECT到Status.UP,LivenessState.BROKEN到Status.DOWN的映射

ReadinessStateHealthIndicator

org/springframework/boot/actuate/availability/ReadinessStateHealthIndicator.java

public class ReadinessStateHealthIndicator extends AvailabilityStateHealthIndicator {public ReadinessStateHealthIndicator(ApplicationAvailability availability) {super(availability, ReadinessState.class, (statusMappings) -> {statusMappings.add(ReadinessState.ACCEPTING_TRAFFIC, Status.UP);statusMappings.add(ReadinessState.REFUSING_TRAFFIC, Status.OUT_OF_SERVICE);});}@Overrideprotected AvailabilityState getState(ApplicationAvailability applicationAvailability) {return applicationAvailability.getReadinessState();}}

ReadinessStateHealthIndicator继承了AvailabilityStateHealthIndicator,它定义了ReadinessState.ACCEPTING_TRAFFIC到Status.UP,ReadinessState.REFUSING_TRAFFIC到Status.OUT_OF_SERVICE的映射

EventPublishingRunListener

org/springframework/boot/context/event/EventPublishingRunListener.java

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {@Overridepublic void started(ConfigurableApplicationContext context) {context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);}@Overridepublic void running(ConfigurableApplicationContext context) {context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);}
}

EventPublishingRunListener的started方法会发布AvailabilityChangeEvent,其state为LivenessState.CORRECT;running方法会发布AvailabilityChangeEvent,其state为ReadinessState.ACCEPTING_TRAFFIC

SpringApplicationRunListeners

org/springframework/boot/SpringApplicationRunListeners.java

class SpringApplicationRunListeners {void started(ConfigurableApplicationContext context) {for (SpringApplicationRunListener listener : this.listeners) {listener.started(context);}}void running(ConfigurableApplicationContext context) {for (SpringApplicationRunListener listener : this.listeners) {listener.running(context);}}//......
}	

SpringApplicationRunListeners的started会回调listener的started,running会回调listener的running方法

ServletWebServerApplicationContext

org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java

public class ServletWebServerApplicationContext extends GenericWebApplicationContextimplements ConfigurableWebServerApplicationContext {@Overrideprotected void doClose() {if (isActive()) {AvailabilityChangeEvent.publish(this, ReadinessState.REFUSING_TRAFFIC);}super.doClose();}//......
}	

ServletWebServerApplicationContext的doClose方法在active的时候会发布AvailabilityChangeEvent,state为ReadinessState.REFUSING_TRAFFIC

SpringApplication

org/springframework/boot/SpringApplication.java

public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;}

SpringApplication的run方法会先获取SpringApplicationRunListeners,然后执行listeners.starting(),接着prepareEnvironment、createApplicationContext、prepareContext、refreshContext、afterRefresh;之后执行listeners.started(context);再执行listeners.running(context)

小结

AvailabilityHealthContributorAutoConfiguration定义了LivenessStateHealthIndicator、ReadinessStateHealthIndicator,它们依赖AvailabilityChangeEvent,SpringApplication的run方法会先后触发listeners.starting()、listeners.started(context)、listeners.running(context);EventPublishingRunListener的started方法会发布AvailabilityChangeEvent,其state为LivenessState.CORRECT;running方法会发布AvailabilityChangeEvent,其state为ReadinessState.ACCEPTING_TRAFFIC。

更多推荐

聊聊springboot的liveness及readiness

本文发布于:2023-12-03 17:06:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1656899.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:springboot   liveness   readiness

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!