You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2020/11/06 06:47:55 UTC

[dubbo] branch 3.0 updated: [3.0] enhance migration rule: support interface configuration (#6883)

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 26b9169  [3.0] enhance migration rule: support interface configuration (#6883)
26b9169 is described below

commit 26b916951d501e3af0e16cf9bcf9b9bb0ae0df54
Author: ken.lj <ke...@gmail.com>
AuthorDate: Fri Nov 6 14:31:16 2020 +0800

    [3.0] enhance migration rule: support interface configuration (#6883)
---
 .../DefaultMigrationAddressComparator.java         |  7 ++-
 .../migration/MigrationAddressComparator.java      |  3 +-
 .../client/migration/MigrationClusterInvoker.java  |  5 ++
 .../client/migration/MigrationInvoker.java         | 14 +++++-
 .../client/migration/MigrationRuleHandler.java     | 18 +++++--
 .../client/migration/MigrationRuleListener.java    |  2 +-
 ...rationRule.java => InterfaceMigrationRule.java} | 33 +++++-------
 .../client/migration/model/MigrationRule.java      | 58 ++++++++++++++++++++++
 8 files changed, 112 insertions(+), 28 deletions(-)

diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java
index 2936688..a3f7c02 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/DefaultMigrationAddressComparator.java
@@ -20,6 +20,8 @@ import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.registry.client.migration.model.MigrationRule;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.cluster.ClusterInvoker;
 
@@ -32,7 +34,7 @@ public class DefaultMigrationAddressComparator implements MigrationAddressCompar
     private static final float DEFAULT_THREAD = 0.8f;
 
     @Override
-    public <T> boolean shouldMigrate(ClusterInvoker<T> serviceDiscoveryInvoker, ClusterInvoker<T> invoker) {
+    public <T> boolean shouldMigrate(ClusterInvoker<T> serviceDiscoveryInvoker, ClusterInvoker<T> invoker, MigrationRule rule) {
         if (!serviceDiscoveryInvoker.isAvailable()) {
             logger.info("No instance address available, will not migrate.");
             return false;
@@ -48,7 +50,8 @@ public class DefaultMigrationAddressComparator implements MigrationAddressCompar
         int newAddressSize = CollectionUtils.isNotEmpty(invokers1) ? invokers1.size() : 0;
         int oldAddressSize = CollectionUtils.isNotEmpty(invokers2) ? invokers2.size() : 0;
 
-        String rawThreshold = ConfigurationUtils.getDynamicProperty(MIGRATION_THRESHOLD, DEFAULT_THRESHOLD_STRING);
+        String rawThreshold = rule.getThreshold(invoker.getUrl().getServiceKey());
+        rawThreshold = StringUtils.isNotEmpty(rawThreshold) ? rawThreshold : ConfigurationUtils.getDynamicProperty(MIGRATION_THRESHOLD, DEFAULT_THRESHOLD_STRING);
         float threshold;
         try {
             threshold = Float.parseFloat(rawThreshold);
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationAddressComparator.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationAddressComparator.java
index 2be527b..57906ca 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationAddressComparator.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationAddressComparator.java
@@ -17,9 +17,10 @@
 package org.apache.dubbo.registry.client.migration;
 
 import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.registry.client.migration.model.MigrationRule;
 import org.apache.dubbo.rpc.cluster.ClusterInvoker;
 
 @SPI
 public interface MigrationAddressComparator {
-    <T> boolean shouldMigrate(ClusterInvoker<T> serviceDiscoveryInvoker, ClusterInvoker<T> invoker);
+    <T> boolean shouldMigrate(ClusterInvoker<T> serviceDiscoveryInvoker, ClusterInvoker<T> invoker, MigrationRule rule);
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationClusterInvoker.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationClusterInvoker.java
index fcb68f3..d1dca9d 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationClusterInvoker.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationClusterInvoker.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.registry.client.migration;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.client.migration.model.MigrationRule;
 import org.apache.dubbo.registry.client.migration.model.MigrationStep;
 import org.apache.dubbo.rpc.cluster.ClusterInvoker;
 
@@ -33,6 +34,10 @@ public interface MigrationClusterInvoker<T> extends ClusterInvoker<T> {
 
     void setMigrationStep(MigrationStep step);
 
+    MigrationRule getMigrationRule();
+
+    void setMigrationRule(MigrationRule rule);
+
     boolean invokersChanged();
 
     void fallbackToInterfaceInvoker();
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java
index 20dc035..73e2d28 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationInvoker.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.client.migration.model.MigrationRule;
 import org.apache.dubbo.registry.client.migration.model.MigrationStep;
 import org.apache.dubbo.registry.integration.DynamicDirectory;
 import org.apache.dubbo.registry.integration.RegistryProtocol;
@@ -52,6 +53,7 @@ public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
     private volatile ClusterInvoker<T> serviceDiscoveryInvoker;
     private volatile ClusterInvoker<T> currentAvailableInvoker;
     private volatile MigrationStep step;
+    private volatile MigrationRule rule;
 
     public MigrationInvoker(RegistryProtocol registryProtocol,
                             Cluster cluster,
@@ -249,6 +251,16 @@ public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
     }
 
     @Override
+    public MigrationRule getMigrationRule() {
+        return rule;
+    }
+
+    @Override
+    public void setMigrationRule(MigrationRule rule) {
+        this.rule = rule;
+    }
+
+    @Override
     public boolean invokersChanged() {
         return invokersChanged;
     }
@@ -262,7 +274,7 @@ public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
         }
 
         Set<MigrationAddressComparator> detectors = ExtensionLoader.getExtensionLoader(MigrationAddressComparator.class).getSupportedExtensionInstances();
-        if (detectors != null && detectors.stream().allMatch(migrationDetector -> migrationDetector.shouldMigrate(serviceDiscoveryInvoker, invoker))) {
+        if (detectors != null && detectors.stream().allMatch(migrationDetector -> migrationDetector.shouldMigrate(serviceDiscoveryInvoker, invoker, rule))) {
             discardInterfaceInvokerAddress(invoker);
         } else {
             discardServiceDiscoveryInvokerAddress(serviceDiscoveryInvoker);
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java
index d22bd6b..e2d3054 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleHandler.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.registry.client.migration;
 
+import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.common.logger.Logger;
@@ -33,9 +34,12 @@ public class MigrationRuleHandler<T> {
 
     private MigrationClusterInvoker<T> migrationInvoker;
     private MigrationStep currentStep;
+    private MigrationRule rule;
+    private URL consumerURL;
 
-    public MigrationRuleHandler(MigrationClusterInvoker<T> invoker) {
+    public MigrationRuleHandler(MigrationClusterInvoker<T> invoker, URL url) {
         this.migrationInvoker = invoker;
+        this.consumerURL = url;
     }
 
     public void doMigrate(String rawRule) {
@@ -48,8 +52,13 @@ public class MigrationRuleHandler<T> {
         } else if (INIT.equals(rawRule)) {
             step = Enum.valueOf(MigrationStep.class, ConfigurationUtils.getDynamicProperty(DUBBO_SERVICEDISCOVERY_MIGRATION, step.name()));
         } else {
-            MigrationRule rule = MigrationRule.parse(rawRule);
-            step = rule.getStep();
+            try {
+                rule = MigrationRule.parse(rawRule);
+                setMigrationRule(rule);
+                step = rule.getStep(consumerURL.getServiceKey());
+            } catch (Exception e) {
+                logger.error("Parse migration rule error, will use default step " + step, e);
+            }
         }
 
         if (currentStep == null || currentStep != step) {
@@ -70,6 +79,9 @@ public class MigrationRuleHandler<T> {
 
     public void setCurrentStep(MigrationStep currentStep) {
         this.currentStep = currentStep;
+    }
+
+    public void setMigrationRule(MigrationRule rule) {
         this.migrationInvoker.setMigrationStep(currentStep);
     }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java
index 2c3a904..0eeb520 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/MigrationRuleListener.java
@@ -85,7 +85,7 @@ 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);
+        MigrationRuleHandler<?> migrationListener = new MigrationRuleHandler<>(migrationInvoker, url);
         listeners.add(migrationListener);
 
         migrationListener.doMigrate(rawRule);
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/InterfaceMigrationRule.java
similarity index 63%
copy from dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
copy to dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/InterfaceMigrationRule.java
index b0f84b1..658248b 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/InterfaceMigrationRule.java
@@ -16,26 +16,17 @@
  */
 package org.apache.dubbo.registry.client.migration.model;
 
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-
-/**
- * # key = demo-consumer.migration
- * # group = DUBBO_SERVICEDISCOVERY_MIGRATION
- * # content
- * key: demo-consumer
- * step: APPLICATION_FIRST
- */
-public class MigrationRule {
-    private String key;
+public class InterfaceMigrationRule {
+    private String serviceKey;
     private MigrationStep step;
+    private String threshold;
 
-    public String getKey() {
-        return key;
+    public String getServiceKey() {
+        return serviceKey;
     }
 
-    public void setKey(String key) {
-        this.key = key;
+    public void setServiceKey(String serviceKey) {
+        this.serviceKey = serviceKey;
     }
 
     public MigrationStep getStep() {
@@ -46,9 +37,11 @@ public class MigrationRule {
         this.step = step;
     }
 
-    public static MigrationRule parse(String rawRule) {
-        Constructor constructor = new Constructor(MigrationRule.class);
-        Yaml yaml = new Yaml(constructor);
-        return yaml.load(rawRule);
+    public String getThreshold() {
+        return threshold;
+    }
+
+    public void setThreshold(String threshold) {
+        this.threshold = threshold;
     }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
index b0f84b1..a0aecf9 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
@@ -19,16 +19,31 @@ package org.apache.dubbo.registry.client.migration.model;
 import org.yaml.snakeyaml.Yaml;
 import org.yaml.snakeyaml.constructor.Constructor;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * # key = demo-consumer.migration
  * # group = DUBBO_SERVICEDISCOVERY_MIGRATION
  * # content
  * key: demo-consumer
  * step: APPLICATION_FIRST
+ * threshold: 1.0
+ * interfaces:
+ * - serviceKey: DemoService:1.0.0
+ * threshold: 1.0
+ * step: APPLICATION_FIRST
+ * - serviceKey: GreetingService:1.0.0
+ * step: FORCE_APPLICATION
  */
 public class MigrationRule {
     private String key;
     private MigrationStep step;
+    private String threshold;
+    private List<InterfaceMigrationRule> interfaces;
+
+    private transient Map<String, InterfaceMigrationRule> interfaceRules;
 
     public String getKey() {
         return key;
@@ -38,14 +53,57 @@ public class MigrationRule {
         this.key = key;
     }
 
+    public MigrationStep getStep(String serviceKey) {
+        InterfaceMigrationRule rule = interfaceRules.get(serviceKey);
+        if (rule != null) {
+            return rule.getStep() == null ? step : rule.getStep();
+        }
+        return step;
+    }
+
+    public InterfaceMigrationRule getInterfaceRule(String serviceKey) {
+        return interfaceRules.get(serviceKey);
+    }
+
     public MigrationStep getStep() {
         return step;
     }
 
+    public String getThreshold(String serviceKey) {
+        InterfaceMigrationRule rule = interfaceRules.get(serviceKey);
+        if (rule != null) {
+            return rule.getThreshold() == null ? threshold : rule.getThreshold();
+        }
+        return threshold;
+    }
+
+    public String getThreshold() {
+        return threshold;
+    }
+
+    public void setThreshold(String threshold) {
+        this.threshold = threshold;
+    }
+
     public void setStep(MigrationStep step) {
         this.step = step;
     }
 
+    public List<InterfaceMigrationRule> getInterfaces() {
+        return interfaces;
+    }
+
+
+    public void setInterfaces(List<InterfaceMigrationRule> interfaces) {
+        this.interfaces = interfaces;
+        if (interfaces != null) {
+            this.interfaceRules = new HashMap<>();
+            interfaces.forEach(rule -> {
+                interfaceRules.put(rule.getServiceKey(), rule);
+            });
+        }
+    }
+
     public static MigrationRule parse(String rawRule) {
         Constructor constructor = new Constructor(MigrationRule.class);
         Yaml yaml = new Yaml(constructor);