1. Config
微服务意味着要将整体应用的业务拆分成一个个子服务,每个服务的粒度相对较小, 因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,因此一套集中式的、动态的配置管理设施是必不可少的。
1.1 功能
Spring Cloud Config 为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供一个中心化的外部配置。
-
分为服务端和客户端:
- 服务端也称分布式配置中心,是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。
- 客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息,默认使用git作为配置服务器来存储配置信息,有助于对环境进行版本管理,并且可以通过git客户端工具来方便管理和访问配置内容。
-
作用:
- 计中管理配置文件;
- 针对不同环境动态化的配置更新;
- 运行期间动态调整,不需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息;
- 配置发生变化时,服务不需要重启即可感知到配置的变化并应用新的配置;
- 配置信息以Rest风格暴露。
1.2 服务端配置
这里就是新建一个git仓库,并且clone,拥有针对仓库的git文件,可以提交修改。使用Gitee。
-
新建module:
cloud-config-center3344
-
依赖:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.example</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
-
配置文件:
server: port: 3344 spring: application: name: cloud-config-center cloud: config: server: git: skipSslValidation: true uri: https://gitee.com/jminzhou/jm-cloud.git # gitee仓库地址 search-paths: #搜索目录 - jm-cloud label: master #读取分支 eureka: client: service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/, # 注入7002 和 7001
-
主启动类
@SpringBootApplication @EnableConfigServer public class ConfigMain3344 { public static void main(String[] args) { SpringApplication.run(ConfigMain3344.class,args); } }
-
在当前项目下,新建配置文件并提交到git测试。
prod:label: master profile: prod config: info: master-prod
dev:
label: master profile: dev config: info: master-dev
test:
label: master profile: test config: info: master-test
-
确保gitee已经提交成功:
-
访问成功。
1.3 客户端配置
让当前客户端去上方服务端中找配置。
-
新建module:
cloud-config-client3366
; -
依赖:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.example</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
-
新建配置文件:
bootstrap.yml
,系统级配置文件,优先级高,优先于application.yml加载。server: port: 3366 spring: application: name: config-client cloud: config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 uri: http://localhost:3344 #配置中心的地址 # 合起来读取的就是:http://localhost:3344/master/config-dev.yml 配置文件。 eureka: client: service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/, # 注入7002 和 7001
-
主启动类:
@EnableEurekaClient @SpringBootApplication public class ConfigClient3366 { public static void main(String[] args) { SpringApplication.run(ConfigClient3366.class,args); } }
-
新建controller以rest风格读取配置文件信息。
@RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo() { return configInfo; } }
-
访问客户端接口测试:成功获取配置文件内容
1.4 客户端的动态刷新
模拟环境,修改了git上面的配置文件,3344服务端立刻响应,但是3366服务端没有任何响应,只能重启更新配置信息。
这里可以针对客户端来实现动态刷新配置。
-
修改
bootstrap.yml
:server: port: 3366 spring: application: name: config-client cloud: config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 uri: http://localhost:3344 #配置中心的地址 # 合起来读取的就是:http://localhost:3344/master/config-dev.yml 配置文件。 eureka: client: service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/, # 注入7002 和 7001 # 暴露监控端点 management: endpoints: web: exposure: include: "*"
-
修改controller:
@RestController @RefreshScope public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo() { return configInfo; } }
-
对客户端发送一个post请求:
http://localhost:3366/actuator/refresh
-
再次更改测试:刷新成功
2. Bus
上方基于SpringCloudConfig只能实现手动刷新,即每次更新git上配置文件必须发送一个post请求才可以,比较繁琐。
这里引入Bus可以实现动态的刷新配置文件。
-
通知客户端然后传播至其它客户端:将分布式节点和轻量级消息系统连接起来,整合了Java的事件处理机制和消息中间件的功能。
-
通知服务端然后去更新其它客户端:能管理和传播分布式系统间的消息,像一个分布式执行器,可用于广播状态更改、时间推送等,也可以当作微服务间的通信信道。
-
支持消息代理:
- RabbitMQ
- Kafka
-
总线:在微服务架构中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所微服务实例都连接上来,由于该主题中产生的消息会背所有实例监听和消费,因此称为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其它连接在该主题的实例都知道的消息。
-
基本原理:ConfigClient实例都监听MQ中同一个topic(默认是SpringCloudBus)。当一个服务刷新数据时,他会把这个信息放入到Topic中,这样其它监听同一Topic的服务就都能得到通知,去更新自身的配置。
2.1 使用RabbitMQ实现动态更新配置
- 新建一个与
cloud-config-client3366
完全相同的module:cloud-config-client3355
(除名字和端口以外都相同)。
2.1.1 修改服务端
-
新增依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
-
修改配置文件:
server: port: 3344 spring: application: name: cloud-config-center cloud: config: server: git: skipSslValidation: true uri: https://gitee.com/jminzhou/jm-cloud.git # gitee仓库地址 search-paths: #搜索目录 - jm-cloud label: master #读取分支 #rabbitmq相关配置 rabbitmq: host: localhost port: 5672 username: guest password: guest eureka: client: service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/, # 注入7002 和 7001 ##rabbitmq相关配置,暴露bus刷新配置的端点 SpringCloud Bus动态刷新全局广播 management: endpoints: #暴露bus刷新配置的端点 web: exposure: include: 'bus-refresh'
2.1.2 修改客户端3355和客户端3366
-
新增依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
-
修改配置文件:
server: port: 3355 # 3366 spring: application: name: config-client cloud: config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 uri: http://localhost:3344 #配置中心的地址 # 合起来读取的就是:http://localhost:3344/master/config-dev.yml 配置文件。 ##rabbitmq相关配置,暴露bus刷新配置的端点 rabbitmq: host: localhost port: 5672 username: guest password: guest eureka: client: service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/, # 注入7002 和 7001 # 暴露监控端点 management: endpoints: web: exposure: include: "*"
2.1.3 测试
-
启动所有服务;
-
修改git上配置文件:
-
向服务端发送post请求:
-
重新访问:更新成功
2.2 动态刷新——定点通知
修改需求:更改配置文件之后,通知指定的客户端。
- 更改发送的post请求,指定客户端的地址:
http://localhost:3344/actuator/bus-refresh/localhost:3355/
。