美文网首页
基于Spring Cloud 服务治理组件开发心得

基于Spring Cloud 服务治理组件开发心得

作者: NealLemon | 来源:发表于2020-03-22 20:28 被阅读0次

Spring Cloud 近几年非常火,是微服务架构一站式解决方案,但是在某些特定场景的服务治理上还是有些欠缺,开源的强大就是我们可以站在巨人的肩膀上实现定制化功能。目前我也在我司的平台组进行相关微服务组件开发,对于遇到的需求和问题经过思考等整理了一些东西,为以后组件优化和升级做铺垫。

针对基于Eureka注册中心的扩展

目前比较流行的还是 Spring Cloud Netflix 这一套,因此可以利用Eureka注册中心做很大部分的扩展,本次就简单减少一下如何将自定义的元信息发布到Eureka上。

元数据的注册

之前有一篇文章聊到 Eureka Client 源码 , 我们就基于这一篇在简单的讲解一下思路。在org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration 这个配置类中我们可以看到下面这一段代码

    @Bean
    @ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
    public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils,
            ManagementMetadataProvider managementMetadataProvider) {
        //省略代码
        
        /**
        * 这段代码就是本地初始化元数据的地方了 
        *
        **/
        if (metadata != null) {
            instance.setStatusPageUrl(metadata.getStatusPageUrl());
            instance.setHealthCheckUrl(metadata.getHealthCheckUrl());
            if (instance.isSecurePortEnabled()) {
                instance.setSecureHealthCheckUrl(metadata.getSecureHealthCheckUrl());
            }
            //我们可以使用 metadataMap 进行元数据的添加
            Map<String, String> metadataMap = instance.getMetadataMap();
            metadataMap.computeIfAbsent("management.port",
                    k -> String.valueOf(metadata.getManagementPort()));
        }
        else {
            // without the metadata the status and health check URLs will not be set
            // and the status page and health check url paths will not include the
            // context path so set them here
            if (StringUtils.hasText(managementContextPath)) {
                instance.setHealthCheckUrlPath(
                        managementContextPath + instance.getHealthCheckUrlPath());
                instance.setStatusPageUrlPath(
                        managementContextPath + instance.getStatusPageUrlPath());
            }
        }

        setupJmxPort(instance, jmxPort);
        return instance;
    }

根据上面的代码,我们可以很轻松的看出添加元数据的地方,但是我们可以看到这个Bean的注册是不支持覆盖的。因此我们如果想要扩展还需要在注册Bean的地方下功夫,我这里是这样想的,重写一个配置 EurekaInstanceConfigBean 的Bean 在EurekaClientAutoConfiguration并 将其设置为 @Primary 。这样后续的组件的依赖注入会采取咱们自定义的Bean,当然这样比较暴露。还有一种是在该组件初始化完成后,注册到Eureka之前,将其内容修改,这样做到了 解耦,无论Spring Cloud 如何更新,不影响我们元数据注册。

元数据的获取

这里获取元数据的接口,个人建议是直接用Spring Cloud原生的 组件去获取,主要就是 DiscoveryClient这个接口。我们可以简单的看一下其中的一个实现类。

EurekaDiscoveryClient 中的两个方法

//  获取其元数据
    @Override
    public List<ServiceInstance> getInstances(String serviceId) {
        List<InstanceInfo> infos = this.eurekaClient.getInstancesByVipAddress(serviceId,
                false);
        List<ServiceInstance> instances = new ArrayList<>();
        for (InstanceInfo info : infos) {
            instances.add(new EurekaServiceInstance(info));
        }
        return instances;
    }

//获取所有注册服务实例名
    @Override
    public List<String> getServices() {
        Applications applications = this.eurekaClient.getApplications();
        if (applications == null) {
            return Collections.emptyList();
        }
        List<Application> registered = applications.getRegisteredApplications();
        List<String> names = new ArrayList<>();
        for (Application app : registered) {
            if (app.getInstances().isEmpty()) {
                continue;
            }
            names.add(app.getName().toLowerCase());

        }
        return names;
    }

我们可以自己实现组件,获取其对应的 注册Client ,然后通过实例名获取其实例的信息。

小结

其实通过我们自定义的元数据,可以做相当多的微服务扩展,通过原生的Spring Cloud 组件的接口方法,去做定制化开发,这样可以做到不管Spring Cloud 如何更新,接口大部分的情况下是不会改变的,因此减少了升级整合的工作量,做开发适应自己公司业务的微服务平台。这里就不一一举例了,其实就是一种新的元数据管理方式,通过注册中心,动态的更新到每一个微服务上,这里注意,跟微服务的统一配置是有区别的。

相关文章

网友评论

      本文标题:基于Spring Cloud 服务治理组件开发心得

      本文链接:https://www.haomeiwen.com/subject/xwtbyhtx.html