赞
踩
建议先去学完SpringCloud-微服务入门之Gateway+Nginx(4),否则下面很多你会看不明白的
要做好微服务的配置管理,则需要处理好以下几个问题:
SpringCloud Config核心就是配置中心,通过一个服务端和多个客户端实现配置服务。具有中心化、版本控制、支持动态更新和语言独立等特性,其优点:
Spring Cloud Config有两个角色Server和Client
1, 当配置客户端获取配置时,服务端及时从Git仓库中获取配置副本,从而保证配置数据为最新。
2,支持从yml、json、properties等文件加载配置
3,配置Eureka可实现服务发现,配置Cloud Bus可实现配置推送更新
4,默认配置存储基于Git,从而支持配置的版本管理。Client只需要在引导配置文件中声明所使用的配置服务器地址即可。
bootstrap.yml文件也是Spring Boot的默认配置文件,而且其加载的时间相比于application.yml更早。application.yml和bootstrap.yml虽然都是Spring Boot的默认配置文件,但是定位却不相同。bootstrap.yml,可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。application.yml 可以用来定义应用级别的,总结就是,bootstrap.yml文件相当于项目启动时的引导文件,内容相对固定 能保证服务正常启动。application.yml文件是针对当前微服务 配置一些细节方面的东西变化比较频繁。
他们两个文件是可以同时存在的那么有人会问了 bootstrap.yml文件内容是从 git 上获取而application.yml 是当前服务的配置文件,如果内容相同会不会冲突 ? 答案不会 bootstrap.yml 加载的时间相比于application.yml更早。 如果有些配置属性相同的话就会被application.yml内覆盖配置
当服务中同时有bootstrap.yml ,application.yml时,application.yml中的端口则不会覆盖掉bootstrap.yml中的端口,也就是 默认使用的是bootstrap.yml的端口号 ,还有就是application.yml在application.properties之前加载,同名属性会被application.properties覆盖, 远程配置中心会最后兜底,覆盖掉所有同名属性
知名的Git远程仓库有国外的GitHub和国内的码云(gitee);但是使用GitHub时,国内的用户经常遇到的问题是访
问速度太慢,有时候还会出现无法连接的情况。如果希望体验更好一些,可以使用国内的Git托管服务——码云(gitee.com)。
与GitHub相比,码云也提供免费的Git仓库。此外,还集成了代码质量检测、项目演示等功能。对于团队协作开发,
码云还提供了项目管理、代码托管、文档管理的服务。本章中使用的远程Git仓库是码云。码云访问地址:https://gitee.com/
创建远程仓库
首先要使用码云上的私有远程git仓库需要先注册帐号;请先自行访问网站并注册帐号,然后使用帐号登录码云控制台并创建公开仓库
新建仓库
公开仓库
在新建的仓库中创建需要被统一配置管理的配置文件。配置文件的命名方式:{application}-{profifile}.yml 或 {application}-{profifile}.properties
application: 为应用名称
profifile: 用于区分开发环境,测试环境、生产环境等
如common-dev.yml,表示公共模块通用开发环境下使用的配置文件
这里将common工程的配置文件application.yml
文件的内容复制作为common-dev.yml
文件的内容,具体配置如下:
创建common-dev.yml配置文件
将之前common模块的application-common.yml内容添加到这个里, 不要eureka配置相关内容,而eureka相关配置保存在其他模块自己的bootstrap.yml里(必须的条件),因为bootstrap.yml优先级比application.yml高,先会去注册中心找config服务,如果找不到那么就会报错
以上都完成了那么 我们就开始搭建搭建配置中心微服务
创建一个config-server
子模块
添加Maven依赖
<dependencies>
<!-- 添加公共模块-->
<dependency>
<groupId>org.example</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
然后添加application.yml
配置文件
#设置端口号
server:
port: 12000
# 设置 服务名 config-server
spring:
application:
name: config-server
profiles:
active: common
cloud:
config:
server:
git:
uri: https://gitee.com/huanminabc/spring-cloud-config.git #码云 配置文件仓库地址
#向Eureka 中注册实例
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8000/eureka,http://127.0.0.1:8001/eureka,http://127.0.0.1:8002/eureka
启动类
package com.itheima.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
以上都完成了那么将eureka服务启动
然后在启动config-server
访问http://localhost:12000/common-dev.yml
先改造producer1的配置, 配置文件信息不再由common模块提供,而是从配置中心获取。
application.yml
内容如下:
server:
port: 9010
# 设置服务名称 会在Eureka中显示
spring:
profiles:
active: common # 使用公共模块的yml合并到当前的yml
application:
name: producer
bootstrap.yml
内容如下:
spring:
cloud:
config:
name: common,producer # 与远程仓库中的配置文件的application保持一致 ,多个配置使用,分割
profile: dev # 远程仓库中的配置文件的profile保持一致
label: master # 远程仓库中(分支名称)
discovery:
enabled: true # 使用配置中心
service-id: config-server # 配置中心服务名称
#向Eureka 中注册实例
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8000/eureka,http://127.0.0.1:8001/eureka,http://127.0.0.1:8002/eureka
然后添加Maven
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
然后在将producer1和producer2也都更换为配置中心的方式 ,其他依赖common模块
的都要改,相关的配置需要在gitee上补充文件
消费者因为使用了feign相关的配置那么我们可以将内容移入远程配置consumer-dev.yml里(需要自己创建)
消费者目前的配置如下:
application.yml
server:
port: 9001
# 设置服务名称 会在Eureka中显示 而且其他方也要用的
spring:
application:
name: consumer
bootstrap.yml
spring:
cloud:
config:
name: common,consumer # 与远程仓库中的配置文件的application保持一致 ,多个配置使用,分割
profile: dev # 远程仓库中的配置文件的profile保持一致
label: master # 远程仓库中(分支名称)
discovery:
enabled: true # 使用配置中心
service-id: config-server # 配置中心服务名称
#向Eureka 中注册实例
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8000/eureka,http://127.0.0.1:8001/eureka,http://127.0.0.1:8002/eureka
注意不要忘记添加Maven依赖
,如果以上服务都能正常启动那么说明没问题,然后访问消费者试试,如果也ok那么就说明配置中心搭建好了
上面的案例会面临着新的问题 就是我们修改gitee中的配置文件内容 但是并不会立马生效 必须重启使用配置文件的那个服务才行,在项目上线后如果我们重启服务肯定是不现实的那么如何在不重启服务的情况下完成刷新配置文件呢?可以使用Spring Cloud Bus来实现配置的自动更新(热部署)。需要注意的是Spring Cloud Bus底层是基于RabbitMQ实现的,默认使用本地的消息队列服务,所以需要提前启动本地RabbitMQ服务(安装RabbitMQ以后才有),如下:
config服务端配置
然后我们在config-server 里pom.xml添加:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
然后修改config-server 里 application.yml 内容
spring:
# rabbitmq的配置信息; 我下面使用的是rabbitmq自带的默认配置
rabbitmq:
host: 127.0.0.1 #ip
port: 5672 #端口 5672 固定端口
username: guest #账号
password: guest #密码
management:
endpoints:
web:
exposure:
# 暴露触发消息总线的地址 : xxx/actuator/bus-refresh 固定的访问方式
include: "*"
重启config-server服务
config客户端配置
在客户端服务添加对应的maven依赖和在需要使用配置刷新的类上加上 @RefreshScope
就行了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--bus-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
注意:自动刷新 只能刷新 @RefreshScope 注解下的配置,一些特殊配置,如数据库等,需要先设置数据库链接ConfigServer类,然后通过加 @RefreshScope 注解方式否则还是需要重启服务的
,然后重启config-server
就行了,必须重启,别忘了,不然客户端会报错的
然后添加rabbitmq配置信息到对应的客户端的远程配置文件里
,这里我以消费者consumer为例:
spring:
# rabbitmq的配置信息; 我下面使用的是rabbitmq自带的默认配置
rabbitmq:
host: 127.0.0.1 #ip
port: 5672 #端口 5672 固定端口
username: guest #账号
password: guest #密码
在消费者consumer的controller里添加一个接口,并且在当前controller类上添加@RefreshScope //动态刷新配置
@Value("${test.name}")
private String name;
@GetMapping("/testConfig")
public ResponseEntity testConfig() {
return ResponseEntity.ok(name);
}
然后我们请求接口
然后我们修改远程配置中的test.name
,之后在请求,发现参数没有变化,这是怎么回事呢? ,因为刷新方式需要我手动或者自动去刷新,自动刷新需要进行配置的
手动刷新就是我们修改了远程配置后,调用config-server服务
提供的内置的刷新缓存接口,然后从新从gitee上读取新的置,
http://localhost:12000/actuator/bus-refresh
POST请求
会有点慢,当刷新完毕后,我们在请求消费者就发现获取的参数就变更了
自动刷新需要利用Gitee中的WebHooks
如果自己测试的话,可以使用内网穿透工具进行代理自己的电脑ip,让外网能访问到自己的电脑,我这里有教程自行参考外网访问内网(内网穿透)
WebHook 推送数据格式说明 ,因为我们/actuator/bus-refresh
不允许发送请求体不然会报错
我们可以在config-server服务内
自己写一个http://域名或者ip/refresh
代理接口来绕过, 添加mvc的Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/refresh")
public class RefreshController {
@Value("${server.port}")
private int port;
@PostMapping("")
public void refresh(){
sendPostRequest("http://127.0.0.1:"+port+"/actuator/bus-refresh");
}
/**
* 向目的URL发送post请求
* @param url 目的url
* @return ResultVO
*/
public static String sendPostRequest(String url){
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
HttpEntity<String> formEntity = new HttpEntity<String>(headers);
return restTemplate.postForObject(url, formEntity, String.class);
}
}
然后我们修改Gitee中的 common-dev.yml 内容test.name
,之后我们回到WebHooks里查看请求记录,每次修改提交…都会自动请求我们的/refresh
刷新接口,而我们内部就会转发请求去访问实际的配置刷新接口,来完成自动化刷新配置的动作
然后你就可以试试了, 修改gitee中的配置后立马就会作用到项目里, 访问的配置信息会一直是最新的
将相同的config-server搭建3个都注册到eureka就行了,当我们刷新一台config-server上的配置那么,全部集群都会进行同步数据的,因为会触发消息队列广播模式,会通知其他的集群节点从新拉取最新数据
config-server: 12000 , config-server1:120001 , config-server2:120002
注意: 如果我们 config-server: 12000 宕机了, 配置中心的自动刷新配置就会失效,但是config的服务还是可以正常使用的,而且还是可以进行手动刷新的 ,因为我们在WebHooks里设置的url是指定ip和端口号的,就算配置的域名,那么域名本身也只能绑定一个应用 ,那么解决办法就是,使用nginx进行负载这3台config-server, 然后将nginx地址作为WebHooks的url
然后我们在WebHooks配置nginx的地址即可 http//:nginx:15000/refresh
, 之后就不用在担心config-server宕机了导致配置不会自动刷新的问题了
先启动eureka,然后在启动config-server,然后在启动其他服务, 不然会出问题的,因为config-server会先注册到eureka中,其他服务才能发现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。