暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

配置管理中心

AweSomeBaZinGa 2019-09-03
322


配置管理中心

一、为什么需要配置管理中心

  • 随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址……

  • 并且对配置的期望也越来越高,配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……

  • 并且随着采用分布式的开发模式,项目之间的相互引用随着服务的不断增多,相互之间的调用复杂度成指数升高,每次投产或者上线新的项目时苦不堪言,因此需要引用配置中心治理。

二、配置管理中心对比

1、功能特性

2、兼容性

3、可用性和易用性

4、ApolloNacos对比

结论:选择Apollo

[官网地址]    https://github.com/ctripcorp/apollo 

Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

三、Apollo

1、基础模型

如下即是Apollo的基础模型:

  1. 用户在配置中心对配置进行修改并发布

  2. 配置中心通知Apollo客户端有配置更新

  3. Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用

2、架构模块

上图简要描述了Apollo的总体设计,我们可以从下往上看:

  • Config Service提供配置的读取、推送等功能,服务对象是Apollo客户端

  • Admin Service提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)

  • Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳

  • 在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口

  • Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试

  • Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试

  • 为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中

总结:重要的组件有apollo-configservice、apollo-adminservice、apollo-portal、apollo-client

3、工作流程图

用户在Portal操作配置发布Portal调用Admin Service的接口操作发布Admin Service发布配置后,发送ReleaseMessage给各个Config ServiceConfig Service收到ReleaseMessage后,通知对应的客户端

4、客户端设计

上图简要描述了Apollo客户端的实现原理:

  1. 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。(通过Http Long Polling实现)

  2. 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。

  • 这是一个fallback机制,为了防止推送机制失效导致配置不更新

  • 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified

  • 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval
    来覆盖,单位为分钟。

  • 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中

  • 客户端会把从服务端获取到的配置在本地文件系统缓存一份

    • 在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置

  • 应用程序可以从Apollo客户端获取最新的配置、订阅配置更新通知

  • 四、Apollo实战

    1、部署Apollo

    Apollo的部署官网有非常详细的教程,这里不再详细描述,只提本地化的东西。

    1.1数据库

    apollo的数据是一个portal数据库配合多个不同环境的config数据库使用,portal管理多个环境。部署成功后如果是多个环境需要修改数据库配置。

    修改apolloportaldb的serverconfig表中的apollo.portal.envs和configView.memberOnly.envs,默认支持四个环境(DEV,UAT,FAT,PRO),逗号隔开,更多环境的配置参考官方Wiki中的《部署&开发遇到的常见问题》

    修改apolloconfigdb的serverconfig表中的eureka.service.url,多个地址用逗号分隔

    1.2应用

    应用暂时无需修改,如果需要修改,参考官方Wiki中的《分部署部署指南》

    2、使用Apollo

    2.1环境地址配置

    方式一:通过环境配置文件/opt/data/settings.properties

    apollo.meta=http://127.0.0.1:8080
    复制

    方式二:通过工程内配置文件apollo-env.properties

    dev.meta=http://127.0.0.1:8080
    复制
    2.2环境应用配置

    通过环境配置文件/opt/data/settings.properties

    方式一:通过启动参数

    -Denv=YOUR-ENVIRONMENT
    复制

    方式二:通过环境配置文件/opt/data/settings.properties

    env=DEV
    复制
    2.3集群配置(可选)

    通过环境配置文件/opt/data/settings.properties

    idc=xxx
    复制
    2.4缓存配置

    默认缓存路径/opt/data/cache,无需修改

    2.5AppId配置

    通过application.yml

    app:
    id: 100000001
    复制
    2.6引入依赖
    <!-- apollo support -->
    <dependency>
     <groupId>com.ctrip.framework.apollo</groupId>
     <artifactId>apollo-client</artifactId>
     <version>1.4.0</version>
    </dependency>
    复制
    2.7客户端使用

    客户端使用默认支持很多种方式,api,spring,springboot,dubbo等等,推荐参考官网案例即可

    [案列]    https://github.com/ctripcorp/apollo-use-cases 

    此处选择springboot说明

    2.7.1配置
    apollo:
    bootstrap:
       #设置apollo在启动阶段就加载配置
      enabled: true
       #注入namespace的配置
      namespaces: application,LCGLB.application,LCGLB.jwt,LCGLB.aeskey,datasources.yml,workflow.yml,sleuth.yml
       #将apollo配置加载提到初始化日志系统之前  
      eagerLoad:
        enabled: true
    复制
    2.7.2配置解析器

    解决读取复杂yml读取失败的问题

    启动类中注册Bean

    @Bean
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer () {
     return new PropertySourcesPlaceholderConfigurer();
    }
    复制
    2.7.3配置文件
    /**
    * jwt配置文件读取类
    *
    * @author zhangwy
    * @date 2019-03-26
    *
    * */
    @Configuration
    @ConfigurationProperties(ignoreInvalidFields=true, ignoreUnknownFields=true, prefix="jwt")
    @EnableApolloConfig
    @Component("jwtConfig")
    @RefreshScope
    @Data
    public class JwtConfig {
    private String secretkey;
    }
    复制
    2.7.4配置自定刷新
    /**
    * @author zhangwy
    */
    @Component
    public class SpringBootApolloRefreshConfig {
    private static final Logger logger = LoggerFactory.getLogger(SpringBootApolloRefreshConfig.class);

    private final RefreshScope refreshScope;

    public SpringBootApolloRefreshConfig(final RefreshScope refreshScope) {
    this.refreshScope = refreshScope;
    }

    @Autowired
    DataSourceProps dataSourceProps;

    @Autowired
    WorkflowConfig workflowConfig;

    @Autowired
    SamplerLocalProperties samplerLocalProperties;

    @ApolloConfigChangeListener(value = { ConfigConsts.NAMESPACE_APPLICATION, "LCGLB.jwt", "LCGLB.aeskey", "LCGLB.application", "datasources.yml", "workflow.yml", "sleuth.yml" })
    public void onChange(ConfigChangeEvent changeEvent) {
    logger.info("dataSourceProps before refresh {}", dataSourceProps.toString());
    logger.info("workflowConfig before refresh {}", workflowConfig.toString());
    refreshScope.refresh("jwtConfig");
    refreshScope.refresh("aesConfig");
    refreshScope.refresh("dataSourceProps");
    refreshScope.refresh("workflowConfig");
    refreshScope.refresh("samplerLocalProperties");
    logger.info("dataSourceProps after refresh {}", dataSourceProps.toString());
    logger.info("workflowConfig after refresh {}", workflowConfig.toString());
    }
    }
    复制

    3、开放平台

    [参考官网]    https://github.com/ctripcorp/apollo/wiki/Apollo%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0 


    文章转载自AweSomeBaZinGa,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论