前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊dubbo的DubboHealthIndicator

聊聊dubbo的DubboHealthIndicator

原创
作者头像
code4it
修改2019-08-19 17:07:27
4490
修改2019-08-19 17:07:27
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下dubbo的DubboHealthIndicator

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

代码语言:javascript
复制
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()";
    }
​
}
  • DubboHealthIndicator继承了AbstractHealthIndicator,这里注入了dubboHealthIndicatorProperties、protocolConfigs、providerConfigs
  • doHealthCheck方法会先获取StatusChecker的ExtensionLoader,然后通过resolveStatusCheckerNamesMap方法获取statusCheckerNamesMap,之后遍历该map根据statusCheckerName获取checker,然后执行check获取status及level,构建detail
  • resolveStatusCheckerNamesMap方法分别通过resolveStatusCheckerNamesMapFromDubboHealthIndicatorProperties、resolveStatusCheckerNamesMapFromProtocolConfigs、resolveStatusCheckerNamesMapFromProviderConfig来组装statusCheckerNamesMap

DubboHealthIndicatorTest

dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/actuator/src/test/java/org/apache/dubbo/spring/boot/actuate/health/DubboHealthIndicatorTest.java

代码语言:javascript
复制
@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());
​
    }
}
  • DubboHealthIndicatorTest验证了resolveStatusCheckerNamesMap及dubboHealthIndicator.health()方法

DubboHealthIndicatorProperties

dubbo-spring-boot-project-2.7.3/dubbo-spring-boot-compatible/actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/health/DubboHealthIndicatorProperties.java

代码语言:javascript
复制
@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;
        }
    }
​
}
  • DubboHealthIndicatorProperties定义了Status,其定义了defaults、extras字段

小结

  • DubboHealthIndicator继承了AbstractHealthIndicator,这里注入了dubboHealthIndicatorProperties、protocolConfigs、providerConfigs
  • doHealthCheck方法会先获取StatusChecker的ExtensionLoader,然后通过resolveStatusCheckerNamesMap方法获取statusCheckerNamesMap,之后遍历该map根据statusCheckerName获取checker,然后执行check获取status及level,构建detail
  • resolveStatusCheckerNamesMap方法分别通过resolveStatusCheckerNamesMapFromDubboHealthIndicatorProperties、resolveStatusCheckerNamesMapFromProtocolConfigs、resolveStatusCheckerNamesMapFromProviderConfig来组装statusCheckerNamesMap

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DubboHealthIndicator
  • DubboHealthIndicatorTest
  • DubboHealthIndicatorProperties
  • 小结
  • doc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档