使用spring-cloud-config-server 配合Git仓库,配置中心分为服务端和客户端,这里默认添加了服务注册
服务端步骤:
1、引用依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
2、启动类添加注解
@EnableConfigServer
3、修改配置文件
server:
port: 8091
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/zhonglunsheng/config.git
# 公共仓库可不填
# username:
# password:
basedir: C:/Users/zhonglunsheng/Desktop/Git/SpringCloud/config-server/basedir
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
客户端步骤:
1、同样引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
2、不需要添加注解,只需要修改配置文件
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: config
cloud:
config:
discovery:
service-id: config-server
enabled: true
profile: test
启动后可以访问http://localhost:8091/config-test.yml 查看配置文件
访问的url匹配规则
这里最大的缺点是:如果配置中心也就是Git仓库中文件修改,服务器端和客户端需要重新启动才能生效,不方便
使用消息总线spring-cloud-starter-bus配合消息队列动态刷新
服务器端步骤:
1、在之前的基础上添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
<version>1.3.4.RELEASE</version>
</dependency>
2、配置文件中添加消息队列的配置,这里我使用的是RabbitMq,同时暴露bus/refresh刷新接口
rabbitmq:
host: 192.168.121.131
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include: bus-refresh
客户端配置:
1、跟服务器端一样添加同样的依赖
2、在配置文件中加入消息队列的配置同上,这里就不需要暴露刷新接口了
修改配置时,需要先执行refresh方法:http://localhost:8091/bus/refresh Get请求,POST请求的在后面
命令行
这里Git仓库修改动态刷新利用到其提供的Webhooks功能,使用monitor方式:
先在服务端添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-monitor</artifactId>
</dependency>
然后进行配置,这里需要提供外网,我这里用的是内网映射工具,网上有很多免费的自行搜索
这时你修改仓库里的配置文件,在服务器端会自动刷新,但这里有一个坑的是,服务器端刷新可以,但客户端刷新死活不行,目测SpringCloud的版本有点问题,我这里在启动类自定义一个POST接口来解决
@Value("${server.port}")
private String port;
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
@PostMapping("postRefresh")
public void httpPostJSON() throws IOException {
// 模拟 http 请求
HttpClient httpClient = HttpClientBuilder.create().build();
String url = String.format("http://localhost:%s/actuator/bus-refresh", port);
HttpPost httpPost = new HttpPost(url);
// 设置请求的header
httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
// 执行请求
HttpResponse response = httpClient.execute(httpPost);
}
然后Webhooks那里用这个接口来替换
还需要注意的是:
在客户端如果需要注入从配置中心获取的配置,这里需要在使用的类前添加注解
@RefreshScope
完整代码
@RequestMapping("/index")
@RestController
@RefreshScope
public class IndexController {
@Value("${env}")
private String env;
@RequestMapping("/env")
public String getEnv(){
return env;
}
}
当然也可以把需要注入的写在一个类中
同时需要注意的是,如果有需求想先从配置中心拉取配置后然后在加载本地程序,那么你需要将application.yml替换成bootstrap.yml