Describe the bug
com.alibaba.nacos.client.naming.remote.gprc.redo.RedoScheduledTask
任务在反注册后马上注册时,对反注册任务 redo 会导致注册的实例失效。
Expected behavior
按照指令提交的时序保证最终一致性。
Actually behavior
redo 任务导致后提交的指令失效
How to Reproduce Steps to reproduce the behavior:
- 注册实例A
- 反注册实例A
- 注册实例B
实例 A 和 B 的 serviceName、ip、port 信息一致
在反注册实例 A 成功之前 com.alibaba.nacos.client.naming.remote.gprc.redo.RedoScheduledTask
扫描到对应任务执行 redo,但是在执行 redo 成功之前,主线程先注册了实例 B。最终 redo 任务的结果会覆盖注册实例 B 的信息。
Desktop (please complete the following information):
- OS: Ubuntu
- Version nacos-server 2.1.2, nacos-client 2.2.1-RC
- Module naming
- SDK original
Additional context
关键日志如下:
Provider:
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO metadata.MetadataInfo: [DUBBO] metadata revision changed: fcbd87cacae4b7833a71908ed11a73c9 -> 8baad1a3026019171d25f19813f857fd, app: App4, services: 3, dubbo version: 3.1.5-SNAPSHOT, current host: 172.20.0.6
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO client.AbstractServiceDiscovery: [DUBBO] Metadata of instance changed, updating instance with revision 8baad1a3026019171d25f19813f857fd., dubbo version: 3.1.5-SNAPSHOT, current host: 172.20.0.6
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO client.naming: [DEREGISTER-SERVICE] public deregistering service App4 with instance: Instance{instanceId='null', ip='172.20.0.6', port=20880, weight=1.0, healthy=true, enabled=true, ephemeral=true, clusterName='null', serviceName='App4', metadata={dubbo.endpoints=[{"port":20880,"protocol":"dubbo"}], dubbo.metadata-service.url-params={"connections":"1","version":"1.0.0","dubbo":"2.0.2","release":"3.1.5-SNAPSHOT","side":"provider","port":"20880","protocol":"dubbo"}, dubbo.metadata.revision=fcbd87cacae4b7833a71908ed11a73c9, dubbo.metadata.storage-type=local, timestamp=1673172310370}}
[08/01/23 10:05:45:045 UTC] DubboServerHandler-172.20.0.6:20880-thread-200 INFO client.naming: [DEREGISTER-SERVICE] public deregistering service providers:org.apache.dubbo.samples.api.DemoService3:: with instance: Instance{instanceId='null', ip='172.20.0.6', port=20880, weight=1.0, healthy=true, enabled=true, ephemeral=true, clusterName='DEFAULT', serviceName='null', metadata={}}
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO client.naming: [REGISTER-SERVICE] public registering service App4 with instance Instance{instanceId='null', ip='172.20.0.6', port=20880, weight=1.0, healthy=true, enabled=true, ephemeral=true, clusterName='null', serviceName='App4', metadata={dubbo.endpoints=[{"port":20880,"protocol":"dubbo"}], dubbo.metadata-service.url-params={"connections":"1","version":"1.0.0","dubbo":"2.0.2","release":"3.1.5-SNAPSHOT","side":"provider","port":"20880","protocol":"dubbo"}, dubbo.metadata.revision=8baad1a3026019171d25f19813f857fd, dubbo.metadata.storage-type=local, timestamp=1673172310370}}
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO metadata.MetadataInfo: [DUBBO] metadata revision changed: 8baad1a3026019171d25f19813f857fd -> 87d04346ba5686acfd02e97748b86896, app: App4, services: 2, dubbo version: 3.1.5-SNAPSHOT, current host: 172.20.0.6
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO client.AbstractServiceDiscovery: [DUBBO] Metadata of instance changed, updating instance with revision 87d04346ba5686acfd02e97748b86896., dubbo version: 3.1.5-SNAPSHOT, current host: 172.20.0.6
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO client.naming: [DEREGISTER-SERVICE] public deregistering service App4 with instance: Instance{instanceId='null', ip='172.20.0.6', port=20880, weight=1.0, healthy=true, enabled=true, ephemeral=true, clusterName='null', serviceName='App4', metadata={dubbo.endpoints=[{"port":20880,"protocol":"dubbo"}], dubbo.metadata-service.url-params={"connections":"1","version":"1.0.0","dubbo":"2.0.2","release":"3.1.5-SNAPSHOT","side":"provider","port":"20880","protocol":"dubbo"}, dubbo.metadata.revision=8baad1a3026019171d25f19813f857fd, dubbo.metadata.storage-type=local, timestamp=1673172310370}}
[08/01/23 10:05:45:045 UTC] com.alibaba.nacos.client.naming.grpc.redo.0 INFO client.naming: Redo instance operation UNREGISTER for isolated@@App4
[08/01/23 10:05:45:045 UTC] Dubbo-framework-shared-scheduler-thread-7 INFO client.naming: [REGISTER-SERVICE] public registering service App4 with instance Instance{instanceId='null', ip='172.20.0.6', port=20880, weight=1.0, healthy=true, enabled=true, ephemeral=true, clusterName='null', serviceName='App4', metadata={dubbo.endpoints=[{"port":20880,"protocol":"dubbo"}], dubbo.metadata-service.url-params={"connections":"1","version":"1.0.0","dubbo":"2.0.2","release":"3.1.5-SNAPSHOT","side":"provider","port":"20880","protocol":"dubbo"}, dubbo.metadata.revision=87d04346ba5686acfd02e97748b86896, dubbo.metadata.storage-type=local, timestamp=1673172310370}}
Consumer:
[08/01/23 10:05:46:046 UTC] nacos-grpc-client-executor-nacos-3 INFO client.naming: removed ips(1) service: isolated@@App4 -> [{"ip":"172.20.0.6","port":20880,"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"DEFAULT","serviceName":"isolated@@App4","metadata":{"dubbo.metadata-service.url-params":"{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.1.5-SNAPSHOT\",\"side\":\"provider\",\"port\":\"20880\",\"protocol\":\"dubbo\"}","dubbo.endpoints":"[{\"port\":20880,\"protocol\":\"dubbo\"}]","dubbo.metadata.revision":"fcbd87cacae4b7833a71908ed11a73c9","dubbo.metadata.storage-type":"local","timestamp":"1673172310370"},"instanceHeartBeatTimeOut":15000,"ipDeleteTimeout":30000,"instanceHeartBeatInterval":5000}]
[08/01/23 10:05:46:046 UTC] nacos-grpc-client-executor-nacos-3 INFO client.naming: current ips:(0) service: isolated@@App4 -> []
以下是测试反注册时使用的 instance metadata 不一致是否会成功反注册:
String serverAddr = System.getProperty("nacos.address", "mse-*******-p.nacos-ans.mse.aliyuncs.com");
Properties properties = new Properties();
properties.put("username", System.getProperty("username", "nacos"));
properties.put("password", System.getProperty("password", "nacos"));
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
NamingService namingService = NacosFactory.createNamingService(properties);
Instance instance1 = new Instance();
instance1.setServiceName("TestService");
instance1.setIp(NetUtils.getLocalHost());
instance1.setPort(20880);
Map<String, String> metadata = new HashMap<>();
metadata.put("key1", "val1");
metadata.put("key2", "val2");
metadata.put("key3", "val3");
instance1.setMetadata(metadata);
instance1.setEnabled(true);
instance1.setHealthy(true);
namingService.registerInstance("TestService", "isolated", instance1);
Instance instance2 = new Instance();
instance2.setServiceName("TestService");
instance2.setIp(NetUtils.getLocalHost());
instance2.setPort(20880);
Map<String, String> metadata2 = new HashMap<>();
metadata2.put("key1", "val1");
metadata2.put("key2", "val3");
metadata2.put("key3", "val3");
instance2.setMetadata(metadata2);
instance2.setEnabled(true);
instance2.setHealthy(true);
namingService.deregisterInstance("TestService", "isolated", instance2);
List<Instance> testService = namingService.getAllInstances("TestService");
System.out.println(testService);