From 629859cbc87e1ba193a254d94e67edae77fdc1e7 Mon Sep 17 00:00:00 2001 From: SkyeBeFreeman <928016560@qq.com> Date: Wed, 11 May 2022 11:53:54 +0800 Subject: [PATCH] fix:fix routes of gateway doesn't refresh bug. --- CHANGELOG.md | 1 + pom.xml | 8 +++ .../polaris/DiscoveryConfigModifier.java | 9 +++ .../polaris/PolarisDiscoveryProperties.java | 13 ++++ .../discovery/PolarisDiscoveryHandler.java | 8 +++ .../PolarisServiceChangeListener.java | 62 +++++++++++++++++++ .../registry/PolarisServiceRegistry.java | 11 +++- ...larisServiceRegistryAutoConfiguration.java | 14 ++++- ...itional-spring-configuration-metadata.json | 6 ++ .../ratelimit/utils/RateLimitUtils.java | 4 +- .../src/main/resources/bootstrap.yml | 49 ++++++++++++--- src/checkstyle/checkstyle-suppressions.xml | 2 + 12 files changed, 172 insertions(+), 15 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceChangeListener.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc61c9e..7db7eb18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,3 +6,4 @@ - [feat:optimize config server address.](https://github.com/Tencent/spring-cloud-tencent/pull/149) - [feat: override recover router config](https://github.com/Tencent/spring-cloud-tencent/pull/159) - [feat:refactor loadbalancer module as a basic module for router and circuit breaker.](https://github.com/Tencent/spring-cloud-tencent/pull/155) +- [fix:fix routes of gateway doesn't refresh bug.](https://github.com/Tencent/spring-cloud-tencent/pull/163) diff --git a/pom.xml b/pom.xml index 7bd47278..d99a686c 100644 --- a/pom.xml +++ b/pom.xml @@ -61,6 +61,14 @@ https://github.com/SkyeBeFreeman/ + + lepdou + lepdou + lepdou@126.com + Tencent + https://github.com/lepdou + + Andrew Shan samshan08@126.com diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java index a52a6dd4..67690ef2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryConfigModifier.java @@ -24,6 +24,8 @@ import com.tencent.polaris.api.config.consumer.ServiceRouterConfig; import com.tencent.polaris.factory.config.ConfigurationImpl; import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig; +import org.springframework.beans.factory.annotation.Autowired; + /** * Spring Cloud Tencent config Override polaris config. * @@ -31,6 +33,9 @@ import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig; */ public class DiscoveryConfigModifier implements PolarisConfigModifier { + @Autowired + private PolarisDiscoveryProperties polarisDiscoveryProperties; + @Override public void modify(ConfigurationImpl configuration) { // Set excludeCircuitBreakInstances to false @@ -41,6 +46,10 @@ public class DiscoveryConfigModifier implements PolarisConfigModifier { // Update modified config to source properties configuration.getConsumer().getServiceRouter() .setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig); + + // Set ServiceRefreshInterval + configuration.getConsumer().getLocalCache() + .setServiceListRefreshInterval(polarisDiscoveryProperties.getServiceListRefreshInterval()); } @Override diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java index dc3f3831..24ef50e8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java @@ -105,6 +105,11 @@ public class PolarisDiscoveryProperties { @Value("${spring.cloud.polaris.discovery.health-check-url:}") private String healthCheckUrl; + /** + * Millis interval of refresh of service info list. Default: 60000. + */ + private Long serviceListRefreshInterval = 60000L; + @Autowired private Environment environment; @@ -215,6 +220,14 @@ public class PolarisDiscoveryProperties { this.healthCheckUrl = healthCheckUrl; } + public Long getServiceListRefreshInterval() { + return serviceListRefreshInterval; + } + + public void setServiceListRefreshInterval(Long serviceListRefreshInterval) { + this.serviceListRefreshInterval = serviceListRefreshInterval; + } + @Override public String toString() { return "PolarisProperties{" + "token='" + token + '\'' + ", namespace='" + namespace + '\'' + ", service='" diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java index 0ea9bb97..53190bf2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryHandler.java @@ -33,6 +33,7 @@ import com.tencent.polaris.api.rpc.GetInstancesRequest; import com.tencent.polaris.api.rpc.GetServicesRequest; import com.tencent.polaris.api.rpc.InstancesResponse; import com.tencent.polaris.api.rpc.ServicesResponse; +import com.tencent.polaris.client.api.SDKContext; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -52,6 +53,9 @@ public class PolarisDiscoveryHandler { @Autowired private ProviderAPI providerAPI; + @Autowired + private SDKContext sdkContext; + @Autowired private ConsumerAPI polarisConsumer; @@ -112,6 +116,10 @@ public class PolarisDiscoveryHandler { return providerAPI; } + public SDKContext getSdkContext() { + return sdkContext; + } + /** * Return all service for given namespace. * @return service list diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceChangeListener.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceChangeListener.java new file mode 100644 index 00000000..d52628f2 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceChangeListener.java @@ -0,0 +1,62 @@ +package com.tencent.cloud.polaris.registry; + +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +import com.google.common.collect.Sets; +import com.tencent.polaris.api.plugin.registry.AbstractResourceEventListener; +import com.tencent.polaris.api.pojo.RegistryCacheValue; +import com.tencent.polaris.api.pojo.ServiceEventKey; +import com.tencent.polaris.client.pojo.ServicesByProto; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.discovery.event.HeartbeatEvent; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; + +/** + * Change listener of Polaris service info. + * + * @author Haotian Zhang + */ +public class PolarisServiceChangeListener extends AbstractResourceEventListener implements ApplicationEventPublisherAware { + + private static final Logger LOG = LoggerFactory.getLogger(PolarisServiceChangeListener.class); + + private static final AtomicInteger INDEX = new AtomicInteger(0); + + private ApplicationEventPublisher publisher; + + @Override + public void onResourceUpdated(ServiceEventKey svcEventKey, RegistryCacheValue oldValue, + RegistryCacheValue newValue) { + if (newValue.getEventType() != ServiceEventKey.EventType.SERVICE) { + return; + } + if (oldValue instanceof ServicesByProto && newValue instanceof ServicesByProto) { + LOG.debug("receive service={} change event", svcEventKey); + Set oldServiceInfoSet = ((ServicesByProto) oldValue).getServices().stream() + .map(i -> i.getNamespace() + "::" + i.getService()).collect(Collectors.toSet()); + Set newServiceInfoSet = ((ServicesByProto) newValue).getServices().stream() + .map(i -> i.getNamespace() + "::" + i.getService()).collect(Collectors.toSet()); + + Sets.SetView addServiceInfoSetView = Sets.difference(newServiceInfoSet, oldServiceInfoSet); + Sets.SetView deleteServiceInfoSetView = Sets.difference(oldServiceInfoSet, newServiceInfoSet); + + if (addServiceInfoSetView.isEmpty() && deleteServiceInfoSetView.isEmpty()) { + return; + } + LOG.info("Service info is update. Add service of {}. Delete service of {}", addServiceInfoSetView, deleteServiceInfoSetView); + + // Trigger reload of gateway route cache. + this.publisher.publishEvent(new HeartbeatEvent(this, INDEX.getAndIncrement())); + } + } + + @Override + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + this.publisher = applicationEventPublisher; + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index a903f780..b2f5e7d7 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -63,8 +63,11 @@ public class PolarisServiceRegistry implements ServiceRegistry { private final ScheduledExecutorService heartbeatExecutor; + private final PolarisServiceChangeListener polarisServiceChangeListener; + public PolarisServiceRegistry(PolarisDiscoveryProperties polarisDiscoveryProperties, - PolarisDiscoveryHandler polarisDiscoveryHandler, MetadataLocalProperties metadataLocalProperties) { + PolarisDiscoveryHandler polarisDiscoveryHandler, + MetadataLocalProperties metadataLocalProperties, PolarisServiceChangeListener polarisServiceChangeListener) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; this.polarisDiscoveryHandler = polarisDiscoveryHandler; this.metadataLocalProperties = metadataLocalProperties; @@ -76,6 +79,8 @@ public class PolarisServiceRegistry implements ServiceRegistry { else { this.heartbeatExecutor = null; } + + this.polarisServiceChangeListener = polarisServiceChangeListener; } @Override @@ -112,6 +117,10 @@ public class PolarisServiceRegistry implements ServiceRegistry { // Start the heartbeat thread after the registration is successful. heartbeat(heartbeatRequest); } + + // Register service change listener + polarisDiscoveryHandler.getSdkContext().getExtensions().getLocalRegistry() + .registerResourceListener(polarisServiceChangeListener); } catch (Exception e) { log.error("polaris registry, {} register failed...{},", registration.getServiceId(), registration, e); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java index 64ac2e81..071947fe 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java @@ -27,6 +27,7 @@ import com.tencent.polaris.client.api.SDKContext; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; @@ -49,9 +50,11 @@ import org.springframework.context.annotation.Configuration; public class PolarisServiceRegistryAutoConfiguration { @Bean - public PolarisServiceRegistry polarisServiceRegistry(PolarisDiscoveryProperties polarisDiscoveryProperties, - PolarisDiscoveryHandler polarisDiscoveryHandler, MetadataLocalProperties metadataLocalProperties) { - return new PolarisServiceRegistry(polarisDiscoveryProperties, polarisDiscoveryHandler, metadataLocalProperties); + public PolarisServiceRegistry polarisServiceRegistry( + PolarisDiscoveryProperties polarisDiscoveryProperties, PolarisDiscoveryHandler polarisDiscoveryHandler, + MetadataLocalProperties metadataLocalProperties, PolarisServiceChangeListener polarisServiceChangeListener) { + return new PolarisServiceRegistry(polarisDiscoveryProperties, + polarisDiscoveryHandler, metadataLocalProperties, polarisServiceChangeListener); } @Bean @@ -69,4 +72,9 @@ public class PolarisServiceRegistryAutoConfiguration { return new PolarisAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration); } + @Bean + @ConditionalOnMissingBean + public PolarisServiceChangeListener polarisServiceChangeListener() { + return new PolarisServiceChangeListener(); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json index eb160ae9..7743b5f6 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -59,6 +59,12 @@ "type": "java.lang.Integer", "defaultValue": 100, "description": "the weight of polaris instance , use to load-balance." + }, + { + "name": "spring.cloud.polaris.discovery.service-list-refresh-interval", + "type": "java.lang.Long", + "defaultValue": 60000, + "description": "Millis interval of refresh of service info list. Default: 60000." } ] } diff --git a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java index 2e036909..467a53d2 100644 --- a/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java +++ b/spring-cloud-starter-tencent-polaris-ratelimit/src/main/java/com/tencent/cloud/polaris/ratelimit/utils/RateLimitUtils.java @@ -21,7 +21,6 @@ package com.tencent.cloud.polaris.ratelimit.utils; import com.tencent.cloud.common.util.ResourceFileUtils; import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant; -import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,8 +33,7 @@ import org.springframework.util.StringUtils; */ public final class RateLimitUtils { - private static final Logger LOG = LoggerFactory - .getLogger(QuotaCheckServletFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(RateLimitUtils.class); private RateLimitUtils() { diff --git a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml index b820b2ee..8acb66cb 100644 --- a/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service/src/main/resources/bootstrap.yml @@ -15,19 +15,52 @@ spring: address: grpc://127.0.0.1:8091 namespace: default enabled: true + discovery: + service-list-refresh-interval: 1000 gateway: discovery: locator: enabled: true - lowerCaseServiceId: false - routes: - - id: GatewayCalleeService - uri: lb://GatewayCalleeService - predicates: - - Path=/GatewayCalleeService/** - filters: - - StripPrefix=1 + 'predicates[0]': + name: Path + args: + patterns: '''/'' + serviceId + ''/**''' + 'filters[0]': + name: RewritePath + args: + regexp: '''/'' + serviceId + ''/(?.*)''' + replacement: '''/$\{remaining}''' + 'filters[1]': + name: Retry + args: + retries: 3 + exceptions: + '[0]': '''java.net.ConnectException''' + '[1]': '''java.io.IOException''' + statuses: + '[0]': '''BAD_GATEWAY''' + '[1]': '''SERVICE_UNAVAILABLE''' + series: + '[0]': '''CLIENT_ERROR''' + methods: + '[0]': '''GET''' + '[1]': '''POST''' + '[2]': '''PUT''' + '[3]': '''DELETE''' + backoff: + firstBackoff: '''100ms''' + maxBackoff: '''500ms''' + factor: 2 + basedOnPreviousValue: false +# routes: +# - id: GatewayCalleeService +# uri: lb://GatewayCalleeService +# predicates: +# - Path=/GatewayCalleeService/** +# filters: +# - StripPrefix=1 logging: level: org.springframework.cloud.gateway: info + com.tencent.cloud.polaris: debug diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index 5993108d..ace6b329 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -4,4 +4,6 @@ "https://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> + + \ No newline at end of file