fantiq commented on PR #15639: URL: https://github.com/apache/dubbo/pull/15639#issuecomment-3266671313
In addition to adding the isAvailable method, the following sections describe some logical adjustments to support the failure retry strategy. ## service-name-mapping ### consumer The `service-name-mapping` listener support local cache, no need to retry. ### provider https://github.com/apache/dubbo/blob/d45ce97c489bc096102533b7a87ef80e3184d2e9/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java#L426-L469 If `serviceNameMapping.map(url)` return false, it will retry by `FrameworkExecutorRepository` schedule executor. https://github.com/apache/dubbo/blob/d45ce97c489bc096102533b7a87ef80e3184d2e9/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java#L94-L156 But the value of variable `result` is determined by the report result of the last metadata-report client. Maybe there shoule retry every report failed metadata-report client. In order to support failed retries, I have made the following changes: https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java#L144-L171 add the `registerServiceAppMapping` method, calculate whether the appName is exists in the metadata-center, if it doesn't exists report it. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java#L142 define the abstract method `boolean doMap(MetadataReport metadataReport, URL url)` to execute the reporting logic of appName. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java#L62-L92 There implement the `doMap` method, retained the original failed retry logic, https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java#L114-L139 The `boolean map(URL url)` method move to `AbstractServiceNameMapping`, it will add the report failed metadat-report client and service to the retry task. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportRetryTask.java#L42-L57 Add an new class `MetadataReportRetryTask` (some unit test waiting for add), it will schedule by fixed rate, retry task use `FrameworkExecutorRepository` thread pool. It will replace the original code https://github.com/apache/dubbo/blob/d45ce97c489bc096102533b7a87ef80e3184d2e9/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java#L462 ## service-discovery ### consumer https://github.com/apache/dubbo/blob/d45ce97c489bc096102533b7a87ef80e3184d2e9/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java#L356 When consumer subscribe service, it will get service instance by service-discovery, if the service-discovery connection is unavailable, there will throw an exception. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java#L387-L394 If `consumer.check = false`, support for failed retry is required, there add retry logic by method `FailbackRegistry.addFailedSubscribed()`. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/FailbackRegistry.java#L138-L154 Due to current retry tasks calling the `doSubscribe` method, service-discovery subscribe process need only call `subscribeURLs` method no need to call from `doSubscribe`, so there add an new method `void addFailedSubscribed(URL url, NotifyListener listener, ThrowableAction handler)` to support customize retry processing logic. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/retry/FailedSubscribedTask.java#L30-L49 add new field `ThrowableAction handler` for `FailedSubscribedTask`, `handler` is the customize function. If `handler` is `null`, the retry will call `doSubscribe` or else customize functon will called. ### provider https://github.com/apache/dubbo/blob/d45ce97c489bc096102533b7a87ef80e3184d2e9/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java#L379-L388 In the method 'calOrupdateInstanceRevision', it calculates whether metadata has been updated. But it will return `true` once, This results in the inability to retry when metadata reporting fails or when serviceInstance register or update fails. The following changes have been made to support failed retries: https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java#L70 If the filed `serviceInstance` is `null`, this means that the `serviceInstance` need to be initialized and registered to registry-center. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java#L82 Add field `reportedRevision` in class `MetadataInfo`, it records the revision of metadata that has successfully reported to metadata-center. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java#L404-L427 On the line 405 of method `reportMetadata`, preventing duplicate reporting by comparing the value of `MetadataInfo.revision` and `MetadataInfo.reportedRevision`. On the line 418 of method `reportMetadata`, After the metadata is successfully reported, Update the value of 'MetadataInfo.reportaedRevision' to the successfully reported revision. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java#L397-L402 Refactored the logic of the 'calOrupdateInstanceRevision' method. Enable it to support retry after failer. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java#L170-L178 https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java#L212-L217 https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java#L132-L137 https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-zookeeper/src/main/java/org/apache/dubbo/registry/zookeeper/ZookeeperServiceDiscovery.java#L135-L138 When execute register() or update() method, it will clone a new ServiceInstance Object from field `serviceInstance` and named `newServiceInstance`, Then assign the revision value of the successfully reported metadata to `newServiceInstance.metadata[dubbo.metadata.revision]`. Once the method register() or update() is execute successfully, `newServiceInstance` will assign to field `serviceInstance`. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java#L365-L376 There are some special cases. if the scene here is re-register, it is the same as `register()`. if the scene is unregister, there will assign `0` to `MetadataInfo.reportedRevision`, to prevent duplicate execution of update logic in `calOrUpdateInstanceRevision` method. https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java#L204-L219 https://github.com/apache/dubbo/blob/eb728417846025108aa61fb7ae777018b9ea96af/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java#L259-L279 In the `updateInstance` or `deregisterInstance` method, place the logic to remove the local `InstanceInfo` object after the successful operation on the registry-center. (To facilitate code review, I have made as few changes as possible to the original code here, and optimizations can be made later.) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@dubbo.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@dubbo.apache.org For additional commands, e-mail: notifications-h...@dubbo.apache.org