摘要:对于单机服务来说,可以采用application.yml配置文件的方式,抽取代码中固定配置的数据或者可能发生变化的配置数据,将其保存到配置文件中。如果配置有变化,则开发人员需要重新修改文件、编译打包及部署。随着微服务概念的兴起,服务被拆分成多个,每个服务又进行
对于单机服务来说,可以采用application.yml配置文件的方式,抽取代码中固定配置的数据或者可能发生变化的配置数据,将其保存到配置文件中。如果配置有变化,则开发人员需要重新修改文件、编译打包及部署。随着微服务概念的兴起,服务被拆分成多个,每个服务又进行集群管理,分别部署在不同的环境中,如果用配置文件的方式进行配置数据的修改,则显得更加复杂。此时就需要一套配置中心管理平台,该平台可以区分不同环境和不同集群,并可以动态下发,实时生效,同时还可以支持灰度和回滚等功能。通过将烦琐的配置操作封装到配置中心,使开发人员只需专注于业务代码,显著提升了开发效率及运维效率。将配置和发布解耦,能进一步提升发布的成功率,并为运维的细粒度管控、应急处理等提供强有力的支撑。
服务发现也是微服务开发中必不可少的组件之一。多个服务之间依赖复杂,如何统一管理服务是开发中需要面临的问题。通过服务发现组件提供的服务注册中心,可以将各个服务实例注册到服务注册中心上。当客户端访问服务发现组件时,先获取服务实例,然后再进行服务调用,使客户端和真实服务解耦,通过服务发现组件来完成服务的查询。本章将重点讲解微服务开发中常用的配置中心与服务发现组件。
本节主要介绍当前比较成熟的一些开源配置中心组件,包括XXLCONF、Apollo和Spring Cloud Config。以上3个组件都可以在GitHub上找到源码,其中,XXL-CONF和apollo是国产开源组件,都带有管理平台页面,操作直观,Spring Cloud Config是Spring Cloud家族提供的配置方式,它基于Git仓库存储配置文件,没有提供Web管理界面。
XXL-CONF组件简介
XXL-CONF是一个轻量级的分布式配置管理平台,具有轻量级、秒级动态推送、多环境部署、跨机房部署、动态监听配置、权限控制和版本快速回滚等多种特性,可以开箱即用。
轻量级:接入灵活,快速上手,不依赖于第三方服务,部署简单。
高可用:支持集群部署和跨机房部署,提供Web管理界面,直观、高效。
多环境:配置可以在测试环境和线上环境等多种环境中进行。
多数据类型:可以对不同的数据类型进行配置。
高性能:基于配置中心的磁盘存储及客户端本地缓存,数据可实时更新。
灵活配置:支持API、注解和XML占位符的方式。
权限控制:多项目隔离及用户权限控制。
版本回滚:记录10个历史版本,支持历史版本回滚。
XXL-CONF的整体架构如图5.1所示。
XXL-CONF配置管理平台主要由以下几部分组成:
管理平台:一个功能完善的配置平台后台管理页面,包括环境、用户、项目和配置等管理功能,通过简单的UI页面完成操作管理。
管理平台数据存储:存储配置信息的备份和版本修改记录等,保证数据的安全,同时存储管理平台的底层数据。
配置数据的磁盘存储:配置中心在每个集群节点的磁盘中存储着一份镜像数据,当进行配置新增和更新等操作时,将会广播通知并实时刷新每个集群节点磁盘中的配置数据,再实时发送通知给接入的客户端。
XXL-CONF客户端的架构如图5.2所示。客户端的四层设计如下:
API接口层:提供了开放的API接口,业务方可以直接使用,简单、方便,同时还能保证配置的高效和实时性。
本地缓存层:客户端采用本地缓存可以极大地提高API接口层的性能,从而降低对配置中心集群的访问压力。首次读取配置信息、监听配置信息的变更以及异步或同步配置时,都将配置信息写入缓存中或对缓存进行更新。
镜像文件层:配置信息的本地快照文件,会周期性地同步本地缓存层中的配置信息并将其写入镜像文件中。当应用无法从配置中心获取配置数据时,将会使用镜像文件中的配置数据,这样可以提高系统的高可用性。
远程层:配置中心远程客户端的封装,用于加载远程配置,实时监听配置变更情况,提高配置的时效性。
下面搭建XXL-CONF配置中心管理平台。
(1)使用git clone https://github.com/xuxueli/xxlconf.git命令拉取项目到本地,然后获取数据库的初始化SQL脚本并执行,路径为xxl-conf/doc/db/xxl-conf.sql。
(2)修改配置文件/xxl-conf/xxl-confadmin/src/main/resources/application.properties,并配置本地MySQL路径。具体配置如下:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl-conf?
Unicode
=true&characterEncoding=UTF-8
xxl.conf.confdata.filepath=/data/xxl-conf/confdata
xxl.conf.access.token=
(3)项目编译打包后可直接通过命令行java-jar xxl-confadmin.jar启动。启动后打开管理页面,分别进行用户管理、项目管理、环境管理和配置管理的设置,具体操作如图5.3至图5.6所示。
(4)在项目中引入XXL-CONF。修改项目的application.yml文件,配置XXL-CONF信息,具体代码如下:
xxl:
conf:
admin:
address: http://localhost:8080/xxl-conf-admin
env: test
access:
token:
mirrorfile: /data/xxl-conf/xxl-conf-mirror.properties
(5)在项目中添加自动配置类XxlConfConfig,代码如下:
//配置XXL-CONF
@Configuration
public class XxlConfConfig {
@Value("${xxl.conf.admin.address}")
private String adminAddress;
@Value("${xxl.conf.env}")
private String env;
@Value("${xxl.conf.access.token}")
private String accessToken;
@Value("${xxl.conf.mirrorfile}")
private String mirrorfile;
//定义XxlConfGactory
@Bean
public XxlConfFactory xxlConfFactory {
XxlConfFactory xxlConf = new XxlConfFactory;
xxlConf.setAdminAddress(adminAddress); //管理后台
路径
xxlConf.setEnv(env); //运行环境
xxlConf.setAccessToken(accessToken); //设置
Token
xxlConf.setMirrorfile(mirrorfile); //设置镜像
文件
return xxlConf;
}
}
(6)客户端获取配置信息。有3种获取配置数据的方式,分别为使用客户端API、注解@XxlConf和XML占位符。本例采用注解方式,代码如下:
@XxlConf("default.userName")
public String userName;
(7)XXL-CONF提供了监听Listener,用于监听配置的变更事件,代码如下:
//监听处理
XxlConfClient.addListener("default.userName", new
XxlConfListener{
@Override
public void onChange(String key, String value) throws
Exception {
logger.info("配置数据发送变更:{}={}", key, value);
}
});
Apollo(阿波罗)是携程公司开源的一款分布式配置管理中心,可以集中管理不同环境下的应用配置信息。配置数据修改后,可以将其实时推送到服务端。Apollo同时还提供了权限管理和发布流程管理功能,适用于各种需要配置管理的场景,支持应用(Application)、环境(Environment)、集群(Cluster)和命名空间(Namespace)4个维度的配置。
Apollo具有以下特性:
提供统一的管理页面,可以管理不同的环境和集群。
可以使配置实时生效。
应用部署的发布与版本回滚。
可以对配置进行权限管理。
Apollo的整体架构如图5.7所示。
图5.7中的Apollo主架构主要分为以下几部分:
配置服务(Config Service):提供读取、推送配置数据等功能,主要为Apollo客户端服务。
后台页面服务(Admin Service):提供UI页面,可以修改和发布配置数据,服务对象是Apollo Portal(管理界面)。
注册发现服务(Eureka):集成了Eureka,主要用于服务的注册和发现。
元数据服务(Meta Server):封装了Eureka的服务发现接口。
从上往下可以看到,客户端首先访问Meta Server获取配置服务列表(IP+Port),然后直接通过IP+Port的方式访问服务,同时在客户端进行负载均衡、错误重试等操作,后台管理页面通过访问MetaServer,获取Admin Service进行配置数据修改等操作。
Apollo的客户端架构如图5.8所示。
Apollo客户端的实现原理:客户端和服务端维持一个长连接,用来快速获取配置数据修改的推送通知。客户端定时从Apollo配置中心服务端获取应用的最新配置,然后将配置数据保存在本地内存中进行缓存,同时在本地磁盘也缓存一份。
下面讲解Apollo的搭建过程。
(1)Apollo提供了Quick Start,从
https://github.com/nobodyiam/apollo-build-scripts.git上下载工程例子,并执行相关SQL语句。
(2)修改数据库配置数据,具体如下:
apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfig
DB?
characterEncoding=utf8
apollo_config_db_username=用户名
apollo_config_db_password=密码
apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortal
DB?
apollo_portal_db_username=用户名
apollo_portal_db_password=密码
(3)执行脚本./demo.sh start启动服务,访问http://localhost:8070,输入用户名apollo和密码admin后登录,其主页面如图5.9所示。
(4)主页面中展示了配置信息,如图5.10所示。
(5)如果本地服务想要接入Apollo平台,则需要配置相关属性,例如:
app.id=YOUR-APP-ID
apollo.meta=http://config-service-url
apollo.cacheDir=/opt/data/some-cache-dir
env=DEV
apollo.cluster=SomeCluster
apollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719
apollo.bootstrap.enabled = true
apollo.bootstrap.namespaces =
application,FX.apollo,application.yml
(6)Apollo提供了多种方式获取配置数据。下面采用SpringBoot配置注解的方式获取,代码如下:
public class TestApolloAnnotationBean {
@ApolloConfig
private Config config; //注入配置
@ApolloConfig("application")
private Config anotherConfig; //通过
applicationg命名注入
@ApolloConfig("FX.apollo")
private Config yetAnotherConfig; //通过
FX.apollo命名注入
@ApolloConfig("application.yml")
private Config ymlConfig; //通过
application.yml注入
@ApolloJsonValue("${JsonBeanProperty:}")
private List anotherJsonBeans;
@Value("${batch:100}")
private int batch;
//配置监听
@ApolloConfigChangeListener
private void someOnChange(ConfigChangeEvent changeEvent) {
//修改属性
if (changeEvent.isChanged("batch")) {
batch = config.getIntProperty("batch", 100);
}
}
//配置监听
@ApolloConfigChangeListener("application")
private void anotherOnChange(ConfigChangeEvent changeEvent)
{
//do something
}
//监听配置
@ApolloConfigChangeListener({"application", "FX.apollo",
"application.yml"})
private void yetAnotherOnChange(ConfigChangeEvent
changeEvent) {
//do something
}
//获取配置
public int getTimeout {
return config.getIntProperty("timeout", 200);
}
//获取配置
public int getBatch {
return this.batch;
}
private static class JsonBean{
private String someString;
private int someInt;
}
}
(7)新建配置类AppConfig,生成TestApollAnnotationBean实例,具体代码如下:
@Configuration
@EnableApolloConfig
public class AppConfig {
@Bean
public TestApolloAnnotationBean testApolloAnnotationBean
{
return new TestApolloAnnotationBean;
}
}
Spring Cloud Config是Spring Cloud家族的一个开源组件,它为分布式系统提供配置支持,通过配置中心管理微服务所有环境下的配置信息。Spring Cloud Config默认采用Git作为配置中心,其主要特性如下:
提供对服务端和客户端的支持。
进行集中式的配置管理。
与Spring Boot和Spring Cloud应用无缝集成。
默认基于Git进行版本管理。
Spring Cloud Config架构如图5.11所示。
接下来介绍基于Spring Cloud Config配置中心的搭建过程。
(1)首先在个人GitHub网站上新建自己的仓库,本例中的仓库名为config-repo,然后在仓库中新建4个配置文件。
config-client.yml文件内容如下:
#定义属性
name: config-client-default
config-client-dev.yml文件内容如下:
#定义属性
name: config-client-dev
config-client-test.yml文件内容如下:
#定义属性
name: config-client-test
config-client-prod.yml文件内容如下:
#定义属性
name: config-client-prod
(2)搭建config-server工程,依赖spring-cloud-configserver包,代码如下:
org.springframework.cloud
spring-cloud-config-server
2.2.5.RELEASE
(3)修改config-server工程的配置文件application.yml,在其中添加Git仓库配置,具体如下:
spring:
cloud:
config:
server:
git:
uri: https://github.com/xxx/config-repo
username: test
password: 123456
default-label: master
(4)在启动类中添加注解@EnableConfigServer,使启动服务后即可访问配置文件。访问配置文件有一定的规则,具体如下:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
其中,{application}为应用名称,{profile}为环境配置,{label}为Git的分支。
访问4个URL:http://localhost:8080/config-client/default、http://localhost:8080/ config-client/dev/master、http://localhost:8080/config-client-test.yml和http://localhost: 8080/master/config-client-prod.yml,均可以获取配置数据。
(5)搭建客户端工程config-client,依赖spring-cloudstarter-config包,然后修改bootstrap.yml文件,代码如下:
spring:
cloud:
config:
name: config-client
uri: http://localhost:8080
label: master
profile: dev
(6)新建Controller类访问配置数据,代码如下:
@RestController
public class ConfigController {
@Value("${name}")
private String name;
@GetMapping("/name")
public String getName {
return name;
}
}
启动服务访问接口即可获取name配置数据。本节只介绍了SpringCloud Config的基本配置,如果想实现动态地修改配置,可以结合Webhook或者Spring Cloud Bus进行配置修改的实时刷新。
来源:大数据架构师