fix:fix routes of gateway doesn't refresh bug.

pull/163/head
SkyeBeFreeman 3 years ago
parent 8f7573b403
commit 629859cbc8

@ -6,3 +6,4 @@
- [feat:optimize config server address.](https://github.com/Tencent/spring-cloud-tencent/pull/149) - [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: 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) - [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)

@ -61,6 +61,14 @@
<url>https://github.com/SkyeBeFreeman/</url> <url>https://github.com/SkyeBeFreeman/</url>
</developer> </developer>
<developer>
<id>lepdou</id>
<name>lepdou</name>
<email>lepdou@126.com</email>
<organization>Tencent</organization>
<url>https://github.com/lepdou</url>
</developer>
<developer> <developer>
<name>Andrew Shan</name> <name>Andrew Shan</name>
<email>samshan08@126.com</email> <email>samshan08@126.com</email>

@ -24,6 +24,8 @@ import com.tencent.polaris.api.config.consumer.ServiceRouterConfig;
import com.tencent.polaris.factory.config.ConfigurationImpl; import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig; import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig;
import org.springframework.beans.factory.annotation.Autowired;
/** /**
* Spring Cloud Tencent config Override polaris config. * Spring Cloud Tencent config Override polaris config.
* *
@ -31,6 +33,9 @@ import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig;
*/ */
public class DiscoveryConfigModifier implements PolarisConfigModifier { public class DiscoveryConfigModifier implements PolarisConfigModifier {
@Autowired
private PolarisDiscoveryProperties polarisDiscoveryProperties;
@Override @Override
public void modify(ConfigurationImpl configuration) { public void modify(ConfigurationImpl configuration) {
// Set excludeCircuitBreakInstances to false // Set excludeCircuitBreakInstances to false
@ -41,6 +46,10 @@ public class DiscoveryConfigModifier implements PolarisConfigModifier {
// Update modified config to source properties // Update modified config to source properties
configuration.getConsumer().getServiceRouter() configuration.getConsumer().getServiceRouter()
.setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig); .setPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, recoverRouterConfig);
// Set ServiceRefreshInterval
configuration.getConsumer().getLocalCache()
.setServiceListRefreshInterval(polarisDiscoveryProperties.getServiceListRefreshInterval());
} }
@Override @Override

@ -105,6 +105,11 @@ public class PolarisDiscoveryProperties {
@Value("${spring.cloud.polaris.discovery.health-check-url:}") @Value("${spring.cloud.polaris.discovery.health-check-url:}")
private String healthCheckUrl; private String healthCheckUrl;
/**
* Millis interval of refresh of service info list. Default: 60000.
*/
private Long serviceListRefreshInterval = 60000L;
@Autowired @Autowired
private Environment environment; private Environment environment;
@ -215,6 +220,14 @@ public class PolarisDiscoveryProperties {
this.healthCheckUrl = healthCheckUrl; this.healthCheckUrl = healthCheckUrl;
} }
public Long getServiceListRefreshInterval() {
return serviceListRefreshInterval;
}
public void setServiceListRefreshInterval(Long serviceListRefreshInterval) {
this.serviceListRefreshInterval = serviceListRefreshInterval;
}
@Override @Override
public String toString() { public String toString() {
return "PolarisProperties{" + "token='" + token + '\'' + ", namespace='" + namespace + '\'' + ", service='" return "PolarisProperties{" + "token='" + token + '\'' + ", namespace='" + namespace + '\'' + ", service='"

@ -33,6 +33,7 @@ import com.tencent.polaris.api.rpc.GetInstancesRequest;
import com.tencent.polaris.api.rpc.GetServicesRequest; import com.tencent.polaris.api.rpc.GetServicesRequest;
import com.tencent.polaris.api.rpc.InstancesResponse; import com.tencent.polaris.api.rpc.InstancesResponse;
import com.tencent.polaris.api.rpc.ServicesResponse; import com.tencent.polaris.api.rpc.ServicesResponse;
import com.tencent.polaris.client.api.SDKContext;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -52,6 +53,9 @@ public class PolarisDiscoveryHandler {
@Autowired @Autowired
private ProviderAPI providerAPI; private ProviderAPI providerAPI;
@Autowired
private SDKContext sdkContext;
@Autowired @Autowired
private ConsumerAPI polarisConsumer; private ConsumerAPI polarisConsumer;
@ -112,6 +116,10 @@ public class PolarisDiscoveryHandler {
return providerAPI; return providerAPI;
} }
public SDKContext getSdkContext() {
return sdkContext;
}
/** /**
* Return all service for given namespace. * Return all service for given namespace.
* @return service list * @return service list

@ -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<String> oldServiceInfoSet = ((ServicesByProto) oldValue).getServices().stream()
.map(i -> i.getNamespace() + "::" + i.getService()).collect(Collectors.toSet());
Set<String> newServiceInfoSet = ((ServicesByProto) newValue).getServices().stream()
.map(i -> i.getNamespace() + "::" + i.getService()).collect(Collectors.toSet());
Sets.SetView<String> addServiceInfoSetView = Sets.difference(newServiceInfoSet, oldServiceInfoSet);
Sets.SetView<String> 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;
}
}

@ -63,8 +63,11 @@ public class PolarisServiceRegistry implements ServiceRegistry<Registration> {
private final ScheduledExecutorService heartbeatExecutor; private final ScheduledExecutorService heartbeatExecutor;
private final PolarisServiceChangeListener polarisServiceChangeListener;
public PolarisServiceRegistry(PolarisDiscoveryProperties polarisDiscoveryProperties, public PolarisServiceRegistry(PolarisDiscoveryProperties polarisDiscoveryProperties,
PolarisDiscoveryHandler polarisDiscoveryHandler, MetadataLocalProperties metadataLocalProperties) { PolarisDiscoveryHandler polarisDiscoveryHandler,
MetadataLocalProperties metadataLocalProperties, PolarisServiceChangeListener polarisServiceChangeListener) {
this.polarisDiscoveryProperties = polarisDiscoveryProperties; this.polarisDiscoveryProperties = polarisDiscoveryProperties;
this.polarisDiscoveryHandler = polarisDiscoveryHandler; this.polarisDiscoveryHandler = polarisDiscoveryHandler;
this.metadataLocalProperties = metadataLocalProperties; this.metadataLocalProperties = metadataLocalProperties;
@ -76,6 +79,8 @@ public class PolarisServiceRegistry implements ServiceRegistry<Registration> {
else { else {
this.heartbeatExecutor = null; this.heartbeatExecutor = null;
} }
this.polarisServiceChangeListener = polarisServiceChangeListener;
} }
@Override @Override
@ -112,6 +117,10 @@ public class PolarisServiceRegistry implements ServiceRegistry<Registration> {
// Start the heartbeat thread after the registration is successful. // Start the heartbeat thread after the registration is successful.
heartbeat(heartbeatRequest); heartbeat(heartbeatRequest);
} }
// Register service change listener
polarisDiscoveryHandler.getSdkContext().getExtensions().getLocalRegistry()
.registerResourceListener(polarisServiceChangeListener);
} }
catch (Exception e) { catch (Exception e) {
log.error("polaris registry, {} register failed...{},", registration.getServiceId(), registration, e); log.error("polaris registry, {} register failed...{},", registration.getServiceId(), registration, e);

@ -27,6 +27,7 @@ import com.tencent.polaris.client.api.SDKContext;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 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.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration;
@ -49,9 +50,11 @@ import org.springframework.context.annotation.Configuration;
public class PolarisServiceRegistryAutoConfiguration { public class PolarisServiceRegistryAutoConfiguration {
@Bean @Bean
public PolarisServiceRegistry polarisServiceRegistry(PolarisDiscoveryProperties polarisDiscoveryProperties, public PolarisServiceRegistry polarisServiceRegistry(
PolarisDiscoveryHandler polarisDiscoveryHandler, MetadataLocalProperties metadataLocalProperties) { PolarisDiscoveryProperties polarisDiscoveryProperties, PolarisDiscoveryHandler polarisDiscoveryHandler,
return new PolarisServiceRegistry(polarisDiscoveryProperties, polarisDiscoveryHandler, metadataLocalProperties); MetadataLocalProperties metadataLocalProperties, PolarisServiceChangeListener polarisServiceChangeListener) {
return new PolarisServiceRegistry(polarisDiscoveryProperties,
polarisDiscoveryHandler, metadataLocalProperties, polarisServiceChangeListener);
} }
@Bean @Bean
@ -69,4 +72,9 @@ public class PolarisServiceRegistryAutoConfiguration {
return new PolarisAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration); return new PolarisAutoServiceRegistration(registry, autoServiceRegistrationProperties, registration);
} }
@Bean
@ConditionalOnMissingBean
public PolarisServiceChangeListener polarisServiceChangeListener() {
return new PolarisServiceChangeListener();
}
} }

@ -59,6 +59,12 @@
"type": "java.lang.Integer", "type": "java.lang.Integer",
"defaultValue": 100, "defaultValue": 100,
"description": "the weight of polaris instance , use to load-balance." "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."
} }
] ]
} }

@ -21,7 +21,6 @@ package com.tencent.cloud.polaris.ratelimit.utils;
import com.tencent.cloud.common.util.ResourceFileUtils; import com.tencent.cloud.common.util.ResourceFileUtils;
import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties; import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant; import com.tencent.cloud.polaris.ratelimit.constant.RateLimitConstant;
import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -34,8 +33,7 @@ import org.springframework.util.StringUtils;
*/ */
public final class RateLimitUtils { public final class RateLimitUtils {
private static final Logger LOG = LoggerFactory private static final Logger LOG = LoggerFactory.getLogger(RateLimitUtils.class);
.getLogger(QuotaCheckServletFilter.class);
private RateLimitUtils() { private RateLimitUtils() {

@ -15,19 +15,52 @@ spring:
address: grpc://127.0.0.1:8091 address: grpc://127.0.0.1:8091
namespace: default namespace: default
enabled: true enabled: true
discovery:
service-list-refresh-interval: 1000
gateway: gateway:
discovery: discovery:
locator: locator:
enabled: true enabled: true
lowerCaseServiceId: false 'predicates[0]':
routes: name: Path
- id: GatewayCalleeService args:
uri: lb://GatewayCalleeService patterns: '''/'' + serviceId + ''/**'''
predicates: 'filters[0]':
- Path=/GatewayCalleeService/** name: RewritePath
filters: args:
- StripPrefix=1 regexp: '''/'' + serviceId + ''/(?<remaining>.*)'''
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: logging:
level: level:
org.springframework.cloud.gateway: info org.springframework.cloud.gateway: info
com.tencent.cloud.polaris: debug

@ -4,4 +4,6 @@
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> "https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions> <suppressions>
<suppress files=".*" checks="RegexpHeader"/> <suppress files=".*" checks="RegexpHeader"/>
<suppress files=".*" checks="HideUtilityClassConstructor"/>
<suppress files=".*" checks="IllegalImport"/>
</suppressions> </suppressions>
Loading…
Cancel
Save