performance tuning, fix cache registry url creation bug (#6914)

This commit is contained in:
ken.lj 2020-11-16 18:53:45 +08:00 committed by GitHub
parent d8fc808425
commit bcc9513934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 58 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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) {