performance tuning, fix cache registry url creation bug (#6914)
This commit is contained in:
parent
d8fc808425
commit
bcc9513934
|
|
@ -22,9 +22,16 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
|
||||
|
||||
public class DubboServiceAddressURL extends ServiceAddressURL {
|
||||
public static final String[] PROVIDER_FIRST_KEYS = new String[]{RELEASE_KEY, DUBBO_VERSION_KEY, METHODS_KEY, TIMESTAMP_KEY, TAG_KEY};
|
||||
|
||||
public static DubboServiceAddressURL valueOf(String rawURL, URL consumerURL) {
|
||||
return valueOf(rawURL, consumerURL, null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur
|
|||
private static final String RULE_KEY = ApplicationModel.getName() + ".migration";
|
||||
private static final String DUBBO_SERVICEDISCOVERY_MIGRATION = "DUBBO_SERVICEDISCOVERY_MIGRATION";
|
||||
|
||||
private Set<MigrationRuleHandler> listeners = new ConcurrentHashSet<>();
|
||||
private Set<MigrationRuleHandler> handlers = new ConcurrentHashSet<>();
|
||||
private DynamicConfiguration configuration;
|
||||
|
||||
private volatile String rawRule;
|
||||
|
|
@ -71,8 +71,8 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur
|
|||
logger.info("Using the following migration rule to migrate:");
|
||||
logger.info(rawRule);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(listeners)) {
|
||||
listeners.forEach(listener -> listener.doMigrate(rawRule));
|
||||
if (CollectionUtils.isNotEmpty(handlers)) {
|
||||
handlers.forEach(listener -> listener.doMigrate(rawRule));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,10 +85,10 @@ public class MigrationRuleListener implements RegistryProtocolListener, Configur
|
|||
public synchronized void onRefer(RegistryProtocol registryProtocol, ClusterInvoker<?> invoker, URL url) {
|
||||
MigrationInvoker<?> migrationInvoker = (MigrationInvoker<?>) invoker;
|
||||
|
||||
MigrationRuleHandler<?> migrationListener = new MigrationRuleHandler<>(migrationInvoker, url);
|
||||
listeners.add(migrationListener);
|
||||
MigrationRuleHandler<?> migrationRuleHandler = new MigrationRuleHandler<>(migrationInvoker, url);
|
||||
handlers.add(migrationRuleHandler);
|
||||
|
||||
migrationListener.doMigrate(rawRule);
|
||||
migrationRuleHandler.doMigrate(rawRule);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -329,7 +328,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> implements NotifyL
|
|||
|
||||
// Cache key is url that does not merge with consumer side parameters, regardless of how the consumer combines parameters, if the server url changes, then refer again
|
||||
Map<URL, Invoker<T>> localUrlInvokerMap = this.urlInvokerMap; // local reference
|
||||
Invoker<T> invoker = localUrlInvokerMap == null ? null : localUrlInvokerMap.get(url);
|
||||
Invoker<T> invoker = localUrlInvokerMap == null ? null : localUrlInvokerMap.remove(url);
|
||||
if (invoker == null) { // Not in the cache, refer again
|
||||
try {
|
||||
boolean enabled = true;
|
||||
|
|
@ -459,49 +458,31 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> implements NotifyL
|
|||
cachedInvokerUrls = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the invoker in the cache needs to be destroyed
|
||||
* If set attribute of url: refer.autodestroy=false, the invokers will only increase without decreasing,there may be a refer leak
|
||||
*
|
||||
* @param oldUrlInvokerMap
|
||||
* @param newUrlInvokerMap
|
||||
*/
|
||||
private void destroyUnusedInvokers(Map<URL, Invoker<T>> oldUrlInvokerMap, Map<URL, Invoker<T>> newUrlInvokerMap) {
|
||||
if (newUrlInvokerMap == null || newUrlInvokerMap.size() == 0) {
|
||||
destroyAllInvokers();
|
||||
return;
|
||||
}
|
||||
// check deleted invoker
|
||||
List<URL> deleted = null;
|
||||
if (oldUrlInvokerMap != null) {
|
||||
Collection<Invoker<T>> newInvokers = newUrlInvokerMap.values();
|
||||
for (Map.Entry<URL, Invoker<T>> entry : oldUrlInvokerMap.entrySet()) {
|
||||
if (!newInvokers.contains(entry.getValue())) {
|
||||
if (deleted == null) {
|
||||
deleted = new ArrayList<>();
|
||||
|
||||
if (oldUrlInvokerMap == null || oldUrlInvokerMap.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<URL, Invoker<T>> entry : oldUrlInvokerMap.entrySet()) {
|
||||
Invoker<T> invoker = entry.getValue();
|
||||
if (invoker != null) {
|
||||
try {
|
||||
invoker.destroy();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("destroy invoker[" + invoker.getUrl() + "] success. ");
|
||||
}
|
||||
deleted.add(entry.getKey());
|
||||
} catch (Exception e) {
|
||||
logger.warn("destroy invoker[" + invoker.getUrl() + "] failed. " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deleted != null) {
|
||||
for (URL url : deleted) {
|
||||
if (url != null) {
|
||||
Invoker<T> invoker = oldUrlInvokerMap.remove(url);
|
||||
if (invoker != null) {
|
||||
try {
|
||||
invoker.destroy();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("destroy invoker[" + invoker.getUrl() + "] success. ");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("destroy invoker[" + invoker.getUrl() + "] failed. " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("New url total size, " + newUrlInvokerMap.size() + ", destroyed total size " + oldUrlInvokerMap.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -51,17 +51,13 @@ import static org.apache.dubbo.common.constants.CommonConstants.CACHE_CLEAR_TASK
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.CACHE_CLEAR_WAITING_THRESHOLD;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CHECK_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_SEPARATOR_ENCODED;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.OVERRIDE_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTE_PROTOCOL;
|
||||
import static org.apache.dubbo.common.url.component.DubboServiceAddressURL.PROVIDER_FIRST_KEYS;
|
||||
|
||||
/**
|
||||
* Useful for registries who's sdk returns raw string as provider instance, for example, zookeeper and etcd.
|
||||
|
|
@ -85,7 +81,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
|
|||
ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
|
||||
cacheRemovalScheduler = executorRepository.nextScheduledExecutor();
|
||||
cacheRemovalTaskIntervalInMillis = getIntConfig(CACHE_CLEAR_TASK_INTERVAL, 10 * 60 * 1000);
|
||||
cacheClearWaitingThresholdInMillis = getIntConfig(CACHE_CLEAR_WAITING_THRESHOLD, 10 * 60 * 1000);
|
||||
cacheClearWaitingThresholdInMillis = getIntConfig(CACHE_CLEAR_WAITING_THRESHOLD, 30 * 60 * 1000);
|
||||
}
|
||||
|
||||
public CacheableFailbackRegistry(URL url) {
|
||||
|
|
@ -203,18 +199,10 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
|
|||
String rawAddress = parts[0];
|
||||
String rawParams = parts[1];
|
||||
boolean isEncoded = encoded;
|
||||
URLAddress address = stringAddress.computeIfAbsent(rawAddress, k -> {
|
||||
URLAddress newAddress = URLAddress.parse(k, getDefaultURLProtocol(), isEncoded);
|
||||
stringAddress.put(k, newAddress);
|
||||
return newAddress;
|
||||
});
|
||||
URLAddress address = stringAddress.computeIfAbsent(rawAddress, k -> URLAddress.parse(k, getDefaultURLProtocol(), isEncoded));
|
||||
address.setTimestamp(System.currentTimeMillis());
|
||||
|
||||
URLParam param = stringParam.computeIfAbsent(rawParams, k -> {
|
||||
URLParam newParam = URLParam.parse(k, isEncoded, extraParameters);
|
||||
stringParam.put(k, newParam);
|
||||
return newParam;
|
||||
});
|
||||
URLParam param = stringParam.computeIfAbsent(rawParams, k -> URLParam.parse(k, isEncoded, extraParameters));
|
||||
param.setTimestamp(System.currentTimeMillis());
|
||||
|
||||
ServiceAddressURL cachedURL = createServiceURL(address, param, consumerURL);
|
||||
|
|
@ -230,7 +218,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
|
|||
}
|
||||
|
||||
protected URL removeParamsFromConsumer(URL consumer) {
|
||||
return consumer.removeParameters(RELEASE_KEY, DUBBO_VERSION_KEY, METHODS_KEY, TIMESTAMP_KEY, TAG_KEY);
|
||||
return consumer.removeParameters(PROVIDER_FIRST_KEYS);
|
||||
}
|
||||
|
||||
private String stripOffVariableKeys(String rawProvider) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue