原文:https://www.jianshu.com/p/23d695af7e80

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

服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。

Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。

.Net客户端不依赖任何框架,能够运行于所有.Net运行时环境。

如果想要深入了解,可以到github上参见Apollo配置中心,官网的介绍很详细。本章主要讲述Spring Boot 2.0 整合Apollo配置中心。

一、Apollo配置中心服务端(来源于官网)

本文的重点在于Apollo在客户端的使用,所以Apollo服务端使用的是官网提供的 Quick Start(针对本地测试使用),后续文章会专门讲述Apollo服务端在分布式环境下的部署。

1.1 准备工作

  1. Java
    Apollo服务端要求Java 1.8+,客户端要求Java 1.7+,笔者本地使用的是Java 1.8。
  2. MySQL
    Apollo的表结构对timestamp使用了多个default声明,所以需要5.6.5以上版本。笔者本地使用的是8.0.13版本
  3. 下载 Quick Start
    官网为我们准备了 Quick Start 安装包。大家只需要下载到本地,就可以直接使用,免去了编译、打包过程。大家可以到github下载,也可以通过百度云盘下载

1.2 安装步骤

1.2.1 创建数据库

Apollo服务端共需要两个数据库:ApolloPortalDB和ApolloConfigDB,官网把数据库、表的创建和样例数据都分别准备了sql文件(在下载的 Quick Start 安装包的sql目录下),只需要导入数据库即可。

1.2.1.1 创建ApolloPortalDB

通过各种Mysql客户端(Navicat,DataGrip等)导入sql/apolloportaldb.sql即可
下面以MySQL原生客户端为例:

source /your_local_path/sql/apolloportaldb.sql

导入成功后,可以通过执行以下sql语句来验证:

select `Id`, `AppId`, `Name` from ApolloPortalDB.App;
Id AppId Name
1 SampleApp Sample App
1.2.1.2 创建ApolloConfigDB

通过各种Mysql客户端(Navicat,DataGrip等)导入sql/apolloconfigdb.sql即可
下面以MySQL原生客户端为例:

source /your_local_path/sql/apolloconfigdb.sql

导入成功后,可以通过执行以下sql语句来验证:

select `NamespaceId`, `Key`, `Value`, `Comment` from ApolloConfigDB.Item;
NamespaceId Key Value Comment
1 timeout 100 sample timeout配置

1.2.2 配置数据库连接信息

Apollo服务端需要知道如何连接到你前面创建的数据库,所以需要编辑demo.sh,修改ApolloPortalDB和ApolloConfigDB相关的数据库连接串信息。

#apollo config db info
apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=用户名
apollo_config_db_password=密码(如果没有密码,留空即可) # apollo portal db info
apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=用户名
apollo_portal_db_password=密码(如果没有密码,留空即可)

1.3 启动Apollo配置中心

1.3.1 确保端口未被占用

Quick Start脚本会在本地启动3个服务,分别使用8070, 8080, 8090端口,请确保这3个端口当前没有被使用。例如,在Linux/Mac下,可以通过如下命令检查:

lsof -i:8080

在windows下,可以通过如下命令检查:

netstat -aon|findstr "8080"

1.3.2 执行启动脚本

在Quick Start目录下执行如下命令:

./demo.sh start

当看到如下输出后,就说明启动成功了!

==== starting service ====
Service logging file is ./service/apollo-service.log
Started [10768]
Waiting for config service startup.......
Config service started. You may visit http://localhost:8080 for service status now!
Waiting for admin service startup....
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Started [10846]
Waiting for portal startup......
Portal started. You can visit http://localhost:8070 now!

1.3.3 异常排查

如果启动遇到了异常,可以分别查看service和portal目录下的log文件排查问题。

注: 在启动apollo-configservice的过程中会在日志中输出eureka注册失败的信息,如com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused。需要注意的是,这个是预期的情况,因为apollo-configservice需要向Meta Server(它自己)注册服务,但是因为在启动过程中,自己还没起来,所以会报这个错。后面会进行重试的动作,所以等自己服务起来后就会注册正常了。

1.4 使用Apollo配置中心

1.4.1 查看样例配置

  1. 浏览器访问http://localhost:8070

    登录界面

    Quick Start集成了Spring Security简单认证,更多信息可以参考Portal 实现用户登录功能

  2. 输入用户名apollo,密码admin登录

    项目界面

    配置中心中包含一个默认的项目SampleApp

  3. 点击SampleApp进入配置界面,可以看到当前有一个配置timeout=100

    项目配置详情

    如果提示系统出错,请重试或联系系统负责人,请稍后几秒钟重试一下,因为通过Eureka注册的服务有一个刷新的延时。

1.4.2 新增项目配置

我们的客户端使用apollo需要新增相关的项目配置。

  1. 点击新建项目

    项目信息
    • 应用ID:这个ID是应用的唯一标识
    • 应用名称:应用的名称,会展示在配置中心的首页上

    点击提交,创建完成

    应用配置界面
  2. 新增配置信息

    点击新增配置,填写配置信息

    配置信息

    点击提交,此时配置还未生效。

    未发布的配置
  3. 发布配置
    点击发布,配置立刻生效

    生效的配置
  4. 回滚
    如果配置做了修改之后,发现配置更改错误,这个时候可以使用回滚功能,回到上一个配置

    回滚配置

二、Apollo配置中心客户端

我们客户端基于Spring Boot 2.0搭建,开发工具是InteIIij IDEA。新建一个项目,项目名称为apollo-client

2.1 客户端搭建

  1. 添加Apollo客户端依赖

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

    目前最新版本为1.1.1

  2. 添加配置信息
    # 应用ID(在Apollo服务端新增项目添加的应用ID)
    app.id=testclient
    # apollo-configservice地址
    apollo.meta=http://127.0.0.1:8080
  3. 开启Apollo客户端
    在项目的启动类上添加@EnableApolloConfig注解
  4. 新增一个测试接口
  @RequestMapping("/index")
public String hello(){
return "hello man";
}
  1. 启动服务测试
    在Apollo配置中心中,我们对该项目有一条配置server.port = 9000,启动服务,访问http://localhost:9000/index,返回hello man。证明,客户端是从服务端获取的配置。

2.2 客户端用法

在上一节,我们简单的搭建了客户端,成功的使用服务端配置。Apollo为我们提供的使用方式有很多种,下面只介绍Spring Boot 2.0环境下的使用方式。

2.2.1 Spring Placeholder的使用

Spring应用通常会使用Placeholder来注入配置,使用的格式形如${someKey:someDefaultValue},如${timeout:100}。冒号前面的是key,冒号后面的是默认值(建议在实际使用时尽量给出默认值,以免由于key没有定义导致运行时错误)。Apollo从v0.10.0开始的版本支持placeholder在运行时自动更新。如果需要关闭placeholder在运行时自动更新功能,可以通过以下两种方式关闭:

  1. 通过设置System Property apollo.autoUpdateInjectedSpringProperties,如启动时传入-Dapollo.autoUpdateInjectedSpringProperties=false
  2. 通过设置META-INF/app.properties中的apollo.autoUpdateInjectedSpringProperties=false
2.2.1.1 Java Config使用方式
  1. 新建配置类JavaConfigBean如下:

    /**
    * Java Config方式
    *
    * @author simon
    * @create 2018-11-02 15:00
    **/
    @Configuration
    public class JavaConfigBean {
    @Value("${timeout:20}")
    private int timeout; public int getTimeout() {
    return timeout;
    }
    }
  2. 新增访问端点
      //1.Java Config方式
    @Autowired
    JavaConfigBean javaConfigBean; @RequestMapping("/index1")
    public String hello1(){
    return javaConfigBean.getTimeout()+"";
    }
  3. 测试
    浏览器访问http://127.0.0.1:8080/index1,正确返回配置的值
2.2.1.2 ConfigurationProperties使用方式

Spring Boot提供了@ConfigurationProperties把配置注入到bean对象中。Apollo也支持这种方式,下面的例子会把redis.cache.expireSecondsredis.cache.commandTimeout分别注入到SampleRedisConfigexpireSecondscommandTimeout字段中。

  1. 新增配置类SampleRedisConfig如下:

    /**
    * ConfigurationProperties使用方式
    *
    * @author simon
    * @create 2018-11-02 9:30
    **/
    @Configuration
    @ConfigurationProperties(prefix = "redis.cache")
    public class SampleRedisConfig {
    private int expireSeconds;
    private int commandTimeout; public void setExpireSeconds(int expireSeconds) {
    this.expireSeconds = expireSeconds;
    } public void setCommandTimeout(int commandTimeout) {
    this.commandTimeout = commandTimeout;
    } public int getExpireSeconds() {
    return expireSeconds;
    } public int getCommandTimeout() {
    return commandTimeout;
    }
    }
  2. 新增访问端点
    //2. ConfigurationProperties使用方式
    @Autowired
    SampleRedisConfig sampleRedisConfig; @RequestMapping("/index2")
    public String hello2(){
    return sampleRedisConfig.getCommandTimeout()+"--"+sampleRedisConfig.getExpireSeconds();
    }
  3. 测试
    浏览器访问http://127.0.0.1:8080/index2,正确返回配置的值

注: @ConfigurationProperties如果需要在Apollo配置变化时自动更新注入的值,需要配合使用EnvironmentChangeEventRefreshScope。这个我会在后续文章中详细描述。

2.2.2 Spring Annotation支持

Apollo同时还增加了几个新的Annotation来简化在Spring环境中的使用。

  • @ApolloConfig用来自动注入Config对象
  • @ApolloConfigChangeListener用来自动注册ConfigChangeListener
  • @ApolloJsonValue用来把配置的json字符串自动注入为对象
2.2.2.1 @ApolloConfig的使用
  1. 新增访问端点

    // 3. @ApolloConfig使用
    @ApolloConfig
    private Config config; @RequestMapping("/index3")
    public String hello3(){
    Set <String> propertyNames = config.getPropertyNames();
    propertyNames.forEach(key -> {
    System.err.println(key+"="+config.getIntProperty(key,0));
    });
    return propertyNames.toString();
    }
  2. 测试
    浏览器访问http://127.0.0.1:8080/index3,正确打印配置的值

    redis.cache.commandTimeout=3000
    redis.cache.expireSeconds=20
    server.port=800
    timeout=200
2.2.2.2 @ApolloConfigChangeListener的使用
  1. 新增以下代码

    @ApolloConfigChangeListener
    private void someOnChange(ConfigChangeEvent changeEvent) {
    //update injected value of batch if it is changed in Apollo
    if (changeEvent.isChanged("timeout")) {
    System.out.println(config.getIntProperty("timeout", 0));
    }
    }
  2. 测试
    在Apollo服务端修改timeout配置的值为300,发布后,控制台打印300
2.2.2.3 @ApolloJsonValue的使用
  1. 新增User如下:

    /**
    * 用户
    *
    * @author simon
    * @create 2018-11-02 16:41
    **/
    public class User {
    private String username;
    private String password; public String getUsername() {
    return username;
    } public void setUsername(String username) {
    this.username = username;
    } public String getPassword() {
    return password;
    } public void setPassword(String password) {
    this.password = password;
    }
    }
  2. 服务端新增配置
    jsonBeanProperty=[ { "username": "john", "password": "1234" }, { "username": "simon", "password": "222132" } ]
  3. 客户端获取配置
    //4. @ApolloJsonValue使用
    @ApolloJsonValue("${jsonBeanProperty:[]}")
    private List<User> anotherJsonBeans; @RequestMapping("/index4")
    public void hello4(){
    anotherJsonBeans.forEach(item -> {
    System.err.println(item.getUsername()+"--"+item.getPassword());
    });
    }
  4. 测试
    浏览器访问http://127.0.0.1:8080/index4,正确打印配置的值

源码下载

Spring Boot 2.0 整合携程Apollo配置中心的更多相关文章

  1. SpringBoot 整合携程Apollo配置管理中心

    携程官网对apollo的使用讲解了很多种方式的使用,但是感觉一些细节还是没讲全,特别是eureka配置中心地址的配置 这里对springboot整合apollo说一下 >SpringBoot启动 ...

  2. 携程 Apollo 配置中心传统 .NET 项目集成实践

    官方文档存在的问题 可能由于 Apollo 配置中心的客户端源码一直处于更新中,导致其相关文档有些跟不上节奏,部分文档写的不规范,很容易给做对接的新手朋友造成误导. 比如,我在参考如下两个文档使用传统 ...

  3. 携程Apollo配置中心架构深度剖析

    转自:http://www.uml.org.cn/wfw/201808153.asp 一.介绍 Apollo(阿波罗)[参考附录]是携程框架部研发并开源的一款生产级的配置中心产品,它能够集中管理应用在 ...

  4. 携程apollo配置中心服务端如何感知配置更新?

    引言 前面有写过一篇<分布式配置中心apollo是如何实时感知配置被修改>,也就是客户端client是如何知道配置被修改了,有不少读者私信我你既然说了client端是如何感知的,那服务端又 ...

  5. spring boot 2.0 整合 elasticsearch6.5.3,spring boot 2.0 整合 elasticsearch NoNodeAvailableException

    原文地址:spring boot 2.0 整合 elasticsearch NoNodeAvailableException 原文说的有点问题,下面贴出我的配置: 原码云项目地址:https://gi ...

  6. Spring Boot 2.0 整合 FreeMarker 模板引擎

    本篇博文将和大家一起使用Spring Boot 2.0 和FreeMarker 模板引擎整合实战. 1. 创建新的项目 2. 填写项目配置信息 3. 勾选web 模块 4. 勾选freemarker模 ...

  7. Spring Boot 2.0 整合Thymeleaf 模板引擎

    本节将和大家一起实战Spring Boot 2.0 和thymeleaf 模板引擎 1. 创建项目 2. 使用Spring Initlizr 快速创建Spring Boot 应用程序 3. 填写项目配 ...

  8. 携程的配置中心(阿波罗apollo)

    https://github.com/ctripcorp/apollo https://pan.baidu.com/s/1dFEGMIX#list/path=%2Fmeetup%20ppt%2F040 ...

  9. 携程apollo系列-客户端集成

    本文讲解如何在 Java 程序中集成 Apollo 配置, 主要涉及到一些基础用法. 对于一些高级用法, 比如如何加密/解密配置项 (可用于数据库密码配置), 如何动态切换数据源地址,如何动态切换日志 ...

随机推荐

  1. Unchecked runtime.lastError: The message port closed before a response was received.

    这是由于某个 Chrome 扩展程序造成的. 打开 chrome://extensions/,逐一关闭排查.我这边是由于“迅雷下载支持”这个扩展引起的,将其关闭即可.

  2. 什么是SQL Server2019大数据群集?

    从SQL Server 2019(15.x)开始,SQL Server大数据群集允许您部署在Kubernetes上运行的SQL Server,Spark和HDFS容器的可伸缩群集.这些组件并排运行,使 ...

  3. 用luks方式对磁盘进行加密以及加密磁盘的自动挂载

    1.关于luks加密 LUKS(Linux Unified Key Setup)为Linux硬盘分区加密提供了一种标准,它不仅能通用于不同的 Linux发行版本,还支持多用户/口令.因为它的加密密钥独 ...

  4. Salesforce 开发整理(六) Visualforce分页

    分页的实现总体上分真分页和假分页. 所谓真分页指页面上列出来的数据就是实际查询的数据,假分页则是无论页面上一次显示多少条记录,实际上后台已经加载了所有的记录,分页只是为了展示给用户查看.今天分享一个V ...

  5. Hadoop vs Elasticsearch – Which one is More Useful

    Hadoop vs Elasticsearch – Which one is More Useful     Difference Between Hadoop and Elasticsearch H ...

  6. 【06月19日】A股滚动市盈率PE最低排名

    ​仅根据最新的市盈率计算公式进行排名,无法对未来的业绩做出预测. 方大集团(SZ000055) - 滚动市盈率PE:2.59 - 滚动市净率PB:1.16 - 滚动年化股息收益率:3.91% - 建筑 ...

  7. SGE部署安装

    1.关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service 2.安装SGE依赖包 # yum instal ...

  8. Python【每日一问】20

    问: [基础题]: 企业发放的奖金根据利润提成.利润(I): 低于或等于10万元时,奖金可提10%: 高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%: ...

  9. 使用scrapy框架做武林中文网的爬虫

    一.安装 首先scrapy的安装之前需要安装这个模块:wheel.lxml.Twisted.pywin32,最后在安装scrapy pip install wheel pip install lxml ...

  10. Scala Type Parameters 2

    类型关系 Scala 支持在泛型类上使用型变注释,用来表示复杂类型.组合类型的子类型关系间的相关性 协变 +T,变化方向相同,通常用在生产 假设 A extends T, 对于 Clazz[+T],则 ...