2. 配置中心
配置中心将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去管理配置。
配置中心的服务流程如下:
1、用户在配置中心更新配置信息。
2、服务A和服务B及时得到配置更新通知,从配置中心获取配置。
总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件。
在系统架构中,配置中心是整个微服务基础架构体系中的一个组件,它的功能看上去并不起眼,无非就是配置的管理和存取,但它是整个微服务架构中不可或缺的一环。
总结一下,在传统巨型单体应用纷纷转向细粒度微服务架构的历史进程中,配置中心是微服务化不可缺少的一个系 统组件,在这种背景下中心化的配置服务即配置中心应运而生,一个合格的配置中心需要满足如下特性:
- 配置项容易读取和修改
- 分布式环境下应用配置的可管理性,即提供远程管理配置的能力
- 支持对配置的修改的检视以把控风险
- 可以查看配置修改的历史记录
- 不同部署环境下应用配置的隔离性
2.1 主流配置中心对比
目前市面上用的比较多的配置中心有:Spring Cloud Config、Apollo、Nacos和Disconf等。 由于Disconf不再维护,下面主要对比一下Spring Cloud Confifig、Apollo和Nacos。
对比项 | Spring Cloud Config | Apollo | Nacos |
---|---|---|---|
配置实时推送 | 支持(Spring Cloud Bus) | 支持(HTTP长轮询1s内) | 支持(HTTP长轮询1s内) |
版本管理 | 支持(Git) | 支持 | 支持 |
配置回滚 | 支持(Git) | 支持 | 支持 |
灰度发布 | 支持 | 支持 | 支持 |
权限管理 | 支持(依赖Git) | 支持 | 不支持 |
多集群 | 支持 | 支持 | 支持 |
多环境 | 支持 | 支持 | 支持 |
监听查询 | 支持 | 支持 | 支持 |
多语言 | 只支持java | 主流语言,提供了Open API | 主流语言,提供了Open API |
配置格式校验 | 不支持 | 支持 | 支持 |
单机读(QPS) | 7(限流所致) | 9000 | 15000 |
单机写(QPS) | 5(限流所致) | 1100 | 1800 |
3节点读 (QPS) | 21(限流所致) | 27000 | 45000 |
3节点写(QPS) | 5(限流所致) | 3300 | 5600 |
从配置中心角度来看:
- 性能方面Nacos的读写性能最高,Apollo次之,Spring Cloud Config依赖Git场景不适合开放的大规模自动化运维API。
- 功能方面Apollo最为完善,nacos具有Apollo大部分配置管理功能,而Spring Cloud Config不带运维管理界面,需要自行开发。
- Nacos的一大优势是整合了注册中心、配置中心功能,部署和操作相比 Apollo都要直观简单,因此它简化了架构复杂度,并减轻运维及部署工作。
综合来看,Nacos的特点和优势还是比较明显的,下面我们一起进入Nacos的世界。 Nacos除了可以做注册中心,同样可以做配置管理来使用。
2.2 Nacos 统一配置管理
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务,由于每个服务都需要必要的配置信息才能运行, 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置就会让人抓狂,而且很容易出错。所以一套集中式的、动态的配置管理是必不可少的。
Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。
2.2.1 在nacos中添加配置文件
到我们的nacos管理页面的配置管理界面来添加配置文件:
然后在弹出的表单中,填写配置信息:
注意:
项目的核心配置,需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好。
2.2.2 从微服务拉取配置
微服务要拉取nacos中管理的配置,并且与本地的application.yml配置合并,才能完成项目启动。
但如果尚未读取application.yml,又如何得知nacos地址呢?
因此spring引入了一种新的配置文件:bootstrap.yaml文件,会在application.yml之前被读取,流程如下:
步骤:
1)引入nacos-config依赖
首先,在shop-order服务中,引入nacos-config的客户端依赖:
<!--nacos-config-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2)添加bootstrap.yaml
然后,在user-service中添加一个bootstrap.yaml文件,内容如下:
spring:application:name: orderservice # 服务名称profiles:active: dev #开发环境,这里是dev cloud:nacos:server-addr: localhost:8848 # Nacos地址config:file-extension: yml # 文件后缀名
这里会根据spring.cloud.nacos.server-addr获取nacos地址,再根据
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
作为文件id,来读取配置。
本例中,就是去读取orderservice-dev.yml
:
启动shop-order,我们可以从控制台查看日志发现,它已经从nacos读取配置文件了:
2022-10-01 08:37:39.523 INFO 29664 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-orderservice-dev.yml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-orderservice.yml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-orderservice,DEFAULT_GROUP'}]
2022-10-01 08:37:39.523 INFO 29664 --- [ main] com.suke.shop.order.OrderApplication : The following profiles are active: dev
2022-10-01 08:37:40.375 INFO 29664 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=db95bdfc-3380-37b0-be7b-eab77e21a2be
我们访问服务,也正常访问
2.3 配置热更新
我们最终的目的,是修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新。
要实现配置热更新,可以使用两种方式:
2.3.1.方式一
在@Value注入的变量所在类上添加注解@RefreshScope,并且对应的@Bean需要添加@RefreshScope
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;@SpringBootConfiguration
@RefreshScope
public class DataSourceConfig {@Value("${spring.datasource.driver-class-name}")private String driverClassName;@Value("${spring.datasource.url}")private String url;@Value("${spring.datasource.username}")private String username;@Value("${spring.datasource.password}")private String password;@Bean@RefreshScopepublic DataSource getDataSource(){HikariDataSource dataSource = new HikariDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setJdbcUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
}
2.3.2 方式二
使用@ConfigurationProperties注解代替@Value注解。
在shop-order服务中,在DataSourceConfig类添加@ConfigurationProperties注解:
student: name: lisiage: 21sex: 男
@Data
@ConfigurationProperties(prefix = "student")
@Component
public class Student {private String name;private Integer age;private String sex;
}
@GetMapping("/student")
public Student getStudent(){return student;
}
当我们把name修改为zhangsan,age修改为22,再访问
此时,我们发现数据以及热更新了
2.4 配置共享
其实微服务启动时,会去nacos读取多个配置文件,例如:
-
[spring.application.name]-[spring.profiles.active].yaml
,例如:orderservice-dev.yaml -
[spring.application.name].yaml
,例如:orderservice.yaml
而[spring.application.name].yaml
不包含环境,因此可以被多个环境共享。
下面我们通过案例来测试配置共享
2.4.1 添加一个环境共享配置
我们在nacos中添加一个orderservice.yaml文件:
2.4.2 在Student类中读取共享配置
2.4.3 运行shop-order,使用不同的profile
请求controller,我们发现student的id有值:
这说明我们的orderservice.yml文件已被共享了
注意:
当nacos、服务本地同时出现相同属性时,优先级有高低之分: