From b4ab4142613df8a30c4c299f24e4f657147ed886 Mon Sep 17 00:00:00 2001 From: Narziss Date: Sun, 29 Sep 2024 09:01:00 +0800 Subject: [PATCH] Optimize interface-level dynamic config --- .../bootstrap/DefaultConsumerBootstrap.java | 78 ++++++++----------- .../apollo/ApolloDynamicConfigManager.java | 42 +++++----- .../nacos/NacosDynamicConfigManager.java | 64 ++++++--------- .../zk/ZookeeperDynamicConfigManager.java | 65 +++++++--------- .../rpc/config/AbstractInterfaceConfig.java | 26 ++++++- .../sofa/rpc/dynamic/ConfigChangedEvent.java | 46 +---------- .../sofa/rpc/dynamic/DynamicConfigKeys.java | 10 ++- .../rpc/dynamic/DynamicConfigManager.java | 19 +++-- .../sofa/rpc/common/utils/StringUtils.java | 5 -- 9 files changed, 148 insertions(+), 207 deletions(-) diff --git a/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java b/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java index 0c4bfc4af..aa1dc4386 100644 --- a/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java +++ b/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java @@ -20,6 +20,7 @@ import com.alipay.sofa.rpc.client.Cluster; import com.alipay.sofa.rpc.client.ClusterFactory; import com.alipay.sofa.rpc.client.ProviderGroup; +import com.alipay.sofa.rpc.common.RpcConstants; import com.alipay.sofa.rpc.common.SofaConfigs; import com.alipay.sofa.rpc.common.SofaOptions; import com.alipay.sofa.rpc.common.utils.CommonUtils; @@ -53,6 +54,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static com.alipay.sofa.rpc.common.RpcConstants.REGISTRY_PROTOCOL_DOMAIN; +import static com.alipay.sofa.common.config.SofaConfigs.getOrDefault; /** * Default consumer bootstrap. @@ -96,6 +98,11 @@ protected DefaultConsumerBootstrap(ConsumerConfig consumerConfig) { */ protected transient volatile CountDownLatch respondRegistries; + /** + * 配置监听器 + */ + protected transient volatile ConfigListener configListener; + /** * 发布的调用者配置(含计数器) */ @@ -145,7 +152,8 @@ public T refer() { // build cluster cluster = ClusterFactory.getCluster(this); // build listeners - consumerConfig.setConfigListener(buildConfigListener(this)); + configListener = buildConfigListener(this); + consumerConfig.setConfigListener(configListener); consumerConfig.setProviderInfoListener(buildProviderInfoListener(this)); // init cluster cluster.init(); @@ -155,26 +163,17 @@ public T refer() { proxyIns = (T) ProxyFactory.buildProxy(consumerConfig.getProxy(), consumerConfig.getProxyClass(), proxyInvoker); - //启用请求级别动态配置 + //请求级别动态配置参数 final String dynamicAlias = consumerConfig.getParameter(DynamicConfigKeys.DYNAMIC_ALIAS); - if (StringUtils.isNotBlank(dynamicAlias)) { - final DynamicConfigManager dynamicManager = DynamicConfigManagerFactory.getDynamicManager( - consumerConfig.getAppName(), dynamicAlias); - dynamicManager.initServiceConfiguration(consumerConfig.getInterfaceId()); - } - - //启用接口级别动态配置 - final String dynamicUrl = consumerConfig.getParameter(DynamicConfigKeys.DYNAMIC_URL); - if (StringUtils.isNotBlank(dynamicUrl)) { + //接口级别动态配置参数 + final String dynamicUrl = getOrDefault(DynamicConfigKeys.DYNAMIC_URL); + if (StringUtils.isBlank(dynamicAlias) & StringUtils.isNotBlank(dynamicUrl)) { + //启用接口级别动态配置 final DynamicConfigManager dynamicManager = DynamicConfigManagerFactory.getDynamicManagerWithUrl( consumerConfig.getAppName(), dynamicUrl); - - //build listeners for dynamic config - consumerConfig.setConfigListener(buildConfigListener(this,dynamicManager)); + dynamicManager.addListener(consumerConfig.getInterfaceId(), configListener); + dynamicManager.initServiceConfiguration(consumerConfig.getInterfaceId(), configListener); } - - - } catch (Exception e) { if (cluster != null) { cluster.destroy(); @@ -214,17 +213,6 @@ protected ConfigListener buildConfigListener(ConsumerBootstrap bootstrap) { return new ConsumerAttributeListener(); } - /** - * Build ConfigListener for consumer bootstrap with dynamic config. - * - * @param bootstrap ConsumerBootstrap - * @param dynamicManager DynamicConfigManager - * @return ConfigListener - */ - protected ConfigListener buildConfigListener(ConsumerBootstrap bootstrap, DynamicConfigManager dynamicManager) { - return new ConsumerAttributeListener(dynamicManager); - } - /** * Build ProviderInfoListener for consumer bootstrap. * @@ -463,28 +451,20 @@ private class ConsumerAttributeListener implements ConfigListener { private Map newValueMap = new HashMap<>(); - ConsumerAttributeListener() { - - } + // 动态配置项 + private List dynamicConfigKeys = Arrays.asList(RpcConstants.CONFIG_KEY_TIMEOUT, + RpcConstants.CONFIG_KEY_RETRIES, RpcConstants.CONFIG_KEY_LOADBALANCER); - ConsumerAttributeListener(DynamicConfigManager dynamicManager) { - this.initWith(consumerConfig.getInterfaceId(),dynamicManager); - } + ConsumerAttributeListener() { - public void initWith(String key, DynamicConfigManager dynamicManager) { - dynamicManager.addListener(key, this); - // 初始化配置值 - String rawConfig = dynamicManager.getConfig(key); - if (!StringUtils.isEmpty(rawConfig)) { - process(new ConfigChangedEvent(key, "sofa-rpc",rawConfig)); - } } @Override - public void process(ConfigChangedEvent event){ - if (event.getChangeType().equals(ConfigChangeType.DELETED)) { - newValueMap = null; - } else { + public void process(ConfigChangedEvent event) { + for (String key : newValueMap.keySet()) { + newValueMap.put(key, " "); + } + if (!event.getChangeType().equals(ConfigChangeType.DELETED)) { // ADDED or MODIFIED String[] lines = event.getContent().split("\n"); for (String line : lines) { @@ -492,7 +472,13 @@ public void process(ConfigChangedEvent event){ if (keyValue.length == 2) { String key = keyValue[0].trim(); String value = keyValue[1].trim(); - newValueMap.put(key, value); + + for (String dynamicConfigKey : dynamicConfigKeys) { + if (key.endsWith(dynamicConfigKey) || key.endsWith("." + dynamicConfigKey)) { + newValueMap.put(key, value); + break; + } + } } } } diff --git a/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java b/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java index e8394b8f8..98ff8c4a5 100644 --- a/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java +++ b/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java @@ -18,6 +18,7 @@ import com.alipay.sofa.common.config.SofaConfigs; import com.alipay.sofa.rpc.auth.AuthRuleGroup; +import com.alipay.sofa.rpc.common.utils.StringUtils; import com.alipay.sofa.rpc.dynamic.*; import com.alipay.sofa.rpc.ext.Extension; import com.alipay.sofa.rpc.listener.ConfigListener; @@ -58,47 +59,50 @@ public class ApolloDynamicConfigManager extends DynamicConfigManager { private final ConcurrentMap watchListenerMap = new ConcurrentHashMap<>(); protected ApolloDynamicConfigManager(String appName) { - super(appName); + super(appName, SofaConfigs.getOrDefault(DynamicConfigKeys.APOLLO_ADDRESS)); System.setProperty(APOLLO_APPID_KEY, appName); - System.setProperty(APOLLO_ADDR_KEY, APOLLO_PROTOCOL_PREFIX + SofaConfigs.getOrDefault(DynamicConfigKeys.APOLLO_ADDRESS)); - config = ConfigService.getConfig(DynamicConfigKeys.DEFAULT_GROUP); + System.setProperty(APOLLO_ADDR_KEY, APOLLO_PROTOCOL_PREFIX + getAddress()); + config = ConfigService.getAppConfig(); } - protected ApolloDynamicConfigManager(String appName,String address) { - super(appName); + protected ApolloDynamicConfigManager(String appName, String address) { + super(appName, address); System.setProperty(APOLLO_APPID_KEY, appName); System.setProperty(APOLLO_ADDR_KEY, APOLLO_PROTOCOL_PREFIX + address); - config = ConfigService.getConfig(DynamicConfigKeys.DEFAULT_GROUP); + config = ConfigService.getAppConfig(); } @Override - public void initServiceConfiguration(String service) { - //TODO not now + public void initServiceConfiguration(String service, ConfigListener listener) { + String rawConfig = config.getProperty(service, DynamicHelper.DEFAULT_DYNAMIC_VALUE); + if (!StringUtils.isEmpty(rawConfig)) { + listener.process(new ConfigChangedEvent(service, rawConfig)); + } } @Override public String getProviderServiceProperty(String service, String key) { return config.getProperty(DynamicConfigKeyHelper.buildProviderServiceProKey(service, key), - DynamicHelper.DEFAULT_DYNAMIC_VALUE); + DynamicHelper.DEFAULT_DYNAMIC_VALUE); } @Override public String getConsumerServiceProperty(String service, String key) { return config.getProperty(DynamicConfigKeyHelper.buildConsumerServiceProKey(service, key), - DynamicHelper.DEFAULT_DYNAMIC_VALUE); + DynamicHelper.DEFAULT_DYNAMIC_VALUE); } @Override public String getProviderMethodProperty(String service, String method, String key) { return config.getProperty(DynamicConfigKeyHelper.buildProviderMethodProKey(service, method, key), - DynamicHelper.DEFAULT_DYNAMIC_VALUE); + DynamicHelper.DEFAULT_DYNAMIC_VALUE); } @Override public String getConsumerMethodProperty(String service, String method, String key) { return config.getProperty(DynamicConfigKeyHelper.buildConsumerMethodProKey(service, method, key), - DynamicHelper.DEFAULT_DYNAMIC_VALUE); + DynamicHelper.DEFAULT_DYNAMIC_VALUE); } @@ -109,12 +113,7 @@ public AuthRuleGroup getServiceAuthRule(String service) { } @Override - public String getConfig(String key){ - return config.getProperty(key, DynamicHelper.DEFAULT_DYNAMIC_VALUE); - } - - @Override - public void addListener(String key, ConfigListener listener){ + public void addListener(String key, ConfigListener listener) { ApolloListener apolloListener = watchListenerMap.computeIfAbsent(key, k -> new ApolloListener()); apolloListener.addListener(listener); config.addChangeListener(apolloListener, Collections.singleton(key)); @@ -124,19 +123,20 @@ public class ApolloListener implements ConfigChangeListener { private Set listeners = new CopyOnWriteArraySet<>(); - ApolloListener() {} + ApolloListener() { + } @Override public void onChange(com.ctrip.framework.apollo.model.ConfigChangeEvent changeEvent) { for (String key : changeEvent.changedKeys()) { ConfigChange change = changeEvent.getChange(key); if ("".equals(change.getNewValue())) { - LOGGER.info("an empty rule is received for key: " + key); + LOGGER.info("an empty rule is received for key: " + key); return; } ConfigChangedEvent event = - new ConfigChangedEvent(key, change.getNamespace(), change.getNewValue(), getChangeType(change)); + new ConfigChangedEvent(key, change.getNewValue(), getChangeType(change)); listeners.forEach(listener -> listener.process(event)); } } diff --git a/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java b/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java index dd58d1bd6..f095e3bac 100644 --- a/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java +++ b/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java @@ -38,8 +38,6 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.Executor; -import static com.alipay.sofa.rpc.common.utils.StringUtils.KEY_SEPARATOR; - /** * @author Narziss * @version NaocsDynamicConfigManager.java, v 0.1 2024年07月26日 09:37 Narziss @@ -48,26 +46,23 @@ @Extension(value = "nacos", override = true) public class NacosDynamicConfigManager extends DynamicConfigManager { - private final static Logger LOGGER = LoggerFactory.getLogger(NacosDynamicConfigManager.class); - - private static final long DEFAULT_TIMEOUT = 5000; + private final static Logger LOGGER = LoggerFactory.getLogger(NacosDynamicConfigManager.class); - private final String address; + private static final long DEFAULT_TIMEOUT = 5000; - private ConfigService configService; + private ConfigService configService; - private Properties nacosConfig = new Properties(); + private Properties nacosConfig = new Properties(); - private final String group; + private final String group; private final ConcurrentMap watchListenerMap = new ConcurrentHashMap<>(); protected NacosDynamicConfigManager(String appName) { - super(appName); - address=SofaConfigs.getOrDefault(DynamicConfigKeys.NACOS_ADDRESS); - group = DynamicConfigKeys.DEFAULT_GROUP; + super(appName, SofaConfigs.getOrDefault(DynamicConfigKeys.NACOS_ADDRESS)); + group = appName; try { - nacosConfig.put(PropertyKeyConst.SERVER_ADDR, address); + nacosConfig.put(PropertyKeyConst.SERVER_ADDR, getAddress()); configService = ConfigFactory.createConfigService(nacosConfig); } catch (NacosException e) { @@ -76,9 +71,8 @@ protected NacosDynamicConfigManager(String appName) { } protected NacosDynamicConfigManager(String appName, String address) { - super(appName); - this.address = address; - group = DynamicConfigKeys.DEFAULT_GROUP; + super(appName, address); + group = appName; try { nacosConfig.put(PropertyKeyConst.SERVER_ADDR, address); configService = ConfigFactory.createConfigService(nacosConfig); @@ -89,16 +83,22 @@ protected NacosDynamicConfigManager(String appName, String address) { } @Override - public void initServiceConfiguration(String service) { - //TODO not now - + public void initServiceConfiguration(String service, ConfigListener listener) { + try { + String rawConfig = configService.getConfig(service, group, DEFAULT_TIMEOUT); + if (!StringUtils.isEmpty(rawConfig)) { + listener.process(new ConfigChangedEvent(service, rawConfig)); + } + } catch (NacosException e) { + LOGGER.error("Failed to getConfig for key:{}, group:{}", service, group, e); + } } @Override public String getProviderServiceProperty(String service, String key) { try { String configValue = configService.getConfig( - DynamicConfigKeyHelper.buildProviderServiceProKey(service, key), + DynamicConfigKeyHelper.buildProviderServiceProKey(service, key), group, DEFAULT_TIMEOUT); return configValue != null ? configValue : DynamicHelper.DEFAULT_DYNAMIC_VALUE; } catch (NacosException e) { @@ -110,7 +110,7 @@ public String getProviderServiceProperty(String service, String key) { public String getConsumerServiceProperty(String service, String key) { try { String configValue = configService.getConfig( - DynamicConfigKeyHelper.buildConsumerServiceProKey(service, key), + DynamicConfigKeyHelper.buildConsumerServiceProKey(service, key), group, DEFAULT_TIMEOUT); return configValue != null ? configValue : DynamicHelper.DEFAULT_DYNAMIC_VALUE; } catch (NacosException e) { @@ -122,7 +122,7 @@ public String getConsumerServiceProperty(String service, String key) { public String getProviderMethodProperty(String service, String method, String key) { try { String configValue = configService.getConfig( - DynamicConfigKeyHelper.buildProviderMethodProKey(service, method, key), + DynamicConfigKeyHelper.buildProviderMethodProKey(service, method, key), group, DEFAULT_TIMEOUT); return configValue != null ? configValue : DynamicHelper.DEFAULT_DYNAMIC_VALUE; } catch (NacosException e) { @@ -134,7 +134,7 @@ public String getProviderMethodProperty(String service, String method, String ke public String getConsumerMethodProperty(String service, String method, String key) { try { String configValue = configService.getConfig( - buildDataId(DynamicConfigKeyHelper.buildConsumerMethodProKey(service, method, key)), + DynamicConfigKeyHelper.buildConsumerMethodProKey(service, method, key), group, DEFAULT_TIMEOUT); return configValue != null ? configValue : DynamicHelper.DEFAULT_DYNAMIC_VALUE; } catch (NacosException e) { @@ -142,33 +142,19 @@ public String getConsumerMethodProperty(String service, String method, String ke } } - public String buildDataId(String proKey) { - return getAppName() + KEY_SEPARATOR + proKey; - } - @Override public AuthRuleGroup getServiceAuthRule(String service) { //TODO 暂不支持 return null; } - @Override - public String getConfig(String key){ - try { - return configService.getConfig(getAppName()+ KEY_SEPARATOR +key, group, DEFAULT_TIMEOUT); - } catch (NacosException e) { - LOGGER.error("Failed to getConfig for key:{}, group:{}", key, group, e); - return DynamicHelper.DEFAULT_DYNAMIC_VALUE; - } - } - @Override public void addListener(String key, ConfigListener listener) { NacosConfigListener nacosConfigListener = watchListenerMap.computeIfAbsent( key, k -> createTargetListener(key)); nacosConfigListener.addListener(listener); try { - configService.addListener(getAppName()+KEY_SEPARATOR +key, group, nacosConfigListener); + configService.addListener(key, group, nacosConfigListener); } catch (NacosException e) { LOGGER.error("Failed to add listener for key:{}, group:{}", key, group, e); } @@ -204,7 +190,7 @@ public Executor getExecutor() { public void innerReceive(String dataId, String group, String configInfo) { String oldValue = cacheData.get(dataId); ConfigChangedEvent event = - new ConfigChangedEvent(dataId, group, configInfo, getChangeType(configInfo, oldValue)); + new ConfigChangedEvent(dataId, configInfo, getChangeType(configInfo, oldValue)); if (configInfo == null) { cacheData.remove(dataId); } else { diff --git a/config/config-zk/src/main/java/com/alipay/sofa/rpc/dynamic/zk/ZookeeperDynamicConfigManager.java b/config/config-zk/src/main/java/com/alipay/sofa/rpc/dynamic/zk/ZookeeperDynamicConfigManager.java index 47dadc444..3dadc150d 100644 --- a/config/config-zk/src/main/java/com/alipay/sofa/rpc/dynamic/zk/ZookeeperDynamicConfigManager.java +++ b/config/config-zk/src/main/java/com/alipay/sofa/rpc/dynamic/zk/ZookeeperDynamicConfigManager.java @@ -19,6 +19,7 @@ import com.alipay.sofa.common.config.SofaConfigs; import com.alipay.sofa.rpc.auth.AuthRuleGroup; import com.alipay.sofa.rpc.common.RpcConstants; +import com.alipay.sofa.rpc.common.utils.StringUtils; import com.alipay.sofa.rpc.dynamic.*; import com.alipay.sofa.rpc.ext.Extension; import com.alipay.sofa.rpc.listener.ConfigListener; @@ -35,7 +36,6 @@ import java.util.concurrent.CopyOnWriteArraySet; import static com.alipay.sofa.rpc.common.utils.StringUtils.CONTEXT_SEP; -import static com.alipay.sofa.rpc.common.utils.StringUtils.KEY_SEPARATOR; /** * @author Narziss @@ -45,27 +45,23 @@ @Extension(value = "zookeeper", override = true) public class ZookeeperDynamicConfigManager extends DynamicConfigManager { - private final static Logger LOGGER = LoggerFactory - .getLogger(ZookeeperDynamicConfigManager.class); + private final static Logger LOGGER = LoggerFactory + .getLogger(ZookeeperDynamicConfigManager.class); - private final CuratorFramework zkClient; - - private final String address; - - private final String rootPath; - private ConcurrentMap configMap = new ConcurrentHashMap<>(); + private final CuratorFramework zkClient; + private final String rootPath; private final ConcurrentMap watchListenerMap = new ConcurrentHashMap<>(); + private ConcurrentMap configMap = new ConcurrentHashMap<>(); protected ZookeeperDynamicConfigManager(String appName) { - super(appName); - rootPath = CONTEXT_SEP + DynamicConfigKeys.CONFIG_NODE + CONTEXT_SEP + DynamicConfigKeys.DEFAULT_GROUP + CONTEXT_SEP + getAppName(); - address = SofaConfigs.getOrDefault(DynamicConfigKeys.ZK_ADDRESS); + super(appName, SofaConfigs.getOrDefault(DynamicConfigKeys.ZK_ADDRESS)); + rootPath = CONTEXT_SEP + DynamicConfigKeys.CONFIG_NODE + CONTEXT_SEP + appName; zkClient = CuratorFrameworkFactory.builder() - .connectString(address) - .retryPolicy(new ExponentialBackoffRetry(1000, 3)) - .namespace(DynamicConfigKeys.DEFAULT_NAMESPACE) - .build(); + .connectString(getAddress()) + .retryPolicy(new ExponentialBackoffRetry(1000, 3)) + .namespace(DynamicConfigKeys.DEFAULT_NAMESPACE) + .build(); zkClient.start(); PathChildrenCache cache = new PathChildrenCache(zkClient, rootPath, true); @@ -97,10 +93,9 @@ public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) th } } - protected ZookeeperDynamicConfigManager(String appName,String address) { - super(appName); - rootPath = CONTEXT_SEP + DynamicConfigKeys.CONFIG_NODE + CONTEXT_SEP + DynamicConfigKeys.DEFAULT_GROUP; - this.address = address; + protected ZookeeperDynamicConfigManager(String appName, String address) { + super(appName, address); + rootPath = CONTEXT_SEP + DynamicConfigKeys.CONFIG_NODE + CONTEXT_SEP + appName; zkClient = CuratorFrameworkFactory.builder() .connectString(address) .retryPolicy(new ExponentialBackoffRetry(1000, 3)) @@ -110,8 +105,16 @@ protected ZookeeperDynamicConfigManager(String appName,String address) { } @Override - public void initServiceConfiguration(String service) { - //TODO not now + public void initServiceConfiguration(String service, ConfigListener listener) { + try { + byte[] bytes = zkClient.getData().forPath(rootPath + CONTEXT_SEP + service); + String rawConfig = new String(bytes, RpcConstants.DEFAULT_CHARSET); + if (!StringUtils.isEmpty(rawConfig)) { + listener.process(new ConfigChangedEvent(service, rawConfig)); + } + } catch (Exception e) { + LOGGER.error("Failed to init service configuration for service: " + service, e); + } } @@ -163,19 +166,8 @@ public AuthRuleGroup getServiceAuthRule(String service) { } @Override - public String getConfig(String key){ - try { - byte[] bytes = zkClient.getData().forPath(rootPath+ CONTEXT_SEP +getAppName()+ KEY_SEPARATOR + key); - String configValue = new String(bytes, RpcConstants.DEFAULT_CHARSET); - return configValue != null ? configValue : DynamicHelper.DEFAULT_DYNAMIC_VALUE; - } catch (Exception e) { - return DynamicHelper.DEFAULT_DYNAMIC_VALUE; - } - } - - @Override - public void addListener(String key, ConfigListener listener){ - String pathKey = rootPath+ CONTEXT_SEP +getAppName()+ KEY_SEPARATOR + key; + public void addListener(String key, ConfigListener listener) { + String pathKey = rootPath + CONTEXT_SEP + key; ZookeeperConfigListener zookeeperConfigListener = watchListenerMap.computeIfAbsent( key, k -> createTargetListener(pathKey)); @@ -224,12 +216,11 @@ public void nodeChanged() throws Exception { content = new String(childData.getData(), RpcConstants.DEFAULT_CHARSET); changeType = ConfigChangeType.MODIFIED; } - ConfigChangedEvent configChangeEvent = new ConfigChangedEvent(pathKey, DynamicConfigKeys.DEFAULT_GROUP, (String) content, changeType); + ConfigChangedEvent configChangeEvent = new ConfigChangedEvent(pathKey, (String) content, changeType); listeners.forEach(listener -> listener.process(configChangeEvent)); } } - } \ No newline at end of file diff --git a/core/api/src/main/java/com/alipay/sofa/rpc/config/AbstractInterfaceConfig.java b/core/api/src/main/java/com/alipay/sofa/rpc/config/AbstractInterfaceConfig.java index acc4a74e1..84c8eec35 100644 --- a/core/api/src/main/java/com/alipay/sofa/rpc/config/AbstractInterfaceConfig.java +++ b/core/api/src/main/java/com/alipay/sofa/rpc/config/AbstractInterfaceConfig.java @@ -215,6 +215,11 @@ public abstract class AbstractInterfaceConfig configValueCache = null; + /** + * 动态配置的方法名称和方法参数配置的map + */ + protected transient volatile Map dynamicConfigValueCache = new ConcurrentHashMap<>(); + /** * 代理接口类,和T对应,主要针对泛化调用 */ @@ -924,6 +929,10 @@ public String queryAttribute(String property) { public boolean updateAttribute(String property, String newValueStr, boolean overwrite) { try { boolean changed = false; + if(newValueStr.equals(" ")){ + // 改为默认值 + newValueStr = configValueCache.get(property) == null ? null : configValueCache.get(property).toString(); + } if (property.charAt(0) == RpcConstants.HIDE_KEY_PREFIX) { // 方法级配置 例如.echoStr.timeout String methodAndP = property.substring(1); @@ -940,6 +949,7 @@ public boolean updateAttribute(String property, String newValueStr, boolean over // 拿到旧的值 Object oldValue = null; Object newValue = CompatibleTypeUtils.convert(newValueStr, propertyClazz); + if (methodConfig == null) { methodConfig = new MethodConfig(); methodConfig.setName(methodName); @@ -960,6 +970,11 @@ public boolean updateAttribute(String property, String newValueStr, boolean over } if (changed && overwrite) { BeanUtils.setProperty(methodConfig, methodProperty, propertyClazz, newValue);// 覆盖属性 + if (newValue != null){ + dynamicConfigValueCache.put(property, newValue); + } else { + dynamicConfigValueCache.remove(property); + } if (LOGGER.isInfoEnabled()) { LOGGER.info("Property \"" + methodName + "." + methodProperty + "\" changed from {} to {}", oldValue, newValueStr); @@ -1016,11 +1031,14 @@ public Object getMethodConfigValue(String methodName, String configKey, Object d * @return 配置值 method config value */ public Object getMethodConfigValue(String methodName, String configKey) { - if (configValueCache == null) { - return null; - } String key = buildmkey(methodName, configKey); - return configValueCache.get(key); + if (dynamicConfigValueCache != null){ + return dynamicConfigValueCache.get(key); + } + if (configValueCache != null) { + return configValueCache.get(key); + } + return null; } /** diff --git a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/ConfigChangedEvent.java b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/ConfigChangedEvent.java index 2dc006610..77d2d06f6 100644 --- a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/ConfigChangedEvent.java +++ b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/ConfigChangedEvent.java @@ -17,7 +17,6 @@ package com.alipay.sofa.rpc.dynamic; import java.util.EventObject; -import java.util.Objects; /** * @author Narziss @@ -28,20 +27,17 @@ public class ConfigChangedEvent extends EventObject { private final String key; - private final String group; - private final String content; private final ConfigChangeType changeType; - public ConfigChangedEvent(String key, String group, String content) { - this(key, group, content, ConfigChangeType.MODIFIED); + public ConfigChangedEvent(String key, String content) { + this(key, content, ConfigChangeType.MODIFIED); } - public ConfigChangedEvent(String key, String group, String content, ConfigChangeType changeType) { - super(key + "," + group); + public ConfigChangedEvent(String key, String content, ConfigChangeType changeType) { + super(key); this.key = key; - this.group = group; this.content = content; this.changeType = changeType; } @@ -50,10 +46,6 @@ public String getKey() { return key; } - public String getGroup() { - return group; - } - public String getContent() { return content; } @@ -61,34 +53,4 @@ public String getContent() { public ConfigChangeType getChangeType() { return changeType; } - - @Override - public String toString() { - return "ConfigChangedEvent{" + "key='" - + key + '\'' + ", group='" - + group + '\'' + ", content='" - + content + '\'' + ", changeType=" - + changeType + "} " - + super.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ConfigChangedEvent)) { - return false; - } - ConfigChangedEvent that = (ConfigChangedEvent) o; - return Objects.equals(getKey(), that.getKey()) - && Objects.equals(getGroup(), that.getGroup()) - && Objects.equals(getContent(), that.getContent()) - && getChangeType() == that.getChangeType(); - } - - @Override - public int hashCode() { - return Objects.hash(getKey(), getGroup(), getContent(), getChangeType()); - } } diff --git a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java index d7929b689..581c7c55e 100644 --- a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java +++ b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java @@ -25,13 +25,17 @@ public class DynamicConfigKeys { public static final String DYNAMIC_ALIAS = "dynamicAlias"; - public static final String DYNAMIC_URL = "dynamicUrl"; - public static final String CONFIG_NODE = "config"; public static final String DEFAULT_NAMESPACE = "sofa-rpc"; - public static final String DEFAULT_GROUP = "sofa-rpc"; + public static ConfigKey DYNAMIC_URL = ConfigKey + .build( + "dynamicUrl", + " ", + false, + "The url of the dynamic configuration.", + new String[] { "dynamicUrl" }); public static ConfigKey ZK_ADDRESS = ConfigKey .build( diff --git a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java index 72f879fcd..76b72aff7 100644 --- a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java +++ b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java @@ -30,21 +30,28 @@ public abstract class DynamicConfigManager { private String appName; - protected DynamicConfigManager(String appName) { + private String address; + + protected DynamicConfigManager(String appName, String address) { this.appName = appName; + this.address = address; } protected String getAppName() { return appName; } + protected String getAddress() { + return address; + } + /** * Init service's governance related configuration. * Such as auth rules、lb rules * * @param service target service */ - public abstract void initServiceConfiguration(String service); + public abstract void initServiceConfiguration(String service, ConfigListener listener); /** * Get provider service related property. @@ -100,12 +107,4 @@ protected String getAppName() { */ public abstract void addListener(String key, ConfigListener listener); - /** - * Get config value by key. - * - * @param key config key - * @return config value - */ - public abstract String getConfig(String key); - } \ No newline at end of file diff --git a/core/common/src/main/java/com/alipay/sofa/rpc/common/utils/StringUtils.java b/core/common/src/main/java/com/alipay/sofa/rpc/common/utils/StringUtils.java index 97bda388b..77febb203 100644 --- a/core/common/src/main/java/com/alipay/sofa/rpc/common/utils/StringUtils.java +++ b/core/common/src/main/java/com/alipay/sofa/rpc/common/utils/StringUtils.java @@ -39,11 +39,6 @@ public class StringUtils { */ public static final String CONTEXT_SEP = "/"; - /** - * The config key separator String {@code ":"} - */ - public static final String KEY_SEPARATOR = ":"; - /** * The string {@code "*"}. *