Apollo 统一配置中心总结

java哥 阅读:279 2021-06-16 22:05:10 评论:0

Apollo(阿波罗)是携程框架部门研发的开源配置管理中心

能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性

地址 IT虾米网

特性

统一管理不同环境、不同集群的配置 
配置修改实时生效(热发布) 
版本发布管理 
灰度发布 
权限管理、发布审核、操作审计 
客户端配置信息监控 
提供Java和.Net原生客户端 
提供开放平台API 
部署简单

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进程中

1.搭建 Apollo 配置中心

参照 https://github.com/ctripcorp/apollo/wiki/Quick-Start 

  (1)下载Quick Start安装包

  (2)创建Apollo服务端需要两个数据库

    ApolloPortalDB

    ApolloConfigDB

  (3)解压Quick Start安装包,修改demo.sh数据库配置

# apollo config db info 
apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8 
apollo_config_db_username=root 
apollo_config_db_password=root 
 
# apollo portal db info 
apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8 
apollo_portal_db_username=root 
apollo_portal_db_password=root

  (4)服务启动与关闭

在git下执行启动脚本

./demo.sh start

关闭

./demo.sh stop

  (5)浏览器打开http://localhost:8070/

 

   输入用户名 apollo,密码 admin

http://localhost:8080/

 2.spring boot集成

  (1)依赖

<dependencies> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-web</artifactId> 
        </dependency> 
        <dependency> 
        <groupId>com.ctrip.framework.apollo</groupId> 
            <artifactId>apollo-client</artifactId> 
            <version>1.6.0</version> 
        </dependency> 
        <!-- 为了编码方便,并非apollo 必须的依赖 --> 
        <dependency> 
            <groupId>org.apache.commons</groupId> 
            <artifactId>commons-lang3</artifactId> 
            <version>3.8.1</version> 
        </dependency> 
</dependencies> 
<dependencyManagement> 
        <dependencies> 
            <dependency> 
                <groupId>com.ctrip.framework.apollo</groupId> 
                <artifactId>apollo-client</artifactId> 
                <version>1.2.0</version> 
            </dependency> 
        </dependencies> 
</dependencyManagement>

  (2)启动类

package com.xyz.provider; 
 
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
 
@SpringBootApplication 
@EnableApolloConfig 
public class ProviderApplication { 
 
    public static void main(String[] args) { 
        SpringApplication.run(ProviderApplication.class, args); 
    } 
 
}

  (3)配置

server.port=8010 
spring.application.name=service-provider 
# 应用全局唯一的身份标识 
app.id = springboot-apollo 
# Apollo Meta Server 地址 
apollo.meta = http://localhost:8080 
# 自定义本地配置文件缓存路径 
apollo.cacheDir = ./config 
# 设置在应用启动阶段就加载 Apollo 配置 
apollo.bootstrap.enabled = true 
# 注入 application namespace 
apollo.bootstrap.namespaces = application 
apollo.bootstrap.eagerLoad.enabled = true 
logging.level.com.xyz.provider.controller=debug 
order.discount = 75

说明:

app.id:AppId是应用的身份信息,是配置中心获取配置的一个重要信息 
apollo.bootstrap.enabled:在应用启动阶段,向Spring容器注入被托管的application.properties文件的配置信息 
apollo.bootstrap.eagerLoad.enabled:将Apollo配置加载提到初始化日志系统之前 
logging.level.com.xyz.provider.controller:调整 controller 包的 log 级别,用来在配置中心动态配置日志级别

  (4)控制器

package com.xyz.provider.controller; 
 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.web.bind.annotation.GetMapping; 
import org.springframework.web.bind.annotation.RestController; 
 
@RestController 
public class HelloController { 
 
    private static Logger logger = LoggerFactory.getLogger(HelloController.class); 
 
    @Value("${server.port}") 
    String port; 
    @Value(("${order.discount}")) 
    Integer discount; 
 
    @GetMapping("hello") 
    public String hello(String name) { 
 
        logger.debug("debug log..."); 
        logger.info("info log..."); 
        logger.warn("warn log..."); 
        return "hello " + name + " ,i am from port:" + port + ",discount:" + discount; 
    } 
 
}

    启动项目

GET http://localhost:8010/hello?name=beibei

返回 

hello beibei ,i am from port:8011,discount:75

  (5)配置

    创建项目

 说明:

部门:选择应用所在的部门 
应用AppId:用来标识应用身份的唯一id,格式为string,需要和客户端application.properties中配置的app.id对应 
应用名称:应用名,仅用于界面展示 
应用负责人:选择的人默认会成为该项目的管理员,具备项目权限管理、集群创建、Namespace创建等权限

  新增配置

     发布配置

    编辑完配置后,需要发布配置,才能生效

   发布后再次请求http://localhost:8010/hello?name=beibei

  返回 hello beibei ,i am from port:8011,discount:50

说明:

  服务的端口依然还是 8010,因为 apollo 修改配置,不会像Spring Cloud Config 那样去重启应用

  重启应用后,客户端会使用配置中心中配置的端口

GET http://localhost:8011/hello?name=beibei  
返回
hello beibei ,i am from port:8011,discount:50
控制台输出

2020-05-27 11:19:48.064 DEBUG 14880 --- [nio-8011-exec-1] c.x.provider.controller.HelloController : debug log...
2020-05-27 11:19:48.064 INFO 14880 --- [nio-8011-exec-1] c.x.provider.controller.HelloController : info log...
2020-05-27 11:19:48.064 WARN 14880 --- [nio-8011-exec-1] c.x.provider.controller.HelloController : warn log...

  配置日志等级

说明:

  在配置中心修改日志等级,发布后也没法立即生效,需要重启应用

重启后

GET http://localhost:8011/hello?name=beibei  
控制台输出

2020-05-27 11:21:57.780 INFO 13200 --- [nio-8011-exec-1] c.x.provider.controller.HelloController : info log...
2020-05-27 11:21:57.780 WARN 13200 --- [nio-8011-exec-1] c.x.provider.controller.HelloController : warn log...

  添加监听

package com.xyz.provider.config; 
 
import com.ctrip.framework.apollo.Config; 
import com.ctrip.framework.apollo.model.ConfigChangeEvent; 
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig; 
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener; 
import org.apache.commons.lang3.StringUtils; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.logging.LogLevel; 
import org.springframework.boot.logging.LoggingSystem; 
import org.springframework.context.annotation.Configuration; 
 
import javax.annotation.PostConstruct; 
import java.util.Set; 
 
@Configuration 
public class LoggerConfig { 
 
    private static final Logger logger = LoggerFactory.getLogger(LoggerConfig.class); 
    private static final String LOGGER_TAG = "logging.level."; 
 
    @Autowired 
    private LoggingSystem loggingSystem; 
 
    @ApolloConfig 
    private Config config; 
 
    @ApolloConfigChangeListener 
    private void configChangeListter(ConfigChangeEvent changeEvent) { 
        refreshLoggingLevels(); 
    } 
 
    @PostConstruct 
    private void refreshLoggingLevels() { 
        Set<String> keyNames = config.getPropertyNames(); 
        for (String key : keyNames) { 
            if (StringUtils.containsIgnoreCase(key, LOGGER_TAG)) { 
                String strLevel = config.getProperty(key, "info"); 
                LogLevel level = LogLevel.valueOf(strLevel.toUpperCase()); 
                loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level); 
                logger.info("{}:{}", key, strLevel); 
            } 
        } 
    } 
 
}

说明:

@ApolloConfig注解:将Apollo服务端的中的配置注入到这个类中 
@ApolloConfigChangeListener注解:监听配置中心配置的更新事件,若该事件发生,则调用refreshLoggingLevels方法处理该事件 
ConfigChangeEvent:获取被修改配置项的key集合,以及被修改配置项的新值、旧值和修改类型等信息
重启项目应用
修改配置logging.level.com.xyz.provider.controller为warn
GET http://localhost:8011/hello?name=beibei  
控制台输出

2020-05-27 11:26:18.211  WARN 4636 --- [nio-8011-exec-4] c.x.provider.controller.HelloController  : warn log...

Apollo与SpringCloud Config的对比
   Apollo  Spring Cloud Config
 配置界面  同一界面管理不同环境/集群配置  无,通过git操作
 配置生效时间  实时  重启生效,或Refresh,git hook+MQ
 版本管理  界面尚志杰提供发布历史和回滚按钮  无
 灰度发布  支持  不支持
 授权/审计/审核  界面直接操作,且支持修改和发布权限分离  需要通过git仓库设置,且不支持修改和发布权限分离
 实时配置监控 可以方便看到当前那些客户端在使用哪些配置   不支持
 配置获取性能  快  较慢
 客户端支持  原生支持Java/.Net,提供API,支持Spring annotation  Spring应用+annotation支持
 

Apollo是企业生产级配置中心,使用范围更广


标签:java
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
关注我们