springboot可以提供诸如Kubernetes Probes向外其可用性的信息。 Spring Boot对常用的“活动性”和“就绪性”可用性状态提供了支持。“活动”状态Liveness表示当前服务是否可用,“就绪”状态Readiness表示应用程序是否已准备好处理请求。 失败的“就绪”状态告诉平台当前不应将流量路由到应用程序。 这通常发生在启动过程中,正在处理CommandLineRunner和ApplicationRunner组件时,或者在应用程序无法处理请求时。
1、创建springboot程序
过程略
2、建立健康检测接口
四个方法分别对应Readiness和Liveness的两种状态
package com.iscas.base.biz.config.health;
/**
* 健康检测处理扩展接口
*
* @author zhuquanwen
* @vesion 1.0
* @date 2021/1/10 15:18
* @since jdk1.8
*/
public interface IHealthCheckHandler {
/**健康检测-readiness检测成功*/
void readinessAccept();
/**健康检测-readiness检测失败*/
void readinessRefuse();
/**健康检测-liveness检测成功*/
void livenessCorrect();
/**健康检测-liveness检测失败*/
void livenessBroken();
}
3、默认实现健康处理接口
这里只做了日志输出,根据实际需要,可以扩展
package com.iscas.base.biz.config.health;
import lombok.extern.slf4j.Slf4j;
/**
* 默认健康检测处理
*
* @author zhuquanwen
* @vesion 1.0
* @date 2021/1/10 15:20
* @since jdk1.8
*/
@Slf4j
public class DefaultHealthCheckHandler implements IHealthCheckHandler {
@Override
public void readinessAccept() {
log.info("健康检测-readiness-检测成功-服务已准备好,可以提供服务");
}
@Override
public void readinessRefuse() {
log.info("健康检测-readiness-检测失败-服务未准备好或即将关闭");
}
@Override
public void livenessCorrect() {
log.info("健康检测-liveness-检测成功-服务正常");
}
@Override
public void livenessBroken() {
log.info("健康检测-liveness-检测失败-服务异常");
}
}
4、编写一个基类,获取接口对应的实现
package com.iscas.base.biz.config.health;
import com.iscas.base.biz.service.common.SpringService;
/**
*
* @author zhuquanwen
* @vesion 1.0
* @date 2021/1/10 15:46
* @since jdk1.8
*/
public class HealthBaseListener {
protected volatile IHealthCheckHandler healthCheckHandler = null;
public IHealthCheckHandler getHealthCheckHandler() {
if (healthCheckHandler == null) {
synchronized (LivenessStateListener.class) {
if (healthCheckHandler == null) {
healthCheckHandler = SpringService.getApplicationContext().getBean(IHealthCheckHandler.class);
}
}
}
return healthCheckHandler;
}
}
SpringService:
@Component
@Lazy(value = false)
public class SpringService implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringService.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) applicationContext.getBean(name);
}
}
5、编写两种健康检测的监听
这里通过调用上面定义的处理类内的函数,实现在健康状态的监听触发时,调用自定义的处理代码。
LivenessStateListener :
package com.iscas.base.biz.config.health;
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.LivenessState;
import org.springframework.context.event.EventListener;
//@Component
//@Lazy(value = false)
public class LivenessStateListener extends HealthBaseListener{
@EventListener
public void onStateChange(AvailabilityChangeEvent<LivenessState> event) {
switch (event.getState()) {
case CORRECT:
// create file /tmp/healthy
getHealthCheckHandler().livenessCorrect();
break;
case BROKEN:
// remove file /tmp/healthy
getHealthCheckHandler().livenessBroken();
break;
}
}
}
ReadinessStateListener :
package com.iscas.base.biz.config.health;
import org.springframework.boot.availability.AvailabilityChangeEvent;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.context.event.EventListener;
//@Component
//@Lazy(value = false)
public class ReadinessStateListener extends HealthBaseListener {
private volatile IHealthCheckHandler healthCheckHandler = null;
@EventListener
public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC:
// create file /tmp/healthy
getHealthCheckHandler().readinessAccept();
break;
case REFUSING_TRAFFIC:
// remove file /tmp/healthy
getHealthCheckHandler().readinessRefuse();
break;
}
}
}
6、编写配置类
注册Bean,注册两种监听和处理类
package com.iscas.base.biz.config.health;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
/**
* 健康检测注册
*
* @author zhuquanwen
* @vesion 1.0
* @date 2021/1/10 15:13
* @since jdk1.8
*/
public class HealthCheckConfig {
@Bean
@Lazy(value = false)
public LivenessStateListener livenessStateListener() {
return new LivenessStateListener();
}
@Bean
@Lazy(value = false)
public ReadinessStateListener readinessStateListener() {
return new ReadinessStateListener();
}
@Bean
@ConditionalOnMissingBean
@Lazy(value = false)
public IHealthCheckHandler healthCheckHelper() {
return new DefaultHealthCheckHandler();
}
}
7、编写一个Enable开关注解
在不需要做健康检测时不启用注解就不会执行
package com.iscas.base.biz.aop.enable;
import com.iscas.base.biz.config.health.HealthCheckConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* 是否启动健康检测
*
* @author zhuquanwen
* @vesion 1.0
* @date 2021/1/10 15:14
* @since jdk1.8
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(HealthCheckConfig.class)
public @interface EnableHealthCheck {
}
8、在启动类加上@EnableHealthCheck
现在可以测试了,在服务启动后或服务关闭时通过查看日志或断点会看到处理函数会执行。