当前位置:网站首页>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
边栏推荐
- Experience sharing of system architecture designers preparing for the exam: from point to surface
- Pycharm跑程序时自动进入测试模式
- Basic method of black box (function) test
- The adequacy of source evaluation forum · observation model test
- seven point two three
- An interview question about interface and implementation in golang
- Based on pexels image material API, sort out the material resource library
- Sqlx library usage
- Leetcode skimming -- guess the size of numbers II 375 medium
- cts测试步骤(卡西欧cts200测试)
猜你喜欢

476-82(322、64、2、46、62、114)

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

Basic method of black box (function) test

My heart's broken! After being cheated by 30000, a 16-year-old girl was unconvinced and cheated by 50000

ag 搜索工具参数详解

Airtest解决“自动装包”过程中需要输入密码的问题(同适用于随机弹框处理)

Programmer's Guide to health quenching 5: introduction to sports Basics

字节一面:TCP 和 UDP 可以使用同一个端口吗?

DDD的Go实战

浅谈web性能优化(一)
随机推荐
Use Navicat to connect to MySQL database through SSH channel (pro test is feasible)
How to choose sentinel vs. hystrix current limiting?
The role of the resize function is "suggestions collection"
I live far away. Is there a good way to open an account? Is it safe to open a stock account by mobile phone?
工作面试总遇秒杀? 看了京东 T8 大咖私藏的秒杀系统笔记, 已献出膝盖
Hello, I'd like to ask questions about C and database operation.
day04_ array
kali修改更新源(无法安全的用该源更新)
Golang language quickly get started to comprehensive practical notes (go language, beego framework, high concurrency chat room, crawler)
Test cases and defect report templates
Dear bosses, how can I print the result of Flink SQL to the console and display it completely?
Miscellaneous notes -- a hodgepodge
两数,三数之和
Interface testing tool restlet client
Focus on data | Haitai Fangyuan directly hits the construction idea of data security governance in the securities industry
租房二三事
Detailed explanation of JVM memory model and structure (five model diagrams)
一道golang中关于recover的面试题
Trusted and controllable way of Tencent cloud database
Huatai Securities account opening process, is it safe to open an account on your mobile phone