目录
配置中心
顾名思义,就是用来统一管理项目中所有配置的系统。虽然听起来很简单,但也不要小 瞧了这个模块。如果一个中型互联网项目,不采用配置中心的模式,一大堆的各类配置项,各种不定时 的修改需求,一定会让开发同学非常头疼且管理十分混乱。我认为甚至可以直接用 “一个项目中是否有 无采用「配置中心」” 这一粗略的条件,来判断一个互联网研发团队是否规范和成熟
为什么需要配置中心?
我们先来看看在没有「配置中心」的传统项目中,我们是怎么处理各类配置参数问题的:
- 一般是静态化配置。大多数在项目中单独写一个配置文件,例如 "config.conf",然后将各类 参数配置、应用配置、环境配置、安全配置、业务配置 都写到这个文件里。当项目代码逻辑中需要使用配置的时候,就从这个配置文件中读取。这种做法虽然简单,但如果参数需要修改,就非常的不灵活,甚至需要重启运行中的项目才能生效。相信大多数开发同学都深有体会。
- 配置文件无法区分环境。由于配置文件是放在项目中的,但是我们项目可能会有多个环境,例如:测试环境、预发布环境、生产环境。每一个环境所使用的配置参数理论上都是不同的,所以我们在配置文件中根据不同环境配置不同的参数,这些都是手动维护,在项目发布的时候,极其容易因开发人员的失误导致出错。
- 配置文件过于分散。如果一个项目中存在多个逻辑模块独立部署,每个模块所使用的配置内容又不相同,传统的做法是会在每一个模块中都放一个配置文件,甚至不同模块的配置文件格式还不一样。那么长期的结果就是配置文件过于分散混乱,难以管理。
- 配置修改无法追溯。因为采用的静态配置文件方式,所以当配置进行修改之后,不容易形成记录,更无法追溯是谁修改的、修改时间是什么、修改前是什么内容。既然无法追溯,那么当配置出错时,更没办法回滚配置了。
既然传统的项目配置有这么多弊端,那我们看看「配置中心」的方案是如何解决这些痛点,「配置中心」的思路就是把项目中各种配置、各种参数、各种开关,全部都放到一个集中的地方进行统 一管理,并提供一套标准的接口。当各个服务需要获取配置的时候,就来「配置中心」的接口拉取。当 「配置中心」中的各种参数有更新的时候,也能通知到各个服务实时的过来同步最新的信息,使之动态更新
按照上述思路,我们理想中的「配置中心」应该具备如下特点:
- 配置集中管理、统一标准
- 配置与应用分离
- 实时更新
- 高可用
配置中心的原理与应用
- 实现配置的记录
- 实现配置的读取、更新、取消
- 实现配置的查看
常见配置中心介绍与对比
Disconf
Disconf是在2014年7月,由百度开源的分布式配置中心。其实很多一线大厂都有开源自己的配置中心 组件,这里挑出百度的Disconf也是因为网上比较火热,易用性也还不错,项目也是托管在github上很 容易找到。它是基于Zookeeper来实现配置变更后实时通知和生效的
Spring Cloud Config
2014年9月开源,Spring Cloud 生态组件,可以和Spring Cloud体系无缝整合,使用起来非常方便。并 且它的配置存储支持Git,不过它没有可视化的操作界面,配置的生效也不是实时的,需要重启或去刷 新。所以比较适用于小型项目快速上手。
Spring Cloud Config包含了Config Client和Config Server两部分,Config Server 实现配置文件的存 储,对外以接口的形式提供获取配置文件,然后Config Client通过这些接口获取数据
Apollo
2016年5月,携程开源的配置管理中心,具备规范的权限、流程治理等特性。Apollo的特点有很多,比如:配置更新之后可以实时生效,还可以支持灰度发布功能。并且能对所有的 配置进行版本管理、操作审计等功能,提供开放平台API。另外由于Apollo使用的人很多,所以网上的 资料也非常的丰富,并且github上资料也写的很详细。
上面即是Apollo的基础模型,看结构很简单。但是其功能很多,之前说过配置中心对高可用的要求很 高。下面可以继续看一下Apollo的架构:
Nacos
2018年6月,阿里开源的配置中心,也可以做DNS和RPC的服务发现。Nacos 支持基于 DNS 和基于 RPC 的服务发现。在Spring Cloud中使用Nacos,只需要先下载 Nacos 并 启动 Nacos server,Nacos只需要简单的配置就可以完成服务的注册发现。
Nacos除了服务的注册发现之外,还支持动态配置服务。动态配置服务可以让您以中心化、外部化和动 态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需 要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性 扩展变得更容易。
Nacos主要提供以下四大功能:
- 服务发现与服务健康检查 Nacos使服务更容易注册自己并通过DNS或HTTP接口发现其他服务。 Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求。
- 动态配置管理 动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置。 Nacos消除了在更新配置时重新部署应用程序和服务的需要,这使配置更改更加高效和灵活。
- 动态DNS服务 Nacos支持加权路由,使您可以更轻松地在数据中心的生产环境中实施中间层负载 平衡,灵活的路由策略,流量控制和简单的DNS解析服务。它可以帮助您轻松实现基于DNS的服 务发现,并防止应用程序耦合到特定于供应商的服务发现API。
- 服务和元数据管理 Nacos提供易于使用的服务仪表板,可帮助您管理服务元数据,配置, kubernetes DNS,服务运行状况和指标统计。
功能对比
对比项目/配置中心 | spring cloud config | apollo | nacos |
开源时间 | 2014.9 | 2016.5 | 2018.6 |
配置实时 推送 | 支持(Spring Cloud Bus) | 支持(HTTP长轮询1s内) | 支持(HTTP长轮询1s内) |
版本管理 | 支持(Git) | 自动管理 | 自动管理 |
配置回滚 | 支持(Git) | 支持 | 支持 |
灰度发布 | 支持 | 支持 | 待支持 |
权限管理 | 支持 | 支持 | 待支持 |
多集群多环境 | 支持 | 支持 | 支持 |
监听查询 | 支持 | 支持 | 支持 |
多语言 | 只支持Java | Go,C++,Python,Java,.net,OpenAPI | Python,Java,Nodejs,OpenAPI |
分布式高 可用最小 集群数量 | ConfigServer2+Git+MQ | Config2+Admin3+Portal*2+Mysql=8 | Nacos*3+MySql=4 |
配置格式 校验 | 不支持 | 支持 | 支持 |
通信协议 | HTTP和AMQP | HTTP | HTTP |
数据一致 性 | Git保证数据一致性, Config-Server从Git 读取数据 | 数据库模拟消息队列,Apollo定时读 消息 | HTTP异步通知 |
单机读 (tps) | 7(限流所制) | 9000 | 15000 |
单机写 (tps) | 5(限流所制) | 1100 | 1800 |
3节点读 | 21(限流所制) | 27000 | 45000 |
3节点写 | 5(限流所制) | 3300 | 5600 |
总的来说 :
- Apollo和Nacos相对于Spring Cloud Config的生态支持更广,在配置管理流程上做的更 好。
- Apollo相对于Nacos在配置管理做的更加全面,不过使用起来也要麻烦一些。
- apollo容器 化较困难,Nacos有官网的镜像可以直接部署,总体来说,Nacos比apollo更符合KISS原则。
- Nacos 部署和使用起来相对比较简洁,在对性能要求比较高的大规模场景更适合。 此外,Nacos除了提供配置中心的功能,还提供了动态服务发现、服务共享与管理的功能,降低了服务 化改造过程中的难度。
Spring Cloud Config实现分布式配置中心
如果只是想把配置统一由spring cloud config来管理,而暂时不想做配置中心的高可用的话,则只需 要config和bus两个组件就够了。但是如果要保证高可用,还得使用spring cloud的注册发现组件。
引入config和bus组件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
启动类使用@EnableConfigServer注解
@SpringBootApplication
@EnableConfigServer
public class ConifgServer {
public static void main(String[] args) {
new SpringApplicationBuilder().sources(ConifgServer.class).run(args);
}
}
application.properties文件配置
server.port=9001
spring.application.name=spring-cloud-config-server
#改成自己的git配置文件地址
spring.cloud.config.server.git.uri=https://gitee.com/numn/config-server
spring.cloud.config.server.git.search-paths=
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=
# 配置RabbitMQ是因为bus组件需要使用它来 通知 客户端,配置有变动
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#Spring boot 1.x 关闭验证
#management.security.enabled=false
#Spring boot 2.x 允许访问刷新配置接口
management.endpoints.web.exposure.include=bus-refresh
客户端接入配置中心
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置application.properties
说名:
- 配置允许访问刷新配置接口,management.endpoints.web.exposure.include=refresh
- spring cloud config相关的配置一定一定要放到bootstrap.properties里
- 使用spring.cloud.config.uri指定配置中心的地址
配置文件优先级
- bootstrap.yml(bootstrap.properties)用来程序引导时执行,应用于更加早期配置信息读取application.yml(application.properties) 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。
- bootstrap.properties优先于application.properties
- bootstrap.yml优先于application.yml
- properties优先于yml
- resources/config优先于resources/
spring.application.name=service-order
server.port=6001
#允许访问刷新配置接口
management.endpoints.web.exposure.include=bus-refresh
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
bootstrap.properties
spring.cloud.config.name=demo
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:9001/
使用配置
@RestController
@RefreshScope
public class ConfigController {
//注入git上配置文件的对应的值
@Value("${address}")
private String address;
@RequestMapping(value = "/getConfigInfo", method = RequestMethod.GET)
public String getConfigInfo() {
return "address:" + address;
}
}
自动更新设置
每次git 上配置文件更新,需要调用调用服务端的 /actuator/bus-refresh 接口,客户端配置才能更新,这个也太麻烦了;可以使用 webhook来帮一下忙,如果用的是新的gitlab,那么只需要在工程里面,点击【Settings】,再点 击【Integrations】,就可以设置webhook了,如下图:url里面填入配置中心服务端的 /actuator/bus-refresh 接口地址,然后点击【添加Webhook】就可 以了。
Nacos实现分布式配置中心
Nacos简介
Nacos是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。是构 建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。使用Java编写,需 要依赖Java环境。 官网地址:https://nacos.io/zh-cn/
基本架构
Nacos安装指南
引入nacos config组件
dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.2.2.RELEASE</version>
</dependency>
bootstrap.properties文件配置
spring.application.name=service-order
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.discovery.enabled=true
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.group=DEFAULT_GROUP
spring.cloud.nacos.config.file-extension=properties
Nacos新增配置文件
注意:dataId 形式为 服务名.properties 或者 服务名.yml
测试代码动态更新配置
@Value("${address}")
private String address;
@RequestMapping(value = "/getConfigInfo", method = RequestMethod.GET)
public String getConfigInfo() {
return "address:" + address;
}
测试效果,可以读取配置文件了!