Detailed Explanation of Using and Refreshing the SpringCloudConfigServer Configuration Center

1. Why not use nacos

The previous project used nacos as the configuration center. During the use, there were still many problems:

  • The choice of nacos is to use the service registration and discovery of nacos at the same time, but in the production environment, many projects have suffered from split-brain failures, including the service discovery capability of
    nacos that was abandoned after versions 1.x and 2.x, and only configuration center capability
  • nacos has its own management background, which needs to maintain the account password separately, which is not convenient for management.
    Note: It seems that LDAP is also supported, so I didn’t research
  • It can only be edited based on the rich text box of the browser, and the editing operation is inconvenient
    Note: Copy it out and then copy it back? Too many steps to make mistakes
  • When submitting modifications, the comparison is also based on the browser's own solution, which is still inconvenient
  • It is troublesome to trace back the historical version, it is inconvenient to retrieve, it cannot be compared, and there is a 30-day limit
  • To increase the common configuration of all modules, all modules need to be modified accordingly to add spring.cloud.nacos.config.shared-configsconfiguration

Based on the above reasons, the new project decided to abandon nacos and use SpringCloud's native configuration center for the following reasons:

  • Spring Cloud's configuration center, using git as a configuration data source
    • Support gitlab, github, gitee, etc.
    • Local files, easy to edit
    • Git's version management mechanism, team management, submission, comparison, branch merging and other sound mechanisms
    • Multiple default global configurations are supported:
      • application.ymlAffects all modules in all environments
      • application-test.ymlAll modules that affect the test environment
      • xxx.ymlThe specified module of xxx that affects all environments
      • xxx-test.ymlThe specified module xxx that affects the test environment

Of course, nacos has an advantage that it integrates the configuration automatic refresh capability;
and SpringCloud's configuration center needs to integrate message middleware such as kafka or rabbitmq to have the configuration automatic refresh capability.
Let's introduce the use of Spring Cloud's configuration center.
This article is based on:

  • IDEA2022.1.3
  • SpringBoot 2.7.9
  • SpringCloud 2021.0.6
  • java 1.8

2. Build the configuration center server

1. Create a git configuration store

You can create a new project storage on git,
or create a new subdirectory in the existing git project, dedicated to storing all configurations.
I created a new directory in an existing project of gitee, called spring-configs, and uploaded it in advance Several configuration files:
insert image description here
Note: In the actual test, it was found that github is basically not connected to the network, so use gitee to test

2. New project + Maven dependency

Create a new project in IDEA, configure the name, language, group, type, software package, JDK version, java version, etc.:
insert image description here

  • Add maven dependencies
    In the next step, select Spring Boot version 2.7.9 (because 3.x does not support Java1.8), and check the dependencies Config Server
    insert image description here
    Note: It is recommended to check the dependencies in the new project, and modify the pom.xml later. troublesome

3. Code and configuration modification

  • Open mainthe class where the function is located and add annotations@EnableConfigServer
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class MyConfigServerDemoApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(MyConfigServerDemoApplication.class, args);
    }
}
  • Delete in the resources directory application.propertiesand create a new file application.yml
    Note: I like the yml format, you can also edit it directlyapplication.properties
  • Open application.yml, add git configuration:
server:
  port: 8999  # 配置中心服务端在8999端口监听

spring:
  application:
    name: my-config-server-demo

  # 配置完直接启动即可,访问方式:
  # http://localhost:8999/{spring.application.name}/{spring.profiles.active}/{git分支}
  # {spring.application.name} 必需,就是具体项目的项目名(yml里配置的),不是config-server的哦
  # {spring.profiles.active} 必需,就是具体项目的环境(yml里配置的),注:具体项目可以不配置,使用默认值
  # {git分支} 可空,git配置文件所在的分支,默认使用下面的default-label
  #
  # 注意:server项目启动后,会把git项目clone到本地,如windows系统会在 C:\Users\xxx\AppData\Local\Temp\config-repo-xxx
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/youbl/my-demo.git # git项目的url地址,支持gitlab、github、gitee等
          search-paths: spring-configs          # git项目下,存放yml配置文件的子目录
          username: beinet                      # git账号
          password: 123456                      # git密码
          default-label: master   # 默认会获取main分支,不存在就报错: No such label: main
          timeout: 6              # 读取git的超时时间,默认5秒
          #clone-on-start: true                 # 启动时把配置clone到本地,默认false,第一次访问会比较慢
          #basedir:	c:/abc  					# 本地默认工作目录
          #refresh-rate: 100                    # 服务从git更新配置的时间间隔,单位秒,默认值0,表示每次请求都去获取最新配置
          skip-ssl-validation: true             # 忽略git地址的ssl错误: unable to find valid certification path to requested target

OK, start
the above project under the preview of the project. After the startup is complete, visit the address: http://localhost:8999/config-client-demo/test
you can see a json similar to the following, listing all the yml files that the project will access, and their contents:

{
    
    
  "name": "config-client-demo",
  "profiles": [
    "test"
  ],
  "label": null,
  "version": "169ff9974ccc09c594995ceabac26c983cd607bf",
  "state": null,
  "propertySources": [
    {
    
    
      "name": "https://gitee.com/youbl/my-demo.git/spring-configs/config-client-demo-test.yml",
      "source": {
    
    
        "beinet.config": "配置中心的front-study-test值",
        "beinet.tttt": "abdefssadfga"
      }
    },
    {
    
    
      "name": "https://gitee.com/youbl/my-demo.git/spring-configs/application-test.yml",
      "source": {
    
    
        "beinet.config": "配置中心的全局-test值",
        "beinet.tttt": "abdefs",
        "beinet.newVal": "2惹2"
      }
    },
    {
    
    
      "name": "https://gitee.com/youbl/my-demo.git/spring-configs/config-client-demo.yml",
      "source": {
    
    
        "beinet.config": "配置中心的front-study默认值",
        "beinet.tttt": "abdefs"
      }
    },
    {
    
    
      "name": "https://gitee.com/youbl/my-demo.git/spring-configs/application.yml",
      "source": {
    
    
        "beinet.config": "配置中心的全局值",
        "beinet.tttt": "abdefs"
      }
    }
  ]
}

3. SpringBoot client connection access configuration center

After the configuration center server is built, the next step is to configure the client to connect and access the configuration of the configuration center.

1. Add maven dependency

  • When creating a new project, on the dependency page, just check it Config Clientto complete the dependency addition.
    Note: For a new project, to open the pom, add the following dependencies:
    <dependency> <!-- 用于加载bootstrap.yml配置,否则报错 No spring.config.import property has been defined -->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
  • If it is an old project, open the pom.xml file of the project and add the configuration:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.9</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>2021.0.6</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency> <!-- 用于加载bootstrap.yml配置,否则报错 No spring.config.import property has been defined -->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2. Add bootstrap.ymlconfiguration

In the project resourcesdirectory, create a new file bootstrap.yml, content reference:

spring:
  application:
    name: config-client-demo           # 项目名,配置中心读取配置用
  cloud:
    config:
      uri: http://localhost:8999       # 指定配置中心的url
      profile: test                    # 指定使用哪个配置,可以搭配spring.profiles.active使用
      label: master                    # 指定分支,可为空,默认取主干

Note: If an error is reported: No spring.config.import property has been defined
confirm whether the Maven dependency is missingspring-cloud-starter-bootstrap

OK, start the client, and output the configuration written in the configuration center to
try. Test reference code:

package beinet.cn.configclientdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;

@SpringBootApplication
public class ConfigClientDemoApplication implements CommandLineRunner {
    
    

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

    @Autowired
    Environment env;
    @Override
    public void run(String... args) throws Exception {
    
    
        System.out.println(env.getProperty("beinet.config"));
    }
}

4. Client configuration refresh

After the client successfully connects to the configuration center, it can only read the configuration at startup.
If the configuration on git is modified, the client must be restarted to load the latest configuration.
Here is how to manually refresh the client configuration.

1. Add actuator dependency

Open the pom.xml of the client project config-client-demoand add the following dependencies:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. Configuration modification

Open the client project config-client-demoand bootstrap.ymladd the following configuration:

management:
  endpoints:
    web:
      exposure:
        include: "refresh"   # 用*表示暴露全部

3. Add RefreshScopeannotations

Add annotations to classes that have read configuration and need to be refreshed RefreshScope, such as:

@Component
@RefreshScope
public class ConfigTest2 {
    
    

    @Value("${beinet.newVal}")
    String str3;

    public String getStr3() {
    
    
        return str3;
    }
}

4. Adjust the client interface and refresh the configuration

OK, when the configuration of the configuration center changes, the configuration refresh can be completed by manually calling the interface of the client: the
POST http://localhost:8080/actuator/refresh
corresponding CURL command: curl -X POST http://localhost:8080/actuator/refresh
after executing the interface request, you can see the log of the client, and there will be more logs for reloading the configuration, for example :

2023-03-22 13:38:37.976  INFO 2260 --- [nio-8080-exec-8] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8999
2023-03-22 13:38:38.844  INFO 2260 --- [nio-8080-exec-8] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=config-client-demo, profiles=[test], label=master, version=e5b67cb61ad976c2c1bd863dae769aabf1553c21, state=null
2023-03-22 13:38:38.844  INFO 2260 --- [nio-8080-exec-8] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-https://gitee.com/youbl/my-demo.git/spring-configs/config-client-demo-test.yml'}, BootstrapPropertySource {name='bootstrapProperties-https://gitee.com/youbl/my-demo.git/spring-configs/application-test.yml'}, BootstrapPropertySource {name='bootstrapProperties-https://gitee.com/youbl/my-demo.git/spring-configs/config-client-demo.yml'}, BootstrapPropertySource {name='bootstrapProperties-https://gitee.com/youbl/my-demo.git/spring-configs/application.yml'}]
2023-03-22 13:38:38.846  INFO 2260 --- [nio-8080-exec-8] o.s.boot.SpringApplication               : No active profile set, falling back to 1 default profile: "default"
2023-03-22 13:38:38.849  INFO 2260 --- [nio-8080-exec-8] o.s.boot.SpringApplication               : Started application in 0.998 seconds (JVM running for 402.306)
配置中心的front-study-test值..

5. Refresh the notes

  • The passed EnvironmentBean reads the configuration and will be refreshed
  • RefreshScopeConfigurations without annotations will not be refreshed
  • The class where the main function is located will not be refreshed, even if it is RefreshScopeadded

5. Automatically refresh all client configurations through the bus message bus

The above method can only refresh the configuration of a single client, and will not refresh the configuration of other services.
Even if a service deploys multiple machines, other machines will not be refreshed.
You need to know which machines each service is deployed on, and call interface refresh one machine at a time.

In this section, we will introduce how to notify all clients on the server side of the configuration center to automatically refresh the configuration.
Principle description:

  • Call the API of the configuration center server to notify the refresh
  • Configure the central server to deliver messages to Kafka
  • All clients listen to Kafka messages and perform refresh configuration

1. Add dependencies and configuration on the server side

  • Open the configuration center server pom.xmland add the following dependencies:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
  • Open the configuration center server application.yml, add the following configuration, and enable bus message push:
spring:
  cloud:
    # 启用bus后,对应的消息队列(如kafka)会自动创建一个topic springCloudBus
    # 使用 curl -X POST http://localhost:8999/actuator/busrefresh 会触发消息推送到这个topic,供client使用
    bus:
      refresh:
        enabled: true
  kafka:
    bootstrap-servers: 10.1.2.3:9092  # 用到的Kafka连接信息
management:
  endpoints:
    web:
      exposure:
        include: "busrefresh"   # 用*表示暴露全部

OK, you can start the configuration center server.

2. The client adds dependencies and configurations

  • Open each client pom.xmland add the following dependencies:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
  • Open each client bootstrap.yml, add kafka configuration, and enable bus message consumption:
spring:
  kafka:
    bootstrap-servers: 10.1.2.3:9092  # 用到的Kafka连接信息

OK, let's start these clients.

3. Adjust the server interface and refresh all client configurations

OK, when the configuration of the configuration center is changed,
it is still necessary to call the interface manually, but the interface of the server is called to complete the configuration refresh of all clients: the
POST http://localhost:8999/actuator/busrefresh
corresponding CURL command:curl -X POST http://localhost:8999/actuator/busrefresh

After executing the interface request, you can see that the server and each client will have more logs for reloading the configuration

Finally, the original configuration center is not good at this point. If you change the configuration, you must manually adjust the interface to refresh it.

Guess you like

Origin blog.csdn.net/youbl/article/details/129586392