本文主要研究一下dubbo的DubboHealthIndicator
dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/health/DubboHealthIndicator.java
public class DubboHealthIndicator extends AbstractHealthIndicator { @Autowired private DubboHealthIndicatorProperties dubboHealthIndicatorProperties; @Autowired(required = false) private Map<String, ProtocolConfig> protocolConfigs = Collections.emptyMap(); @Autowired(required = false) private Map<String, ProviderConfig> providerConfigs = Collections.emptyMap(); @Override protected void doHealthCheck(Health.Builder builder) throws Exception { ExtensionLoader<StatusChecker> extensionLoader = getExtensionLoader(StatusChecker.class); Map<String, String> statusCheckerNamesMap = resolveStatusCheckerNamesMap(); boolean hasError = false; boolean hasUnknown = false; // Up first builder.up(); for (Map.Entry<String, String> entry : statusCheckerNamesMap.entrySet()) { String statusCheckerName = entry.getKey(); String source = entry.getValue(); StatusChecker checker = extensionLoader.getExtension(statusCheckerName); org.apache.dubbo.common.status.Status status = checker.check(); org.apache.dubbo.common.status.Status.Level level = status.getLevel(); if (!hasError && level.equals(org.apache.dubbo.common.status.Status.Level.ERROR)) { hasError = true; builder.down(); } if (!hasError && !hasUnknown && level.equals(org.apache.dubbo.common.status.Status.Level.UNKNOWN)) { hasUnknown = true; builder.unknown(); } Map<String, Object> detail = new LinkedHashMap<>(); detail.put("source", source); detail.put("status", status); builder.withDetail(statusCheckerName, detail); } } /** * Resolves the map of {@link StatusChecker}'s name and its' source. * * @return non-null {@link Map} */ protected Map<String, String> resolveStatusCheckerNamesMap() { Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>(); statusCheckerNamesMap.putAll(resolveStatusCheckerNamesMapFromDubboHealthIndicatorProperties()); statusCheckerNamesMap.putAll(resolveStatusCheckerNamesMapFromProtocolConfigs()); statusCheckerNamesMap.putAll(resolveStatusCheckerNamesMapFromProviderConfig()); return statusCheckerNamesMap; } private Map<String, String> resolveStatusCheckerNamesMapFromDubboHealthIndicatorProperties() { DubboHealthIndicatorProperties.Status status = dubboHealthIndicatorProperties.getStatus(); Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>(); for (String statusName : status.getDefaults()) { statusCheckerNamesMap.put(statusName, DubboHealthIndicatorProperties.PREFIX + ".status.defaults"); } for (String statusName : status.getExtras()) { statusCheckerNamesMap.put(statusName, DubboHealthIndicatorProperties.PREFIX + ".status.extras"); } return statusCheckerNamesMap; } private Map<String, String> resolveStatusCheckerNamesMapFromProtocolConfigs() { Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>(); for (Map.Entry<String, ProtocolConfig> entry : protocolConfigs.entrySet()) { String beanName = entry.getKey(); ProtocolConfig protocolConfig = entry.getValue(); Set<String> statusCheckerNames = getStatusCheckerNames(protocolConfig); for (String statusCheckerName : statusCheckerNames) { String source = buildSource(beanName, protocolConfig); statusCheckerNamesMap.put(statusCheckerName, source); } } return statusCheckerNamesMap; } private Map<String, String> resolveStatusCheckerNamesMapFromProviderConfig() { Map<String, String> statusCheckerNamesMap = new LinkedHashMap<>(); for (Map.Entry<String, ProviderConfig> entry : providerConfigs.entrySet()) { String beanName = entry.getKey(); ProviderConfig providerConfig = entry.getValue(); Set<String> statusCheckerNames = getStatusCheckerNames(providerConfig); for (String statusCheckerName : statusCheckerNames) { String source = buildSource(beanName, providerConfig); statusCheckerNamesMap.put(statusCheckerName, source); } } return statusCheckerNamesMap; } private Set<String> getStatusCheckerNames(ProtocolConfig protocolConfig) { String status = protocolConfig.getStatus(); return StringUtils.commaDelimitedListToSet(status); } private Set<String> getStatusCheckerNames(ProviderConfig providerConfig) { String status = providerConfig.getStatus(); return StringUtils.commaDelimitedListToSet(status); } private String buildSource(String beanName, Object bean) { return beanName + "@" + bean.getClass().getSimpleName() + ".getStatus()"; } }
dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/health/DubboHealthIndicatorTest.java
@RunWith(SpringRunner.class) @TestPropertySource(properties = { "dubbo.protocol.id = dubbo-protocol", "dubbo.protocol.name = dubbo", "dubbo.protocol.port = 12345", "dubbo.protocol.status = registry", "dubbo.provider.id = dubbo-provider", "dubbo.provider.status = server", "management.health.dubbo.status.defaults = memory", "management.health.dubbo.status.extras = load,threadpool" }) @SpringBootTest( classes = { DubboHealthIndicator.class, DubboHealthIndicatorTest.class } ) @EnableConfigurationProperties(DubboHealthIndicatorProperties.class) @EnableDubboConfig public class DubboHealthIndicatorTest { @Autowired private DubboHealthIndicator dubboHealthIndicator; @Test public void testResolveStatusCheckerNamesMap() { Map<String, String> statusCheckerNamesMap = dubboHealthIndicator.resolveStatusCheckerNamesMap(); Assert.assertEquals(5, statusCheckerNamesMap.size()); Assert.assertEquals("dubbo-protocol@ProtocolConfig.getStatus()", statusCheckerNamesMap.get("registry")); Assert.assertEquals("dubbo-provider@ProviderConfig.getStatus()", statusCheckerNamesMap.get("server")); Assert.assertEquals("management.health.dubbo.status.defaults", statusCheckerNamesMap.get("memory")); Assert.assertEquals("management.health.dubbo.status.extras", statusCheckerNamesMap.get("load")); Assert.assertEquals("management.health.dubbo.status.extras", statusCheckerNamesMap.get("threadpool")); } @Test public void testHealth() { Health health = dubboHealthIndicator.health(); Assert.assertEquals(Status.UNKNOWN, health.getStatus()); } }
dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/health/DubboHealthIndicatorProperties.java
@ConfigurationProperties(prefix = PREFIX, ignoreUnknownFields = false) public class DubboHealthIndicatorProperties { /** * The prefix of {@link DubboHealthIndicatorProperties} */ public static final String PREFIX = "management.health.dubbo"; private Status status = new Status(); public Status getStatus() { return status; } public void setStatus(Status status) { this.status = status; } /** * The nested class for {@link StatusChecker}'s names * <pre> * registry= org.apache.dubbo.registry.status.RegistryStatusChecker * spring= org.apache.dubbo.config.spring.status.SpringStatusChecker * datasource= org.apache.dubbo.config.spring.status.DataSourceStatusChecker * memory= org.apache.dubbo.common.status.support.MemoryStatusChecker * load= org.apache.dubbo.common.status.support.LoadStatusChecker * server= org.apache.dubbo.rpc.protocol.dubbo.status.ServerStatusChecker * threadpool= org.apache.dubbo.rpc.protocol.dubbo.status.ThreadPoolStatusChecker * </pre> * * @see StatusChecker */ public static class Status { /** * The defaults names of {@link StatusChecker} * <p> * The defaults : "memory", "load" */ private Set<String> defaults = new LinkedHashSet<>(Arrays.asList("memory", "load")); /** * The extra names of {@link StatusChecker} */ private Set<String> extras = new LinkedHashSet<>(); public Set<String> getDefaults() { return defaults; } public void setDefaults(Set<String> defaults) { this.defaults = defaults; } public Set<String> getExtras() { return extras; } public void setExtras(Set<String> extras) { this.extras = extras; } } }