spring cloud项目02:中心化配置-P01

Java 8

spring boot 2.5.2

spring cloud 2020.0.3

---

 

spring.io guide:Centralized Configuration

https://spring.io/guides/gs/centralized-configuration/

本文基于上面的官方Guide的练习编写,涉及两个项目:

configserver、web3-client

前者为配置中心服务。

配置存放在本地家目录下的git仓库中:git\configserver

期间解决了 获取中文配置显示乱码的问题。

 

目录

1、建立配置仓库

2、建立配置服务器

3、建立配置客户端并测试

4、解决乱码问题

5、访问远程仓库中的配置

参考文档

 

1、建立配置仓库

Ubuntu虚拟机执行:

$ git init --bare configserver.git

Windows上clone仓库:

# 进入家目录,执行(mylinux是配置了 hosts文件的)
> git clone git@mylinux:/home/git/gitrepo/configserver.git

添加项目web3-client需要用到的配置文件 web3-client.properties:

web3-client.properties 的内容(后面会更改,更改后要让配置立即生效):来自cnblogs.com

hello=lib
todo=work
message=hello world!
国家=中国

执行 git add、commit、push 将 配置文件 提交到远程仓库(这个过程在开发期间会 执行多次):

C:\Users\Mi\git\configserver>git add web3-client.properties

C:\Users\Mi\git\configserver>git commit -m "修改web3-client 1230"
[master c4b43ea] 修改web3-client 1230
 1 file changed, 2 insertions(+), 1 deletion(-)

C:\Users\Mi\git\configserver>git push origin master
git@mylinux's password:
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 318 bytes | 318.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To mylinux:/home/git/gitrepo/configserver.git
   cccbaac..c4b43ea  master -> master

 

2、建立配置服务器

访问 https://start.spring.io/ ,添加依赖 spring-cloud-config-server:

在入口类ConfigserverApplication 添加 @EnableConfigServer 注解:

@EnableConfigServer
@SpringBootApplication
public class ConfigserverApplication {

	public static void main(String[] args) {

修改 application.properties:

server.port=10000

spring.application.name=configserver

# 本地仓库
spring.cloud.config.server.git.uri=c:/Users/Mi/git/configserver

准备完毕,启动 configserver,启动后使用端口 10000。 来自cnblogs.com

 

3、建立配置客户端并测试

访问 https://start.spring.io/ ,添加依赖 spring-cloud-starter-config等:

	<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>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>

注:依赖 spring-boot-starter-actuator 是为了 使用其 refresh端点 及时刷新配置。来自cnblogs.com

配置application.properties:

server.port=8083

# 必须:项目就是根据这个去 配置服务 获取其配置信息的!
spring.application.name=web3-client

# 配置服务器的地址,这里用的是 localhost
spring.config.import=optional:configserver:http://localhost:10000/

# 暴露actuator中的所有端点,包括/refresh
management.endpoints.web.exposure.include=*

添加控制器获取配置:

@RestController
@RequestMapping(value="hello")
class HelloController {
	
	@Value("${message}")
	private String message;
	
	@Autowired
	private Environment env;
	
    // 方式1
	@GetMapping(value="getMessage")
	public String getMessage() {
		return message;
	}
    
	// 方式2
	@GetMapping(value="getMessage2")
	public String getMessage2() {
		return env.getProperty("message");
	}
	
    // 方式2:综合
	@GetMapping(value="getByKey")
	public String getByKey(@RequestParam String key) {
		return env.getProperty(key);
	}
	
}

 启动 web3-client 项目,访问上面三个接口:

# Postman进行测试
localhost:8083/hello/getMessage
hello world!

localhost:8083/hello/getMessage2
hello world!

localhost:8083/hello/getByKey?key=message
hello world!

localhost:8083/hello/getByKey?key=国家
错误:什么也没有返回

 读取到了配置,但是,key为“国家”的没有获取成功——Java可是支持中文的。来自cnblogs.com

 

修改仓库文件中message为“欢迎来到地球”,并提交。

hello=lib
todo=work
message=欢迎来到地球!
国家=中国

配置没有自动更新,此时,执行 web3-client服务的 /refresh端点:

 

再次访问3个接口:来自cnblogs.com

localhost:8083/hello/getMessage
hello world!

localhost:8083/hello/getMessage2
欢迎来到地球!

localhost:8083/hello/getByKey?key=message
欢迎来到地球!

第一个url的结果没有更新,其使用 @Value注解 获取的数据(官方Guide 说 使用 @RefreshScope 注解解决——亲测有效),而后面两个出现了乱码

 

4、解决乱码问题

只需要在 配置服务器项目 configserver 上更改即可。来自cnblogs.com

参考文档2 的 前三步 即可解决问题,但参考文档2 中第一步的 loadProperties 需要修改。

因此,修改后的 MyPropertiesHandler 如下:来自cnblogs.com

MyPropertiesHandler
package org.lib.configserver;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.lib.configserver.OriginTrackedPropertiesLoader.Document;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

public class MyPropertiesHandler implements PropertySourceLoader {

	@Override
	public String[] getFileExtensions() {
		return new String[]{"properties", "xml"};
	}

	@Override
	public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
		Map<String, ?> properties = loadProperties(resource);
        if (properties.isEmpty()) {
            return Collections.emptyList();
        }
        return Collections.singletonList(new OriginTrackedMapPropertySource(name, properties));
	}
	
	private Map<String, ?> loadProperties(Resource resource) throws IOException {
        String filename = resource.getFilename();
        if (filename != null && filename.endsWith(".xml")) {
            return (Map) PropertiesLoaderUtils.loadProperties(resource);
        }
        
        // 更改:解决返回值类型错误问题(或可再研究,再改进)
        List<Document> doclist = new OriginTrackedPropertiesLoader(resource).load();
        System.out.println("doclist.size=" + doclist.size());
        Map<String, Object> retmap = new HashMap<>(32);
        doclist.forEach(doc->{
        	retmap.putAll(doc.asMap());
        });
        System.out.println("retmap=" + retmap);
        return retmap;
    }

}

注意,MyPropertiesHandler中有两个 System.out.println输出!来自cnblogs.com

 拷贝 OriginTrackedPropertiesLoader 到项目,并修改其中的 202行的字符集 为 StandardCharsets.UTF_8

在 resources下新建 META-INF 文件夹,新建一个 spring.factories 文件,内容:

org.springframework.boot.env.PropertySourceLoader=org.lib.configserver.MyPropertiesHandler

 

重启 configserver、web3-client,再次测试web3-client的接口,结果如下:

localhost:8083/hello/getMessage
欢迎来到地球!

localhost:8083/hello/getMessage
欢迎来到地球!

localhost:8083/hello/getByKey?key=message
欢迎来到地球!

localhost:8083/hello/getByKey?key=国家
中国

 

一切正常,乱码问题解决了!😬来自cnblogs.com

 

注:启动web3-client时,configserver输出了下面的日志(前两个是 MyPropertiesHandler 中的 输出信息,使用时需要 去掉):

doclist.size=1
retmap={message=欢迎来到地球!, todo=work, 国家=中国, hello=lib}
2021-07-28 14:52:42.684  INFO 16084 --- [io-10000-exec-5] o.s.c.c.s.e.NativeEnvironmentRepository  : 
Adding property source: Config resource 'file [C:\Users\Mi\AppData\Local\Temp\config-repo-1438464604143936187\
web3-client.properties]' via location 'file:/C:/Users/Mi/AppData/Local/Temp/config-repo-1438464604143936187/'

 

/META-INF/spring.factories 有什么用?

在入口类执行 run(...) 函数时调试,可以找到:

public final class SpringFactoriesLoader {

	/**
	 * The location to look for factories.
	 * <p>Can be present in multiple JAR files.
	 */
	public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

在 configserver 打包后,可以在其中找到这个文件——classpath下:

spring boot、spring cloud的官方文档中会有详细的结束,用处很大。

 

5、访问远程仓库中的配置

修改项目configserver中的application.properties:

# 本地仓库
#spring.cloud.config.server.git.uri=c:/Users/Mi/git/configserver

# 远程仓库:Ubuntu中(mylinux是hosts中配置的域名)
spring.cloud.config.server.git.uri=git@mylinux:/home/git/gitrepo/configserver.git
spring.cloud.config.server.git.username=git
spring.cloud.config.server.git.password=git

配置完毕,重启两个服务,再次测试:成功获取配置。

 

spring-cloud-config-server包结构展示:

 

spring-cloud-starter-config包结构展示:

 

更进一步:

1、结合服务注册中心使用 配置服务,单点的配置服务用于生产环境肯定是有风险的,至少双点才行;

2、项目目前是从master获取配置,那么,不同环境的配置在 git中怎么存储呢?客户端又要怎么获取呢?服务器又要做什么配置呢?

 

参考文档

1、springcloud config中文乱码问题

2、springcloud config自动刷新中文乱码问题

3、git 远程仓库回退的两种方式

4、SpringBoot配置分析、获取到SpringBoot配置文件信息以及几种获取配置文件信息的方式

5、

 

posted @ 2021-07-28 15:32  快乐的凡人721  阅读(470)  评论(0编辑  收藏  举报