上手spring cloud(三)统一配置中心

统一配置中心
Spring Cloud Config为各应用环境提供了一个中心化的外部配置。配置服务器默认采用git来存储配置信息,这样就有助于对配置进行版本管理,并且可以通过git客户端工具来方便维护配置内容。当然它也提供本地化文件系统的存储方式。
使用集中式配置管理,在配置变更时,可以通知到各应用程序,应用程序不需要重启。
Config Server
创建Config Server端工程config-server:
File -> New->Product… -> 选择Spring Initializr -> Project SDK用1.8 -> Next -> 输入Product Metadata -> Next
(springboot选择2.0以上)
选择Cloud Discovery -> 选择Eureka Discovery
选择Cloud Config -> 选择Config Server
由于选择了Eureka Discovery和Config Server,创建成功后pom.xml里已经帮你引入了以下依赖:
<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>
Config Server也是要注册到Eureka,作为Eureka Client,我们还要加入如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!– 避免后面的数据库配置出错,mysql依赖也加了 –>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
再给启动类加上注解@EnableDiscoveryClient和@EnableConfigServer:
package com.hicoview.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class EurekaApplication {

public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}

}
配置application.yml:
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: config
cloud:
config:
server:
git:
uri: http://code.hicoview.com:8000/backend/config.git
username: root
password: 8ggf9afd6g9gj
# 配置文件下载后存储的本地目录
basedir: /Users/zhutx/springcloud/config/basedir
server:
port: 9999
然后按照配置的git仓库地址,在github或gitlab上创建config仓库。以商品微服务的配置来演示,在config仓库创建product-dev.yml:
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: passwd_1986
url: jdbc:mysql://127.0.0.1:3306/SpringCloud_Sell?characterEncoding=utf-8&useSSL=false
启动作为Config Server的config-server工程,查看http://localhost:8761:

访问配置服务端的以下任意地址,都可以显示出对应格式的配置内容:http://localhost:9999/product-dev.ymlhttp://localhost:9999/product-dev.propertieshttp://localhost:9999/product-dev.json

可见,Config Server获取到了远程git仓库上的配置,并将其作为自身的REST服务提供了出去。
接下来我们看看配置客户端Config Client(即product-server)怎么引用配置。
Config Client
我们给product-server加入配置客户端的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
修改application.yml配置:
spring:
application:
name: product
cloud:
config:
discovery:
enabled: true
service-id: CONFIG
profile: dev
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
这样子就可以从Eureka服务注册中心找到CONFIG服务,并拿到product-dev.yml了。
启动product-server,查看eureka注册中心,CONFIG这个Config Server服务已经注册上去了:

如果代码里有操作数据库,那么启动其实会出错,因为spring boot不知道配置加载顺序。
我们期望先拿到CONFIG的配置,再初始化数据库。
解决办法是把product-server的application.yml改成bootstrap.yml就好。
微服务工程使用配置服务的情况下,注意将application.yml都改成bootstrap.yml。并且,让bootstrap.yml文件只保留Eureka配置和获取Config Server服务的配置;
另外,如果生产环境要使用统一配置中心,可以启动多个Config Server进程,保持高可用。

同样的操作,把order-server配置也抽取到外部

Spring Cloud Bus
下图是当前的配置工作机制,config-server拉取远端git配置,并在本地存一份。然后config-server通过把自身注册到Eureka从而提供了拉取配置的服务,而配置客户端(product和order)通过引入config-client依赖,在启动时便能获取加载到了配置。
我们需要做到修改远程配置,应用程序不重启,还需要借助Spring Cloud Bus。Spring Cloud Bus集成了MQ,并为config-server提供了这个配置刷新服务(bus-refresh)。
如下图所示,做法是远端git修改配置后,通过webhook调用config-server的/bus-refresh服务,发布RabbitMQ消息,config-client接收消息并更新配置。

我们先安装RabbitMQ:
# docker安装rabbitmq
docker run -d –hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.7.9-management
# 验证下
docker ps | grep ‘rabbitmq’
能成功访问RabbitMQ控制台http://localhost:15671,继续。
修改Config Server端,增加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
修改application.yml,增加以下配置,把包括bus-refresh在内的所有config server的服务都暴露出来:
management:
endpoints:
web:
exposure:
include: “*”
我们拿product-server来演示,修改product-server的pom增加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
然后提供一个接口,方便我们在配置变验证结果:
@RestController
@RequestMapping(“/env”)
@RefreshScope
public class EnvController {

@Value(“${env}”)
private String env;

@GetMapping(“/print”)
public String print() {
return env;
}
}
测试下,我们修改远端git配置,先增加env配置:
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: passwd_1986
url: jdbc:mysql://127.0.0.1:3306/SpringCloud_Sell?characterEncoding=utf-8&useSSL=false
# 增加了该配置
env:
dev
重启下config-server和product-server。访问 product-server http://localhost:8080/env/print,显示dev然后我们把远端env配置项改成test调用config-server的配置刷新服务 bus-refresh:
curl -v -X POST http://localhost:9999/actuator/bus-refresh
再次访问 product-server http://localhost:8080/env/print,显示test
至此,已经做到了变更配置不重启应用。我们再借助Git仓库的webhook功能,在push指令发生后帮我们发个bus-refresh请求就完美了。Gitlab的话在仓库的这个位置:
Repository -> Settings -> Integrations -> Add webhook

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理