转载

上手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 :

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

访问配置服务端的以下任意地址,都可以显示出对应格式的配置内容:

http://localhost:9999/product-dev.yml

http://localhost:9999/product-dev.properties

http://localhost:9999/product-dev.json

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

可见,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 cloud(三)统一配置中心

如果代码里有操作数据库,那么启动其实会出错,因为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(三)统一配置中心

我们需要做到修改远程配置,应用程序不重启,还需要借助Spring Cloud Bus。Spring Cloud Bus集成了MQ,并为config-server提供了这个配置刷新服务(bus-refresh)。

如下图所示,做法是远端git修改配置后,通过webhook调用config-server的/bus-refresh服务,发布RabbitMQ消息,config-client接收消息并更新配置。

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

我们先安装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

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

原文  https://segmentfault.com/a/1190000018329904
正文到此结束
Loading...