添加刷新事件处理以及addListener判断逻辑

pull/1095/head
yangjuanying 2 years ago
parent 70aac11a48
commit e4569710d6

@ -35,15 +35,13 @@ import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* 1. Listen to the Polaris server configuration publishing event 2. Write the changed * 1. Listen to the Polaris server configuration publishing event 2. Write the changed
* configuration content to propertySource 3. Refresh the context through contextRefresher * configuration content to propertySource 3. Refresh the context through contextRefresher
* *
* @author lepdou 2022-03-28 * @author lepdou 2022-03-28
*/ */
public abstract class PolarisConfigPropertyAutoRefresher public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationListener<ApplicationReadyEvent>, PolarisConfigPropertyRefresher {
implements ApplicationListener<ApplicationReadyEvent>, PolarisConfigPropertyRefresher {
private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigPropertyAutoRefresher.class); private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigPropertyAutoRefresher.class);
@ -53,9 +51,7 @@ public abstract class PolarisConfigPropertyAutoRefresher
private final AtomicBoolean registered = new AtomicBoolean(false); private final AtomicBoolean registered = new AtomicBoolean(false);
public PolarisConfigPropertyAutoRefresher( public PolarisConfigPropertyAutoRefresher(PolarisConfigProperties polarisConfigProperties, PolarisPropertySourceManager polarisPropertySourceManager) {
PolarisConfigProperties polarisConfigProperties,
PolarisPropertySourceManager polarisPropertySourceManager) {
this.polarisConfigProperties = polarisConfigProperties; this.polarisConfigProperties = polarisConfigProperties;
this.polarisPropertySourceManager = polarisPropertySourceManager; this.polarisPropertySourceManager = polarisPropertySourceManager;
} }
@ -80,52 +76,75 @@ public abstract class PolarisConfigPropertyAutoRefresher
} }
// register polaris config publish event // register polaris config publish event
registerPolarisConfigPublishChangeListener(polarisPropertySources);
// 增加接收刷新事件接收到事件以后就进行全量配置刷新重新加载PolarisConfigFileLocator同时添加Listener事件
new Thread(new Runnable() {
@Override
public void run() {
for (; ; ) {
try {
List<PolarisPropertySource> polarisPropertySourcesList = PolarisContextRefreshUtil.getRegisterPolarisPropertySourceQueue()
.take();
LOGGER.info("[SCT Config] receive from register queue And start refresh All Config, polarisPropertySourcesList size:{}", polarisPropertySourcesList.size());
refreshConfigurationProperties(null);
LOGGER.info("[SCT Config] start to register configFile polarisPropertySourcesList:{}", polarisPropertySourcesList);
registerPolarisConfigPublishChangeListener(polarisPropertySourcesList);
}
catch (Exception e) {
LOGGER.error("[SCT Config] receive from register queue exception:", e);
}
}
}
}).start();
}
private void registerPolarisConfigPublishChangeListener(List<PolarisPropertySource> polarisPropertySources) {
for (PolarisPropertySource polarisPropertySource : polarisPropertySources) { for (PolarisPropertySource polarisPropertySource : polarisPropertySources) {
polarisPropertySource.getConfigKVFile() ConfigKVFileChangeListener configKVFileChangeListener = configKVFileChangeEvent -> {
.addChangeListener((ConfigKVFileChangeListener) configKVFileChangeEvent -> {
LOGGER.info("[SCT Config] received polaris config change event and will refresh spring context." + " namespace = {}, group = {}, fileName = {}", polarisPropertySource.getNamespace(), polarisPropertySource.getGroup(), polarisPropertySource.getFileName());
LOGGER.info(
"[SCT Config] received polaris config change event and will refresh spring context." Map<String, Object> source = polarisPropertySource.getSource();
+ " namespace = {}, group = {}, fileName = {}",
polarisPropertySource.getNamespace(), for (String changedKey : configKVFileChangeEvent.changedKeys()) {
polarisPropertySource.getGroup(), ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent.getChangeInfo(changedKey);
polarisPropertySource.getFileName());
LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo);
Map<String, Object> source = polarisPropertySource.getSource();
// 新增动态改变日志级别的能力
for (String changedKey : configKVFileChangeEvent.changedKeys()) { try {
ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent if (changedKey.startsWith("logging.level") && changedKey.length() >= 14) {
.getChangeInfo(changedKey); String loggerName = changedKey.substring(14);
String newValue = configPropertyChangeInfo.getNewValue();
LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo); LOGGER.info("[SCT Config] set logging.level loggerName:{}, newValue:{}", loggerName, newValue);
PolarisConfigLoggerContext.setLevel(loggerName, newValue);
// 新增动态改变日志级别的能力
try {
if (changedKey.startsWith("logging.level") && changedKey.length() >= 14) {
String loggerName = changedKey.substring(14);
String newValue = configPropertyChangeInfo.getNewValue();
LOGGER.info("[SCT Config] set logging.level loggerName:{}, newValue:{}", loggerName, newValue);
PolarisConfigLoggerContext.setLevel(loggerName, newValue);
}
}
catch (Exception e) {
LOGGER.error("[SCT Config] set logging.level exception,", e);
}
switch (configPropertyChangeInfo.getChangeType()) {
case MODIFIED:
case ADDED:
source.put(changedKey, configPropertyChangeInfo.getNewValue());
break;
case DELETED:
source.remove(changedKey);
break;
}
// update the attribute with @Value annotation
refreshSpringValue(changedKey);
} }
// update @ConfigurationProperties beans }
refreshConfigurationProperties(configKVFileChangeEvent.changedKeys()); catch (Exception e) {
}); LOGGER.error("[SCT Config] set logging.level exception,", e);
}
switch (configPropertyChangeInfo.getChangeType()) {
case MODIFIED:
case ADDED:
source.put(changedKey, configPropertyChangeInfo.getNewValue());
break;
case DELETED:
source.remove(changedKey);
break;
}
// update the attribute with @Value annotation
refreshSpringValue(changedKey);
}
// update @ConfigurationProperties beans
refreshConfigurationProperties(configKVFileChangeEvent.changedKeys());
};
polarisPropertySource.getConfigKVFile().addChangeListener(configKVFileChangeListener);
// 保存最近添加的ChangeListener
PolarisContextRefreshUtil.getLastPolarisPropertyConfigKVFileMap()
.put(polarisPropertySource, configKVFileChangeListener);
} }
} }
} }

@ -0,0 +1,47 @@
/*
* Copyright (c) 2023 www.tencent.com.
* All Rights Reserved.
* This program is the confidential and proprietary information of
* www.tencent.com ("Confidential Information"). You shall not disclose such
* Confidential Information and shall use it only in accordance with
* the terms of the license agreement you entered into with www.tencent.com.
*/
package com.tencent.cloud.polaris.config.adapter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener;
/**
* @author juanyinyang
*/
public final class PolarisContextRefreshUtil {
// 最近一次的全量PolarisPropertySource集合PolarisPropertySource按 namespace + fileGroup + fileName 确保唯一)
private static final Map<PolarisPropertySource, ConfigKVFileChangeListener> lastPolarisPropertyConfigKVFileMap = new LinkedHashMap<>();
// 命名空间分组namespace + fileGroup的去重Set集合如果这个分组已添加了ConfigFileGroupListener
private static final Set<String> existConfigFileGroupListenerSet = new ConcurrentHashSet<>();
// Queue里存放的是需要添加的配置列表集合这类配置需要重新注册Listener
private static final LinkedBlockingQueue<List<PolarisPropertySource>> registerPolarisPropertySourceQueue = new LinkedBlockingQueue<>(100);
private PolarisContextRefreshUtil() {
}
public static Map<PolarisPropertySource, ConfigKVFileChangeListener> getLastPolarisPropertyConfigKVFileMap() {
return lastPolarisPropertyConfigKVFileMap;
}
public static Set<String> getExistConfigFileGroupListenerSet() {
return existConfigFileGroupListenerSet;
}
public static LinkedBlockingQueue<List<PolarisPropertySource>> getRegisterPolarisPropertySourceQueue() {
return registerPolarisPropertySourceQueue;
}
}

@ -19,11 +19,13 @@
package com.tencent.cloud.polaris.config.adapter; package com.tencent.cloud.polaris.config.adapter;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import com.tencent.polaris.configuration.api.core.ConfigKVFile; import com.tencent.polaris.configuration.api.core.ConfigKVFile;
import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MapPropertySource;
/** /**
* a polaris config file will be wrapped as polaris property source. * a polaris config file will be wrapped as polaris property source.
* *
@ -39,8 +41,7 @@ public class PolarisPropertySource extends MapPropertySource {
private final ConfigKVFile configKVFile; private final ConfigKVFile configKVFile;
public PolarisPropertySource(String namespace, String group, String fileName, public PolarisPropertySource(String namespace, String group, String fileName, ConfigKVFile configKVFile, Map<String, Object> source) {
ConfigKVFile configKVFile, Map<String, Object> source) {
super(namespace + "-" + group + "-" + fileName, source); super(namespace + "-" + group + "-" + fileName, source);
this.namespace = namespace; this.namespace = namespace;
@ -69,9 +70,31 @@ public class PolarisPropertySource extends MapPropertySource {
return configKVFile; return configKVFile;
} }
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + Objects.hash(fileName, group, namespace);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PolarisPropertySource other = (PolarisPropertySource) obj;
return Objects.equals(fileName, other.fileName) && Objects.equals(group, other.group) && Objects.equals(namespace, other.namespace);
}
@Override @Override
public String toString() { public String toString() {
return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" + group + '\'' + ", fileName='" + fileName + '\'' + '}';
+ group + '\'' + ", fileName='" + fileName + '\'' + '}';
} }
} }

Loading…
Cancel
Save