Appolo配置中心原理解读与部署实践(docker)

一/apollo简介

apollo是携程开源的一款企业级配置中心,功能比spring cloud config强大得多,解决配置变更操作特别是多服务多实例部署修改日志级别,促销限制,黑白名单,超时,功能开关等特别麻烦,无法动态变更即时生效并反馈成功与否,改代码重新上线耗时,不便于配置查看,apollo可以解决这些问题,并有权限控制及变更版本管理,统一集中管理不同环境,配置信息监听,开发api平台等功能。代码侵入很小,跟springcloud config差不多,但springcloud config需要依赖GIT操作不友好,设计简单,配置治理能力弱。另有阿里的nacos也是不错的选择。

二/原理图

配置中心会推送apollo客户端,且客户端会定时长轮询拉取最新配置,client端有jvm缓存与本地文件缓存,具有高可用性。Apollo配置中心内部结构图如下图:

  • portal是一个主要是web UI工程,它通过SLB软负载或直接根据metaServer地址从eureka找到adminserver暴露的配置CURD接口进行配置修改。
  • client端如springboot项目同理在eureka找到configserver暴露的端点进行配置查询。
  • adminserver与configserver通过上图双保险进行配置同步。
  • 注意:metaserver eureka是集成到configserver中的。

三/安装步骤

Github有详细等学习资源及集成步骤: https://github.com/ctripcorp/apollo

先到https://github.com/ctripcorp/apollo/tree/master/scripts/sql下载两个数据库脚本安装到mysql,然后进行三个核心模块安装。

方式1:wget zip包解压安装,地址https://github.com/ctripcorp/apollo/releases 

方式2:checkout本地打包安装,适合二次开发;可以利用项目的脚本构建镜像push到docker进行容器化安装,参考https://blog.csdn.net/qq_38983728/article/details/90108387

方式3:搜索docker search搜索可靠镜像进行安装,下面已方式3进行安装。


docker run -d \
-e spring_datasource_url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8 \
-e spring_datasource_username=root \
-e spring_datasource_password=xxx. \
-e server.port=8180 \ 
-e eureka.instance.ip-address=1XX.XX.0.205 \
-v /opt/logs:/opt/logs \
--network host \
--name apollo_configserver \
chenchuxin/apollo


docker run -d \
-e spring_datasource_url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8 \
-e spring_datasource_username=root \
-e spring_datasource_password=xxx. \
-e server.port=8190 \
-e eureka.instance.ip-address=1XX.XX.0.205 \
-v /opt/logs:/opt/logs \
--network host \
--name apollo_adminserver \
docker.io/akafra/apollo-adminservice

docker run -d \
-e spring_datasource_url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8 \
-e spring_datasource_username=root \
-e spring_datasource_password=xxx. \
-e SERVER_PORT=8170 \
-e DEV_META=http://1XX.XX.0.205:8180 \
-v /opt/logs:/opt/logs \ 
--network host \
--name apollo_portalserver \
docker.io/chrishoo/apollo-portal

注意:

a.默认端口8080 8090 8070改为8180 8190 8170避免冲突,注意修改修改ApolloConfigDB的serverConfig表的eureka的地址改为

configer服务的地址,这里端口应改为8180。(configserver服务包含eureka注册中心及metaserver两个逻辑角色,正常启动后访问localhost:8180可见eureka页面且注册了configserver /adminserver两个服务)

b.configserver  adminserver每个环境都要部署,portal只需要一套,注意各自链接的mysql数据库

c.docker inspect可发现前configserver/adminserver容器启动是Java -jar启动,参数-e eureka.instance.ip-address=1XX.XX.0.205 不配置可能导致多网卡环境,portal页面,日志文件报错client端不能正确找到admin/metaserver服务如图instanceID与homepageUrl不一致;portal是利用里面的startup.sh启动,- e DEV_META指定的是eureka地址(即configserver地址).

四/springboot项目集成,即时刷新

1/登录portal :http://localhost:8170  默认超级账号apollo/admin ,创建一个项目,关键是appid,它是一个应用的标识。

然后跳转到配置页面,先报了个“系统错误请联系管理员”?管理员不容易!!!,多刷新几下提示“当前环境有缺失,请点击左侧【补缺环境】”,点了之后就OK了。因为一个项目配置只能属于一个环境,默认只有DEV,需要其他环境在portal数据库表增加。

新增几个测试配置并发布:该配置属于appid=10086,env=DEV,namespace=application(默认)的配置,下面用Java client来获取这些参数并测试实时动态刷新。

 

springboot增加apollo客户端依赖

 <dependency>
            <groupId>com.ctrip.framework.apollo</groupId>
            <artifactId>apollo-client</artifactId>
            <version>1.4.0</version>
        </dependency>

配置文件配置文件apollo读取配置中心的url,appid为10086的配置信息,env环境一般在启动命令-Denv=DEV或在/opt/settings/server.properties指定(env=DEV)

app:
  id: 10086 # 使用的 Apollo 的项目(应用)编号
apollo:
  meta: http://127.0.0.1:8180 # Apollo Meta Server 地址
  bootstrap:
    enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。
    eagerLoad:
      enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。
    namespaces: application,TEST1.apollo # 使用的 Apollo 的命名空间,默认为 application(私有)。

java代码用@Value("${test1:111}")即可注入,并且是实时刷新的,有是我们需要把某些配置统一用一个bean来接收,需要@RefreshScope注解,并用一个监听器实现刷新

@Getter
@Setter
@ToString
@Slf4j
@ConditionalOnProperty("redis.cache.enabled")
@ConfigurationProperties(prefix = "redis.cache")
@Component("sampleRedisProperties") //定个beanName,监听器中根据beanName刷新
@RefreshScope  //需要刷新,还需要监听器配合
public class SampleRedisProperties {
  private int expireSeconds;
  private String clusterNodes;
  private int commandTimeout;
  @PostConstruct
  private void initialize() {
    log.info("**************初始化完毕>>>>:{}",this.toString());
  }
}
@Slf4j
@ConditionalOnProperty("redis.cache.enabled")
@Component
public class SpringBootApolloRefreshConfig {
    @Resource
    private SampleRedisProperties sampleRedisProperties;
    @Autowired
    private RefreshScope refreshScope;

    //监听apollo配置,可指定namespace,配置项前缀等
    @ApolloConfigChangeListener(value = {ConfigConsts.NAMESPACE_APPLICATION, "TEST1.apollo"}, interestedKeyPrefixes = {"redis.cache."})
    public void onChange(ConfigChangeEvent changeEvent) {
        //正式环境变更可考虑发邮件
        log.info("监听到配置项变化,{}", changeEvent.changedKeys());
        log.info("刷新前,{}", sampleRedisProperties.toString());
        refreshScope.refresh("sampleRedisProperties");//使用refreshScope对象刷新bean name为sampleRedisProperties的容器对象
        log.info("刷新后,{}", sampleRedisProperties.toString());
    }
}

日志级别的动态刷新

@Slf4j
@Component
public class LoggingSystemConfigListener {
    private static final String LOGGER_PREFIX = "logging.level.";
    @Autowired
    private LoggingSystem loggingSystem;
    @ApolloConfig
    private Config config;

    @ApolloConfigChangeListener
    public void onChange(ConfigChangeEvent changeEvent) throws Exception {
        log.info("监听到配置项变化,{}",changeEvent.changedKeys());
        Set<String> keys = config.getPropertyNames();
        for (String key : keys) {
            // 如果是 logging.level 配置项,则设置其对应的日志级别
            if (key.startsWith(LOGGER_PREFIX)) {
                String strLevel = config.getProperty(key, "info");
                LogLevel level = LogLevel.valueOf(strLevel.toUpperCase());
                loggingSystem.setLogLevel(key.replace(LOGGER_PREFIX, ""), level);
            }
        }
    }
}

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值