当前位置:网站首页>Handwriting distributed configuration center (1)
Handwriting distributed configuration center (1)
2022-07-25 21:24:00 【You who share dry goods】
1 What is a distributed configuration center
In fact, it is to separate some configuration information from its own system , And these information can be obtained in real time by application . Here we use springboot For example , We all know springboot When it starts , Will load resource Under directory application.properties perhaps application.yml. At this time, we will springboot The configuration file that needs to be loaded when starting Not together with the project , Unified management , This is the core idea of distributed configuration center .
1.1 What are the components of the distributed configuration center
1.1.1, There is an interface to operate and configure
1.1.2, Data can be persistent ( To prevent loss , The service offline configuration still exists at startup )
1.1.3, There are clients and servers , The client actively pulls data or the server actively pushes data . And refresh the configuration of this machine .( The core )
1.1.4, Some operation logs of the management interface , Authority system, etc .
2, Mainstream configuration centers in the market
2.1 Ali's nacos
Nacos Dedicated to helping you discover 、 Configure and manage microservices .Nacos Provides an easy-to-use feature set , Helps you quickly implement dynamic service discovery 、 Service configuration 、 Service metadata and traffic management .
Nacos Helps you build more quickly and easily 、 Deliver and manage microservice platforms . Nacos Is to build in “ service ” Modern application architecture centered ( For example, the microservices paradigm 、 Cloud native paradigm ) Service infrastructure . Please refer to the official website for specific use
2.2 nacos Principle , Namely service Monitor whether the configuration changes , Send it to the client through a long link
The schematic diagram of the architecture is as follows , This is push mode , But it is based on long links
2.3 Ctrip's Apollo
Apollo It is a production level configuration center product developed and open-source by Ctrip framework department , It can centrally manage applications in different environments 、 Configuration of different clusters , After configuration modification, it can be pushed to the application end in real time , And have standard authority 、 Process governance and other features , Applicable to microservice configuration management scenarios . Please refer to the official website for specific use
The schematic diagram of Ctrip's architecture is also similar to Nacos It's the same , Also long link polling , Server push mode .
2.3 spirgcloud config
springCloudConfig, It supports the configuration service to be placed in the memory of the configuration service ( Namely local ), It also supports remote Git/svn Warehouse .
When the service starts config Service It will be remotely git Pull configuration file , And save it locally git library , When remote git Is not available , From the local git The file library pulls configuration information . Please refer to the official website for specific use .
2.4 Baidu disconf
Disconf Baidu is an open source product based on Zookeeper Distributed configuration management software . At present, many companies are using , Including drops 、 Baidu 、 NetEase 、 Shunfeng and other companies . The configuration properties can be dynamically modified through simple interface operation , It's very convenient . Use Disconf One of the great benefits found after is that it saves a lot of configuration , And the configuration can be automatically load, In real time .
Basic schematic diagram : Of course, the concrete must be more complicated than this , This is just the main process .
3 How to implement your own distributed configuration center
3.1 Dynamically modify local @Value Configuration of annotations
3.2 In different bean in , same value How to modify at the same time .
4 Specific ideas
How to dynamically modify @Value annotation Configuration of , We need to know springboot How to load application.ym perhaps application.properties Of documents .
I use it here. springboot2.1.1 Code for demonstration .
Start by opening
find spring.factors Configuration file for
We can see that the above three are the loaders of configuration files , It also shows why properties The priority ratio yaml High priority . He is arranged from top to bottom . But the real configuration file executes the following
Let's click to see the implementation class
ConfigFileApplicationListene
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
// How to load resources
addPropertySources(environment, application.getResourceLoader());
}
protected void addPropertySources(ConfigurableEnvironment environment,
ResourceLoader resourceLoader) {
RandomValuePropertySource.addToEnvironment(environment);
// Give resources to load To the environment variable
new Loader(environment, resourceLoader).load();
}
// Reuse propertySource The parser parses
Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
this.environment = environment;
this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(
this.environment);
this.resourceLoader = (resourceLoader != null) ? resourceLoade
: new DefaultResourceLoader();
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(
PropertySourceLoader.class, getClass().getClassLoader());
}Then we will know , That is, if we can EnvironmentPostProcessor , The method in the rewrite can also dynamically load the configuration file . Now let's start the code implementation .
4.1 Code implementation
In that case, we can achieve EnvironmentPostProcessor This class dynamically loads the configuration file through the interface .
The following is the specific code implementation
@Autowired
ConfigurableEnvironment configurableEnvironment;
@Autowired
Environment environment;
@Test
public void test() {
String name = environment.getProperty("name");
System.out.printf(" Before dynamic loading " +name);
Map<String,String> map = new HashMap<>();
map.put("name"," toot toot ");
configurableEnvironment.getPropertySources().addLast(
new OriginTrackedMapPropertySource("xxxx.xml", map)
);
String property = environment.getProperty("name");
System.out.printf(" After dynamic loading " +property);
}4.1.2 unit testing
The end result is
We have now solved the first problem , How to dynamically add environment variables
The second question is @value How to dynamically refresh the annotation .
Then we need ConfigurablePropertyResolver This class , To parse this key , stay find @value Corresponding bean Refresh through reflection
Specific code
4.2 Code implementation
public static void refreshBean(Object bean, ConfigurablePropertyResolver propertyResolver) {
// Definition EL Expression interpreter
SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
TemplateParserContext templateParserContext= new TemplateParserContext();
String keyResolver, valueResolver = null;
Object parserValue;
// Get real object properties
Field[] declaredFields = bean.getClass().getDeclaredFields();
boolean cglib = Arrays.stream(declaredFields).anyMatch(x -> x.getName().contains("CGLIB"));
// If it is cglib The proxy finds its parent
if(cglib){
declaredFields = bean.getClass().getSuperclass().getDeclaredFields();
}
// Traverse Bean All attributes of the instance
for (Field field : declaredFields) {
// Judge field Does it contain @Value annotation
if (field.isAnnotationPresent(Value.class)) {
// Read Value Annotation placeholder
keyResolver = field.getAnnotation(Value.class).value();
try {
// Read property values
valueResolver = propertyResolver.resolveRequiredPlaceholders(keyResolver);
// EL Expression parsing
// Compatible form as :@Value("#{'${codest.five.url}'.split(',')}") contain EL In the case of expressions
Expression expression = spelExpressionParser.parseExpression(valueResolver, templateParserContext);
if(field.getType() == Boolean.class){
parserValue =Boolean.valueOf(expression.getValue().toString());
}
else if(field.getType() == Integer.class){
parserValue =Integer.valueOf(expression.getValue().toString());
}
else if(field.getType() == Long.class){
parserValue =Long.valueOf(expression.getValue().toString());
}else {
parserValue = expression.getValue(field.getType());
}
} catch (IllegalArgumentException e) {
continue;
}
// Determine whether the configuration item exists
if (Objects.nonNull(valueResolver)) {
field.setAccessible(true);
try {
field.set(bean, parserValue);
continue;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}We are writing a unit test test
4.2.1 unit testing
@Autowired
ConfigurableEnvironment configurableEnvironment;
@Autowired
ConfigurablePropertyResolver configurablePropertyResolver;
@Autowired
Person person;
@Test
public void test() {
System.out.printf(" Before dynamic loading " +person.getName());
Map<String,Object> map = new HashMap<>();
map.put("name"," toot toot ");
configurableEnvironment.getPropertySources().forEach( x->{
if (x instanceof OriginTrackedMapPropertySource ) {
Map<String,Object> map1 = (Map<String, Object>) x.getSource();
map1.putAll(map);
}
}
);
refreshBean(person,configurablePropertyResolver);
System.out.printf(" After dynamic loading " +person.getName());
}The final results :
perfect , In the next issue, we will solve Multiple bean, @value How to refresh at the same time .
Specific documents will be sent to Nuggets first , Please pay attention to Nuggets https://juejin.cn/post/7121327906269200421
边栏推荐
- 3阶有向完全图的所有非同构的子图(不同钩子图个数)
- Canvas 填充渐变
- 一道golang中关于接口和实现的面试题
- [ManageEngine] value brought by Siem to enterprises
- How to copy all files in one folder to another folder
- An interview question about concurrent reading and writing of map in golang
- 一道golang中关于recover的面试题
- Test cases and defect report templates
- 作为测试,如何理解线程同步异步
- npm 模块 移除_【已解决】npm卸载模块后该模块并没有从package.json中去掉[通俗易懂]
猜你喜欢

CNN structural design skills: taking into account speed accuracy and engineering implementation

Interface testing tool restlet client

When facing complex problems, systematic thinking helps you understand the essence of the problem

黑盒(功能)测试基本方法

Opencv learning Fourier transform experience and line direction Fourier transform code
![[fiddlertx plug-in] use Fiddler to capture the package Tencent classroom video download (unable to capture the package solution)](/img/de/7a288ee8e6001235d4869c10503932.png)
[fiddlertx plug-in] use Fiddler to capture the package Tencent classroom video download (unable to capture the package solution)

Job interviews are always a second kill? After reading the seckill system notes secretly stored by JD T8, I have given my knees

Miscellaneous notes -- a hodgepodge

Decompile app

Airtest solves the problem that a password needs to be entered in the process of "automatic packaging" (the same applies to random bullet frame processing)
随机推荐
ES6---4个强大运算符(??、??=、?.、?:)
全志芯片bsp命名规则
JMeter distributed pressure measurement
Leetcode skimming -- guess the size of numbers II 375 medium
DDD go practice
The onnx model is exported as a TRT model
npm 模块 移除_【已解决】npm卸载模块后该模块并没有从package.json中去掉[通俗易懂]
Programmer's Guide to health quenching 5: introduction to sports Basics
腾讯云数据库的可信可控之路
I live far away. Is there a good way to open an account? Is it safe to open a stock account by mobile phone?
How to store pictures in the database "suggested collection"
When facing complex problems, systematic thinking helps you understand the essence of the problem
Jmeter分布式压测
3阶有向完全图的所有非同构的子图(不同钩子图个数)
How to choose sentinel vs. hystrix current limiting?
Interviewer of large factory: how to quickly query a table with tens of millions of data?
Isn't it too much to play Gobang in idea?
Introduction to MySQL engine and InnoDB logical storage structure
作为测试,如何理解线程同步异步
Mysql8.0 MHA to achieve high availability "MHA"