fix:fix routes of gateway doesn't refresh bug. (#163)

fix routes of gateway doesn't refresh bug
pull/195/head
Haotian Zhang 3 years ago committed by GitHub
parent 88594487d0
commit b693c8d16f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,15 +1,9 @@
# Change Log # Change Log
--- ---
- [Bugfix: fix router bug and add router example](https://github.com/Tencent/spring-cloud-tencent/pull/109)
- [feat:add custom label resolver spi for rate limit](https://github.com/Tencent/spring-cloud-tencent/pull/107)
- [feat:fix discovery weight param not set to register request bug](https://github.com/Tencent/spring-cloud-tencent/pull/104)
- [Bugfix: fix causing cpu 100% when set ScheduledThreadPoolExecutor corePoolSize=0](https://github.com/Tencent/spring-cloud-tencent/pull/101)
- [Refactor: refactor transfer metadata](https://github.com/Tencent/spring-cloud-tencent/pull/113)
- [Bugfix: fix circuitbreaker http code greater than 400 as fail response bug](https://github.com/Tencent/spring-cloud-tencent/pull/118)
- [Feat: optimize router dependency](https://github.com/Tencent/spring-cloud-tencent/pull/115)
- [feat:add switch of polaris, discovery and register.](https://github.com/Tencent/spring-cloud-tencent/pull/129)
- [Feature: Support custom rate limit reject response info](https://github.com/Tencent/spring-cloud-tencent/pull/153) - [Feature: Support custom rate limit reject response info](https://github.com/Tencent/spring-cloud-tencent/pull/153)
- [Feature: Remove spring-javaformat-maven-plugin](https://github.com/Tencent/spring-cloud-tencent/pull/151) - [Feature: Remove spring-javaformat-maven-plugin](https://github.com/Tencent/spring-cloud-tencent/pull/151)
- [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)
- [fix:fix routes of gateway doesn't refresh bug.](https://github.com/Tencent/spring-cloud-tencent/pull/163)

@ -0,0 +1,11 @@
# Change Log
---
- [Bugfix: fix router bug and add router example](https://github.com/Tencent/spring-cloud-tencent/pull/109)
- [feat:add custom label resolver spi for rate limit](https://github.com/Tencent/spring-cloud-tencent/pull/107)
- [feat:fix discovery weight param not set to register request bug](https://github.com/Tencent/spring-cloud-tencent/pull/104)
- [Bugfix: fix causing cpu 100% when set ScheduledThreadPoolExecutor corePoolSize=0](https://github.com/Tencent/spring-cloud-tencent/pull/101)
- [Refactor: refactor transfer metadata](https://github.com/Tencent/spring-cloud-tencent/pull/113)
- [Bugfix: fix circuitbreaker http code greater than 400 as fail response bug](https://github.com/Tencent/spring-cloud-tencent/pull/118)
- [Feat: optimize router dependency](https://github.com/Tencent/spring-cloud-tencent/pull/115)
- [feat:add switch of polaris, discovery and register.](https://github.com/Tencent/spring-cloud-tencent/pull/129)

@ -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>
@ -78,7 +86,7 @@
<properties> <properties>
<!-- Project revision --> <!-- Project revision -->
<revision>1.4.1-2020.0.5-SNAPSHOT</revision> <revision>1.4.2-2020.0.5-SNAPSHOT</revision>
<!-- Spring Cloud --> <!-- Spring Cloud -->
<spring.cloud.version>2020.0.5</spring.cloud.version> <spring.cloud.version>2020.0.5</spring.cloud.version>

@ -17,7 +17,7 @@
<!-- Spring Cloud Tencent dependencies start --> <!-- Spring Cloud Tencent dependencies start -->
<dependency> <dependency>
<groupId>com.tencent.cloud</groupId> <groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-polaris-context</artifactId> <artifactId>spring-cloud-tencent-polaris-loadbalancer</artifactId>
</dependency> </dependency>
<!-- Spring Cloud Tencent dependencies end --> <!-- Spring Cloud Tencent dependencies end -->

@ -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() {

@ -70,8 +70,8 @@
</developers> </developers>
<properties> <properties>
<revision>1.4.1-2020.0.5-SNAPSHOT</revision> <revision>1.4.2-2020.0.5-SNAPSHOT</revision>
<polaris.version>1.5.1</polaris.version> <polaris.version>1.5.2-SNAPSHOT</polaris.version>
<powermock.version>2.0.0</powermock.version> <powermock.version>2.0.0</powermock.version>
<!-- Maven Plugin Versions --> <!-- Maven Plugin Versions -->

@ -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,13 +4,19 @@
"name": "spring.cloud.polaris.loadbalancer.enabled", "name": "spring.cloud.polaris.loadbalancer.enabled",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"defaultValue": "true", "defaultValue": "true",
"description": "polaris loadbalancer" "description": "polaris loadbalancer."
},
{
"name": "spring.cloud.polaris.loadbalancer.discoveryType",
"type": "java.lang.String",
"defaultValue": "POLARIS",
"description": "Type of discovery server."
}, },
{ {
"name": "spring.cloud.polaris.loadbalancer.strategy", "name": "spring.cloud.polaris.loadbalancer.strategy",
"type": "java.lang.String", "type": "java.lang.String",
"defaultValue": "random", "defaultValue": "random",
"description": "retry,best_available,availability_filtering,round_robin,weighted_response_time,zone_avoidance,random,consistent_hash,weighted_random" "description": "retry,best_available,availability_filtering,round_robin,weighted_response_time,zone_avoidance,random,consistent_hash,weighted_random."
} }
] ]
} }

@ -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