diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b4934a4e..f24b13553 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,3 +6,4 @@ - [feat:optimize config server address](https://github.com/Tencent/spring-cloud-tencent/pull/150) - [feat:refactor loadbalancer module as a basic module for router and circuit breaker.](https://github.com/Tencent/spring-cloud-tencent/pull/166) - [feat: override recover router config](https://github.com/Tencent/spring-cloud-tencent/pull/167) +- [fix:fix routes of gateway doesn't refresh bug.](https://github.com/Tencent/spring-cloud-tencent/pull/168) 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 a52a6dd4b..67690ef24 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 37b0ad45f..77483b360 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; @@ -218,6 +223,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='" 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 951c99f76..86e829080 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; @@ -114,6 +118,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 000000000..d52628f28 --- /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 83f8967f0..987413ed0 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 @@ -65,9 +65,11 @@ public class PolarisServiceRegistry implements ServiceRegistry { private final ScheduledExecutorService heartbeatExecutor; + private final PolarisServiceChangeListener polarisServiceChangeListener; + public PolarisServiceRegistry(PolarisDiscoveryProperties polarisDiscoveryProperties, PolarisDiscoveryHandler polarisDiscoveryHandler, - MetadataLocalProperties metadataLocalProperties) { + MetadataLocalProperties metadataLocalProperties, PolarisServiceChangeListener polarisServiceChangeListener) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; this.polarisDiscoveryHandler = polarisDiscoveryHandler; this.metadataLocalProperties = metadataLocalProperties; @@ -79,6 +81,8 @@ public class PolarisServiceRegistry implements ServiceRegistry { else { this.heartbeatExecutor = null; } + + this.polarisServiceChangeListener = polarisServiceChangeListener; } @Override @@ -116,6 +120,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...{},", 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 3ec88d554..72ac86162 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; @@ -51,11 +52,10 @@ public class PolarisServiceRegistryAutoConfiguration { @Bean public PolarisServiceRegistry polarisServiceRegistry( - PolarisDiscoveryProperties polarisDiscoveryProperties, - PolarisDiscoveryHandler polarisDiscoveryHandler, - MetadataLocalProperties metadataLocalProperties) { + PolarisDiscoveryProperties polarisDiscoveryProperties, PolarisDiscoveryHandler polarisDiscoveryHandler, + MetadataLocalProperties metadataLocalProperties, PolarisServiceChangeListener polarisServiceChangeListener) { return new PolarisServiceRegistry(polarisDiscoveryProperties, - polarisDiscoveryHandler, metadataLocalProperties); + polarisDiscoveryHandler, metadataLocalProperties, polarisServiceChangeListener); } @Bean @@ -77,4 +77,9 @@ public class PolarisServiceRegistryAutoConfiguration { 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 eb160ae93..7743b5f6c 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 2e036909c..467a53d22 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 b820b2ee6..4d455861c 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 @@ -19,15 +19,46 @@ spring: 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 5993108df..ace6b329d 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