diff --git a/pom.xml b/pom.xml
index 5ec70956e..9fb1e33ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,7 +37,7 @@
SOFABoot Build
- 3.16.2
+ 3.16.3
${revision}
1.6.7
diff --git a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthCheckerProcessor.java b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthCheckerProcessor.java
index 60649d4c7..fda671547 100644
--- a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthCheckerProcessor.java
+++ b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthCheckerProcessor.java
@@ -176,6 +176,9 @@ public boolean readinessHealthCheck(Map healthMap) {
} catch (InterruptedException e) {
logger.error(ErrorCode.convert("01-22005"), e);
}
+ if (!finished) {
+ healthMap.put(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY, Health.unknown().withDetail(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY,SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_MSG).build());
+ }
result = finished && parallelResult.get();
} else {
result = readinessHealthCheckers.entrySet().stream()
diff --git a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthIndicatorProcessor.java b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthIndicatorProcessor.java
index 9755b82ee..d6ae0fd0c 100644
--- a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthIndicatorProcessor.java
+++ b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/HealthIndicatorProcessor.java
@@ -181,6 +181,9 @@ public boolean readinessHealthCheck(Map healthMap) {
} catch (InterruptedException e) {
logger.error(ErrorCode.convert("01-21004"), e);
}
+ if (!finished) {
+ healthMap.put(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY, Health.unknown().withDetail(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY,SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_MSG).build());
+ }
result = finished && parallelResult.get();
} else {
result = healthIndicators.entrySet().stream()
diff --git a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/ReadinessCheckListener.java b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/ReadinessCheckListener.java
index 082ad5694..8b5c86a14 100644
--- a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/ReadinessCheckListener.java
+++ b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/main/java/com/alipay/sofa/healthcheck/ReadinessCheckListener.java
@@ -238,29 +238,30 @@ public Health aggregateReadinessHealth() {
SofaBootConstants.SOFABOOT_HEALTH_CHECK_NOT_READY_MSG).build());
} else {
boolean healthCheckerStatus = getHealthCheckerStatus();
+ boolean healthIndicatorStatus = getHealthIndicatorStatus();
+ boolean afterReadinessCheckCallbackStatus = getHealthCallbackStatus();
Map healthCheckerDetails = getHealthCheckerDetails();
Map healthIndicatorDetails = getHealthIndicatorDetails();
-
- boolean afterReadinessCheckCallbackStatus = getHealthCallbackStatus();
Map afterReadinessCheckCallbackDetails = getHealthCallbackDetails();
Health.Builder builder;
- if (healthCheckerStatus && afterReadinessCheckCallbackStatus) {
- builder = Health.up();
- } else {
- builder = Health.down();
- }
+ builder = healthCheckerStatus ? Health.up():Health.down();
if (!CollectionUtils.isEmpty(healthCheckerDetails)) {
- builder = builder.withDetail("HealthChecker", healthCheckerDetails);
+ builder = builder.withDetails(healthCheckerDetails);
}
- if (!CollectionUtils.isEmpty(afterReadinessCheckCallbackDetails)) {
- builder = builder.withDetail("ReadinessCheckCallback",
- afterReadinessCheckCallbackDetails);
+ healths.put("HealthCheckerInfo", builder.build());
+
+ builder = healthIndicatorStatus ? Health.up():Health.down();
+ if (!CollectionUtils.isEmpty(healthIndicatorDetails)) {
+ builder = builder.withDetails(healthIndicatorDetails);
}
- healths.put("SOFABootReadinessHealthCheckInfo", builder.build());
+ healths.put("HealthIndicatorInfo", builder.build());
- // HealthIndicator
- healths.putAll(healthIndicatorDetails);
+ builder = afterReadinessCheckCallbackStatus ? Health.up():Health.down();
+ if (!CollectionUtils.isEmpty(afterReadinessCheckCallbackDetails)) {
+ builder = builder.withDetails(afterReadinessCheckCallbackDetails);
+ }
+ healths.put("ReadinessCheckCallbackInfo", builder.build());
}
Status overallStatus = this.statusAggregator.getAggregateStatus(
healths.values().stream().map(Health::getStatus).collect(Collectors.toSet()));
diff --git a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthCheckerProcessorParallelTest.java b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthCheckerProcessorParallelTest.java
index 223875c4b..737eb71a1 100644
--- a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthCheckerProcessorParallelTest.java
+++ b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthCheckerProcessorParallelTest.java
@@ -223,6 +223,21 @@ public void testComponentHealthCheckerFailedFirst() {
}
}
+ @Test
+ public void testHealthCheckerParallelTimeout() {
+ initApplicationContextTimeout(0, false, 4);
+
+ HashMap hashMap = new HashMap<>();
+ HealthCheckerProcessor healthCheckerProcessor = applicationContext
+ .getBean(HealthCheckerProcessor.class);
+ boolean result = healthCheckerProcessor.readinessHealthCheck(hashMap);
+ Assert.assertFalse(result);
+ Health timeoutHealth = hashMap.get(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY);
+ Assert.assertEquals(Status.UNKNOWN, timeoutHealth.getStatus());
+ Assert.assertEquals(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_MSG, timeoutHealth
+ .getDetails().get(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY));
+ }
+
private void initApplicationContext(int count, boolean strict, int retryCount) {
Map properties = new LinkedHashMap<>();
properties.put("memory-health-checker.count", count);
@@ -237,4 +252,20 @@ private void initApplicationContext(int count, boolean strict, int retryCount) {
springApplication.setWebApplicationType(WebApplicationType.NONE);
applicationContext = springApplication.run();
}
+
+ private void initApplicationContextTimeout(int count, boolean strict, int retryCount) {
+ Map properties = new LinkedHashMap<>();
+ properties.put("memory-health-checker.count", count);
+ properties.put("memory-health-checker.strict", strict);
+ properties.put("memory-health-checker.retry-count", retryCount);
+ properties.put("spring.application.name", "HealthCheckerProcessorTest");
+ properties.put(SofaBootConstants.SOFABOOT_SKIP_COMPONENT_HEALTH_CHECK, true);
+ properties.put("com.alipay.sofa.boot.health-check-parallel-timeout", "1");
+
+ SpringApplication springApplication = new SpringApplication(
+ HealthCheckerProcessorTestConfiguration.class);
+ springApplication.setDefaultProperties(properties);
+ springApplication.setWebApplicationType(WebApplicationType.NONE);
+ applicationContext = springApplication.run();
+ }
}
\ No newline at end of file
diff --git a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthIndicatorCheckProcessorParallelTest.java b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthIndicatorCheckProcessorParallelTest.java
index e650ddddb..afd8b2e0b 100644
--- a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthIndicatorCheckProcessorParallelTest.java
+++ b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/HealthIndicatorCheckProcessorParallelTest.java
@@ -16,6 +16,7 @@
*/
package com.alipay.sofa.healthcheck.test;
+import com.alipay.sofa.boot.constant.SofaBootConstants;
import com.alipay.sofa.healthcheck.AfterReadinessCheckCallbackProcessor;
import com.alipay.sofa.healthcheck.HealthCheckProperties;
import com.alipay.sofa.healthcheck.HealthCheckerProcessor;
@@ -30,6 +31,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -121,10 +123,39 @@ public void testCheckIndicatorFailed() {
Assert.assertEquals(2, hashMap.size());
}
+ @Test
+ public void testCheckIndicatorParallelTimeout() {
+ initApplicationContextTimeout();
+ ReadinessCheckListener readinessCheckListener = applicationContext
+ .getBean(ReadinessCheckListener.class);
+ Health health = readinessCheckListener.aggregateReadinessHealth();
+ Health healthIndicatorInfo = (Health) health.getDetails().get("HealthIndicatorInfo");
+ Health timeoutHealth = (Health) healthIndicatorInfo.getDetails().get(
+ SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY);
+ Assert.assertEquals(Status.DOWN, health.getStatus());
+ Assert.assertEquals(Status.UNKNOWN, timeoutHealth.getStatus());
+ Assert.assertEquals(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_MSG, timeoutHealth
+ .getDetails().get(SofaBootConstants.SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY));
+ }
+
private void initApplicationContext(boolean health) {
Map properties = new LinkedHashMap<>();
properties.put("disk-health-indicator.health", health);
properties.put("spring.application.name", "HealthIndicatorCheckProcessorTest");
+ properties.put(SofaBootConstants.SOFABOOT_SKIP_HEALTH_INDICATOR_CHECK, "true");
+ SpringApplication springApplication = new SpringApplication(
+ HealthIndicatorConfiguration.class);
+ springApplication.setDefaultProperties(properties);
+ springApplication.setWebApplicationType(WebApplicationType.NONE);
+ applicationContext = springApplication.run();
+ }
+
+ private void initApplicationContextTimeout() {
+ Map properties = new LinkedHashMap<>();
+ properties.put("disk-health-indicator.health", true);
+ properties.put("spring.application.name", "HealthIndicatorCheckProcessorTest");
+ // properties.put(SofaBootConstants.SOFABOOT_SKIP_HEALTH_INDICATOR_CHECK, "true");
+ properties.put("com.alipay.sofa.boot.health-check-parallel-timeout", "1");
SpringApplication springApplication = new SpringApplication(
HealthIndicatorConfiguration.class);
springApplication.setDefaultProperties(properties);
diff --git a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/ReadinessCheckListenerTest.java b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/ReadinessCheckListenerTest.java
index 5eb6d3184..17e75928f 100644
--- a/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/ReadinessCheckListenerTest.java
+++ b/sofa-boot-project/sofa-boot-core/healthcheck-sofa-boot/src/test/java/com/alipay/sofa/healthcheck/test/ReadinessCheckListenerTest.java
@@ -16,10 +16,19 @@
*/
package com.alipay.sofa.healthcheck.test;
+import com.alipay.sofa.healthcheck.AfterReadinessCheckCallbackProcessor;
import com.alipay.sofa.healthcheck.HealthCheckProperties;
+import com.alipay.sofa.healthcheck.HealthCheckerProcessor;
+import com.alipay.sofa.healthcheck.HealthIndicatorProcessor;
+import com.alipay.sofa.healthcheck.ReadinessCheckListener;
import com.alipay.sofa.healthcheck.core.HealthCheckExecutor;
+import com.alipay.sofa.healthcheck.test.bean.DiskHealthIndicator;
+import com.alipay.sofa.healthcheck.test.bean.MemoryHealthChecker;
+import com.alipay.sofa.healthcheck.test.bean.MiddlewareHealthCheckCallback;
+import com.alipay.sofa.runtime.SofaRuntimeProperties;
import com.alipay.sofa.runtime.configure.SofaRuntimeConfigurationProperties;
import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
@@ -40,13 +49,9 @@
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
-import com.alipay.sofa.healthcheck.AfterReadinessCheckCallbackProcessor;
-import com.alipay.sofa.healthcheck.HealthCheckerProcessor;
-import com.alipay.sofa.healthcheck.HealthIndicatorProcessor;
-import com.alipay.sofa.healthcheck.ReadinessCheckListener;
-import com.alipay.sofa.healthcheck.test.bean.DiskHealthIndicator;
-import com.alipay.sofa.healthcheck.test.bean.MemoryHealthChecker;
-import com.alipay.sofa.healthcheck.test.bean.MiddlewareHealthCheckCallback;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.ConcurrentHashMap;
/**
* @author liangen
@@ -120,6 +125,20 @@ public HealthCheckExecutor healthCheckExecutor(HealthCheckProperties properties)
}
}
+ @BeforeClass
+ public static void beforeClass() {
+ try {
+ Field f1 = SofaRuntimeProperties.class.getDeclaredField("manualReadinessCallbackMap");
+ f1.setAccessible(true);
+ Field modifiers = f1.getClass().getDeclaredField("modifiers");
+ modifiers.setAccessible(true);
+ modifiers.setInt(f1, f1.getModifiers() & ~Modifier.FINAL);
+ f1.set(SofaRuntimeProperties.class, new ConcurrentHashMap<>());
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+
@Test
public void testReadinessCheck() throws BeansException {
ReadinessCheckListener readinessCheckListener = applicationContext
diff --git a/sofa-boot-project/sofa-boot/src/main/java/com/alipay/sofa/boot/constant/SofaBootConstants.java b/sofa-boot-project/sofa-boot/src/main/java/com/alipay/sofa/boot/constant/SofaBootConstants.java
index 16be0292f..396046edb 100644
--- a/sofa-boot-project/sofa-boot/src/main/java/com/alipay/sofa/boot/constant/SofaBootConstants.java
+++ b/sofa-boot-project/sofa-boot/src/main/java/com/alipay/sofa/boot/constant/SofaBootConstants.java
@@ -200,11 +200,21 @@ public class SofaBootConstants {
*/
public static final String SOFABOOT_HEALTH_CHECK_NOT_READY_KEY = "HEALTH-CHECK-NOT-READY";
+ /**
+ * health check timeout key
+ */
+ public static final String SOFABOOT_HEALTH_CHECK_TIMEOUT_KEY = "HEALTH-CHECK-TIMEOUT";
+
/**
* health check not ready result
*/
public static final String SOFABOOT_HEALTH_CHECK_NOT_READY_MSG = "App is still in startup process, please try later!";
+ /**
+ * health check timeout result
+ */
+ public static final String SOFABOOT_HEALTH_CHECK_TIMEOUT_MSG = "Timeout when wait for readiness check result!";
+
/** framework constants **/
public static String APPLICATION = "SOFABOOT-APPLICATION";
public static String PROCESSORS_OF_ROOT_APPLICATION_CONTEXT = "PROCESSORS_OF_ROOT_APPLICATION_CONTEXT";