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 9a58bccc..2f2637e1 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 @@ -30,6 +30,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; +import static com.tencent.cloud.common.constant.ContextConstant.DEFAULT_REGISTRY_HEARTBEAT_TIME_INTERVAL; + /** * Properties for Polaris. * @@ -95,6 +97,13 @@ public class PolarisDiscoveryProperties { @Value("${spring.cloud.polaris.discovery.heartbeat.enabled:#{true}}") private Boolean heartbeatEnabled = true; + /** + * Heart beat interval (The time interval must be greater than zone). + * Time unit: millisecond. Default: 5000. + * @see ContextConstant#DEFAULT_REGISTRY_HEARTBEAT_TIME_INTERVAL + */ + private Integer heartBeatInterval = 5000; + /** * Custom health check url to override default. */ @@ -202,6 +211,17 @@ public class PolarisDiscoveryProperties { this.serviceListRefreshInterval = serviceListRefreshInterval; } + public Integer getHeartBeatInterval() { + if (this.heartbeatEnabled && this.heartBeatInterval <= 0) { + return DEFAULT_REGISTRY_HEARTBEAT_TIME_INTERVAL; + } + return heartBeatInterval; + } + + public void setHeartBeatInterval(Integer heartBeatInterval) { + this.heartBeatInterval = heartBeatInterval; + } + @Override public String toString() { return "PolarisDiscoveryProperties{" + @@ -215,6 +235,7 @@ public class PolarisDiscoveryProperties { ", enabled=" + enabled + ", registerEnabled=" + registerEnabled + ", heartbeatEnabled=" + heartbeatEnabled + + ", heartBeatInterval=" + heartBeatInterval + ", healthCheckUrl='" + healthCheckUrl + '\'' + ", serviceListRefreshInterval=" + serviceListRefreshInterval + '}'; 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 ce43c841..5ac48bf7 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 @@ -20,7 +20,6 @@ package com.tencent.cloud.polaris.registry; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; @@ -42,6 +41,7 @@ import org.springframework.beans.BeanUtils; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.springframework.util.ReflectionUtils.rethrowRuntimeException; /** @@ -53,8 +53,6 @@ public class PolarisServiceRegistry implements ServiceRegistry { private static final Logger LOG = LoggerFactory.getLogger(PolarisServiceRegistry.class); - private static final int ttl = 5; - private final PolarisDiscoveryProperties polarisDiscoveryProperties; private final PolarisDiscoveryHandler polarisDiscoveryHandler; @@ -97,7 +95,7 @@ public class PolarisServiceRegistry implements ServiceRegistry { instanceRegisterRequest.setZone(staticMetadataManager.getZone()); instanceRegisterRequest.setCampus(staticMetadataManager.getCampus()); if (null != heartbeatExecutor) { - instanceRegisterRequest.setTtl(ttl); + instanceRegisterRequest.setTtl(polarisDiscoveryProperties.getHeartBeatInterval()); } instanceRegisterRequest.setMetadata(registration.getMetadata()); instanceRegisterRequest.setProtocol(polarisDiscoveryProperties.getProtocol()); @@ -217,6 +215,6 @@ public class PolarisServiceRegistry implements ServiceRegistry { catch (Exception e) { LOG.error("polaris heartbeat runtime error", e); } - }, ttl, ttl, TimeUnit.SECONDS); + }, polarisDiscoveryProperties.getHeartBeatInterval(), polarisDiscoveryProperties.getHeartBeatInterval(), MILLISECONDS); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java index 390c6ea2..9c6e64dc 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/PolarisDiscoveryPropertiesTest.java @@ -41,6 +41,10 @@ public class PolarisDiscoveryPropertiesTest { polarisDiscoveryProperties.setHeartbeatEnabled(true); assertThat(polarisDiscoveryProperties.isHeartbeatEnabled()).isTrue(); + // HeartbeatEnabled + polarisDiscoveryProperties.setHeartBeatInterval(2000); + assertThat(polarisDiscoveryProperties.getHeartBeatInterval()).isEqualTo(2000); + // Namespace polarisDiscoveryProperties.setNamespace(NAMESPACE_TEST); assertThat(polarisDiscoveryProperties.getNamespace()).isEqualTo(NAMESPACE_TEST); @@ -96,6 +100,7 @@ public class PolarisDiscoveryPropertiesTest { + ", enabled=true" + ", registerEnabled=true" + ", heartbeatEnabled=true" + + ", heartBeatInterval=2000" + ", healthCheckUrl='/health'" + ", serviceListRefreshInterval=1000}"); } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java index e2b2608b..8117ef8f 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/ContextConstant.java @@ -36,6 +36,11 @@ public final class ContextConstant { */ public static final String UTF_8 = StandardCharsets.UTF_8.name(); + /** + * Default registry heartbeat time interval, default: 5000 (ms). + */ + public static final Integer DEFAULT_REGISTRY_HEARTBEAT_TIME_INTERVAL = 5000; + private ContextConstant() { } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java new file mode 100644 index 00000000..0b5c1d8d --- /dev/null +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/LoadBalancerUtilsTest.java @@ -0,0 +1,95 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.loadbalancer; + +import java.util.LinkedList; +import java.util.List; + +import com.netflix.loadbalancer.Server; +import com.tencent.cloud.common.pojo.PolarisServer; +import com.tencent.polaris.api.pojo.DefaultInstance; +import com.tencent.polaris.api.pojo.DefaultServiceInstances; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.api.pojo.ServiceInstances; +import com.tencent.polaris.api.pojo.ServiceKey; +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Test for {@link LoadBalancerUtilsTest} . + * + * @author Palmer Xu 2022-06-21 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = LoadBalancerUtilsTest.TestApplication.class, + properties = {"spring.cloud.polaris.namespace = testNamespace", + "spring.cloud.polaris.loadbalancer.enabled = false", + "spring.application.name = testApp", + "spring.main.web-application-type = none"}) +public class LoadBalancerUtilsTest { + + private static final String TEST_NAMESPACE = "testNamespace"; + private static final String TEST_SERVICE = "testService"; + + @Test + public void testTransferServersToServiceInstances() { + ServiceInstances serviceInstances = LoadBalancerUtils.transferServersToServiceInstances(assembleServers()); + Assertions.assertThat(serviceInstances).isInstanceOf(DefaultServiceInstances.class); + Assertions.assertThat(serviceInstances.getInstances().size()).isEqualTo(4); + ServiceKey actual = serviceInstances.getServiceKey(); + Assertions.assertThat(actual.getNamespace()).isEqualTo(TEST_NAMESPACE); + Assertions.assertThat(actual.getService()).isEqualTo(TEST_SERVICE); + } + + private ServiceInstances assembleServiceInstances() { + ServiceKey serviceKey = new ServiceKey(TEST_NAMESPACE, TEST_SERVICE); + List instances = new LinkedList<>(); + DefaultInstance instance = new DefaultInstance(); + instance.setService(TEST_SERVICE); + instances.add(instance); + instances.add(new DefaultInstance()); + instances.add(new DefaultInstance()); + instances.add(new DefaultInstance()); + instances.add(new DefaultInstance()); + + return new DefaultServiceInstances(serviceKey, instances); + } + + private List assembleServers() { + ServiceInstances serviceInstances = assembleServiceInstances(); + List servers = new LinkedList<>(); + DefaultInstance instance = new DefaultInstance(); + instance.setService(TEST_SERVICE); + servers.add(new PolarisServer(serviceInstances, instance)); + servers.add(new PolarisServer(serviceInstances, new DefaultInstance())); + servers.add(new PolarisServer(serviceInstances, new DefaultInstance())); + servers.add(new PolarisServer(serviceInstances, new DefaultInstance())); + return servers; + } + + @SpringBootApplication + protected static class TestApplication { + + } +} diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java index e9d8580d..e34419a4 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java @@ -39,7 +39,7 @@ import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.api.rpc.InstancesResponse; import com.tencent.polaris.router.api.core.RouterAPI; import com.tencent.polaris.router.api.rpc.ProcessLoadBalanceResponse; -import org.junit.Assert; +import org.assertj.core.api.Assertions; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -104,8 +104,8 @@ public class PolarisLoadBalancerTest { String host = balancer.choose(null); - Assert.assertNotNull(host); - Assert.assertEquals("127.0.0.1:8080", host); + Assertions.assertThat(host).isNotNull(); + Assertions.assertThat(host).isEqualTo("127.0.0.1:8080"); } } @@ -136,7 +136,7 @@ public class PolarisLoadBalancerTest { consumerAPI, properties); String host = balancer.choose(null); - Assert.assertEquals("127.0.0.1:8080", host); + Assertions.assertThat(host).isEqualTo("127.0.0.1:8080"); } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java index 5004959f..40ed6568 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfigurationTest.java @@ -113,6 +113,5 @@ public class PolarisLoadBalancerAutoConfigurationTest { public ConsumerAPI consumerAPI() { return new DefaultConsumerAPI(sdkContext); } - } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java index d514af6d..65f11718 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfigurationTest.java @@ -30,7 +30,6 @@ import static org.assertj.core.api.Assertions.assertThat; * Test for {@link PolarisRibbonClientConfiguration}. * * @author wlx - * @date 2022/7/2 10:36 上午 */ public class PolarisRibbonClientConfigurationTest { @@ -51,5 +50,4 @@ public class PolarisRibbonClientConfigurationTest { @SpringBootApplication static class TestApplication { } - }