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
現在可以測試了,在服務啟動後或服務關閉時通過檢視日志或斷點會看到處理函數會執行。