You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/08/27 06:33:26 UTC
[incubator-servicecomb-java-chassis] branch master updated (ea17cca
-> b9eed06)
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git.
from ea17cca [SCB-861]490,590 response not properly used
new 1878b4b [SBC-870]refractor to using custom RuleExt, not using Robin IRule.
new 32eefbc [SBC-870]remove not correct test.
new 479a665 [SBC-870]fix test error.
new d12f88c [SBC-870]fix test error.
new b92c250 [SBC-870] change loadbalancer to meet invocation level
new 7e274a7 [SBC-870] give users a error message when use old configurations
new 5ad67e0 [SBC-870] change weights to Robin Weights and change algorithm
new b9eed06 [SBC-870] make slow machine happy
The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../common/rest/codec/RestObjectMapper.java | 2 +
.../client/CustomLoadbalanceExtensionsFactory.java | 6 +-
.../servicecomb/demo/pojo/client/PojoClient.java | 15 +-
.../demo/springmvc/client/SpringmvcClient.java | 12 ++
.../src/main/resources/microservice.yaml | 3 +-
.../servicecomb/loadbalance/Configuration.java | 27 ---
.../servicecomb/loadbalance/ExtensionsFactory.java | 2 +-
.../servicecomb/loadbalance/ExtensionsManager.java | 14 +-
.../servicecomb/loadbalance/LoadBalancer.java | 85 +++------
.../loadbalance/LoadBalancerCreator.java | 103 -----------
.../loadbalance/LoadbalanceHandler.java | 93 +++++-----
.../servicecomb/loadbalance/RandomRuleExt.java} | 20 +--
.../loadbalance/RoundRobinRuleExt.java} | 20 +--
.../RuleClassNameExtentionsFactory.java | 62 -------
.../apache/servicecomb/loadbalance/RuleExt.java} | 19 +-
.../loadbalance/RuleNameExtentionsFactory.java | 12 +-
.../loadbalance/ServerListFilterExt.java | 12 +-
.../loadbalance/ServiceCombLoadBalancerStats.java | 12 +-
.../servicecomb/loadbalance/ServiceCombServer.java | 16 ++
.../loadbalance/SessionStickinessRule.java | 70 +++-----
.../loadbalance/WeightedResponseTimeRuleExt.java | 103 +++++++++++
.../loadbalance/MyServerListFilterExt.java | 2 +-
.../servicecomb/loadbalance/TestConfiguration.java | 2 -
.../loadbalance/TestExtensionsManager.java | 31 +---
.../loadbalance/TestLoadBalanceCreator.java | 199 +++++++++++++--------
.../loadbalance/TestLoadBalanceHandler2.java | 53 ++++--
.../servicecomb/loadbalance/TestLoadBalancer.java | 110 ++----------
.../loadbalance/TestLoadbalanceHandler.java | 31 +---
.../loadbalance/TestRoundRobinRuleExt.java | 76 ++++++++
.../TestServiceCombLoadBalancerStats.java | 2 +-
.../loadbalance/TestSessionSticknessRule.java | 93 +++++-----
.../TestWeightedResponseTimeRuleExt.java | 126 +++++++++++++
.../filter/TestServerDiscoveryFilter.java | 1 +
.../swagger/engine/SwaggerProducerOperation.java | 8 +
34 files changed, 721 insertions(+), 721 deletions(-)
delete mode 100644 handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
copy handlers/handler-loadbalance/src/{test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java => main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java} (72%)
copy handlers/handler-loadbalance/src/{test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java => main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java} (69%)
delete mode 100644 handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
copy handlers/handler-loadbalance/src/{test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceClientConfig.java => main/java/org/apache/servicecomb/loadbalance/RuleExt.java} (74%)
create mode 100644 handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
create mode 100644 handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java
create mode 100644 handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java
[incubator-servicecomb-java-chassis] 05/08: [SBC-870] change
loadbalancer to meet invocation level
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit b92c25060ee4335a921aa535758cfd2892e1779a
Author: liubao <ba...@huawei.com>
AuthorDate: Sat Aug 25 14:53:27 2018 +0800
[SBC-870] change loadbalancer to meet invocation level
---
.../servicecomb/loadbalance/LoadBalancer.java | 24 ++++----
.../loadbalance/LoadBalancerCreator.java | 69 ----------------------
.../loadbalance/LoadbalanceHandler.java | 31 +++++-----
.../loadbalance/TestLoadBalanceCreator.java | 50 +++++++++++-----
.../loadbalance/TestLoadBalanceHandler2.java | 31 +++++++---
.../servicecomb/loadbalance/TestLoadBalancer.java | 10 ++--
.../loadbalance/TestLoadbalanceHandler.java | 30 +---------
.../loadbalance/TestSessionSticknessRule.java | 4 +-
8 files changed, 95 insertions(+), 154 deletions(-)
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
index 3a96b59..463ea19 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
@@ -20,7 +20,9 @@ package org.apache.servicecomb.loadbalance;
import java.util.List;
import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import com.google.common.annotations.VisibleForTesting;
import com.netflix.loadbalancer.LoadBalancerStats;
/**
@@ -35,25 +37,22 @@ public class LoadBalancer {
private List<ServerListFilterExt> filters;
- private List<ServiceCombServer> servers;
-
- public LoadBalancer(RuleExt rule, String microServiceName,
- LoadBalancerStats stats, List<ServerListFilterExt> filters, List<ServiceCombServer> servers) {
+ public LoadBalancer(RuleExt rule, String microServiceName) {
this.microServiceName = microServiceName;
this.rule = rule;
- this.lbStats = stats;
- this.filters = filters;
- this.servers = servers;
+ this.lbStats = new LoadBalancerStats(null);
+ // load new instances, because filters work on service information
+ this.filters = SPIServiceUtils.loadSortedService(ServerListFilterExt.class);
this.rule.setLoadBalancer(this);
this.filters.forEach((item) -> item.setLoadBalancer(this));
}
public ServiceCombServer chooseServer(Invocation invocation) {
- List<ServiceCombServer> temp = this.servers;
+ List<ServiceCombServer> servers = invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
for (ServerListFilterExt filterExt : filters) {
- temp = filterExt.getFilteredListOfServers(temp, invocation);
+ servers = filterExt.getFilteredListOfServers(servers, invocation);
}
- return rule.choose(temp, invocation);
+ return rule.choose(servers, invocation);
}
public LoadBalancerStats getLoadBalancerStats() {
@@ -63,4 +62,9 @@ public class LoadBalancer {
public String getMicroServiceName() {
return microServiceName;
}
+
+ @VisibleForTesting
+ void setFilters(List<ServerListFilterExt> filters) {
+ this.filters = filters;
+ }
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
deleted file mode 100644
index 5cb18dc..0000000
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 org.apache.servicecomb.loadbalance;
-
-import java.util.List;
-
-import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.netflix.loadbalancer.LoadBalancerStats;
-
-/**
- * Create a suitable load balancer for each invocation.
- *
- * Robin components work good in service level state, and we want to reuse its IRule components and other
- * facilities, but they are not good for operation
- * level filters, so write a custom load balance process.
- *
- * Load balance instance is created for each microservice(plus version rule), thus it is service level,
- * it only can contains stateful information with service. e.g. LoadBalancerStats.
- *
- * ServerListFilter may choose available servers according to invocation information, IRule will work
- * on the result of ServerListFilter, they should not contain operation level state information in instance fields.
- */
-public class LoadBalancerCreator {
- private RuleExt rule;
-
- private LoadBalancerStats lbStats;
-
- private List<ServerListFilterExt> filters;
-
- private String microServiceName;
-
- public LoadBalancerCreator(RuleExt rule, String microServiceName) {
- this.rule = rule;
- this.microServiceName = microServiceName;
- this.lbStats = new LoadBalancerStats(null);
- // load new instances, because filters work on service information
- this.filters = SPIServiceUtils.loadSortedService(ServerListFilterExt.class);
- }
-
- public void shutdown() {
- // nothing to do now
- }
-
- @VisibleForTesting
- void setFilters(List<ServerListFilterExt> filters) {
- this.filters = filters;
- }
-
- public LoadBalancer createLoadBalancer(List<ServiceCombServer> servers) {
- return new LoadBalancer(rule, microServiceName, lbStats, filters, servers);
- }
-}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
index 06f4b10..9055672 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
@@ -58,6 +58,8 @@ import rx.Observable;
* Load balance handler.
*/
public class LoadbalanceHandler implements Handler {
+ public static final String CONTEXT_KEY_SERVER_LIST = "x-context-server-list";
+
// just a wrapper to make sure in retry mode to choose a different server.
class RetryLoadBalancer implements ILoadBalancer {
// Enough times to make sure to choose a different server in high volume.
@@ -67,9 +69,7 @@ public class LoadbalanceHandler implements Handler {
LoadBalancer delegate;
- Invocation invocation;
-
- RetryLoadBalancer(LoadBalancer delegate, Invocation invocation) {
+ RetryLoadBalancer(LoadBalancer delegate) {
this.delegate = delegate;
}
@@ -81,7 +81,7 @@ public class LoadbalanceHandler implements Handler {
@Override
public Server chooseServer(Object key) {
for (int i = 0; i < COUNT; i++) {
- Server s = delegate.chooseServer(invocation);
+ Server s = delegate.chooseServer((Invocation) key);
if (s != null && !s.equals(lastServer)) {
lastServer = s;
break;
@@ -131,7 +131,7 @@ public class LoadbalanceHandler implements Handler {
private DiscoveryTree discoveryTree = new DiscoveryTree();
// key为grouping filter qualified name
- private volatile Map<String, LoadBalancerCreator> loadBalancerMap = new ConcurrentHashMapEx<>();
+ private volatile Map<String, LoadBalancer> loadBalancerMap = new ConcurrentHashMapEx<>();
private final Object lock = new Object();
@@ -154,6 +154,7 @@ public class LoadbalanceHandler implements Handler {
}
}
this.strategy = strategy;
+
LoadBalancer loadBalancer = getOrCreateLoadBalancer(invocation);
if (!Configuration.INSTANCE.isRetryEnabled(invocation.getMicroserviceName())) {
@@ -164,9 +165,6 @@ public class LoadbalanceHandler implements Handler {
}
private void clearLoadBalancer() {
- for (LoadBalancerCreator creator : loadBalancerMap.values()) {
- creator.shutdown();
- }
loadBalancerMap.clear();
}
@@ -282,7 +280,7 @@ public class LoadbalanceHandler implements Handler {
ExecutionContext<Invocation> context = new ExecutionContext<>(invocation, null, null, null);
LoadBalancerCommand<Response> command = LoadBalancerCommand.<Response>builder()
- .withLoadBalancer(new RetryLoadBalancer(chosenLB, invocation))
+ .withLoadBalancer(new RetryLoadBalancer(chosenLB))
.withServerLocator(invocation)
.withRetryHandler(ExtensionsManager.createRetryHandler(invocation.getMicroserviceName()))
.withListeners(listeners)
@@ -350,22 +348,23 @@ public class LoadbalanceHandler implements Handler {
invocation.getAppId(),
invocation.getMicroserviceName(),
invocation.getMicroserviceVersionRule());
+ invocation.addLocalContext(CONTEXT_KEY_SERVER_LIST, serversVersionedCache.data());
- LoadBalancerCreator loadBalancerCreator = loadBalancerMap.computeIfAbsent(serversVersionedCache.name(), name -> {
- return createLoadBalancerCreator(invocation.getMicroserviceName());
- });
+ LoadBalancer loadBalancer = loadBalancerMap
+ .computeIfAbsent(serversVersionedCache.name(), name -> {
+ return createLoadBalancer(invocation.getMicroserviceName());
+ });
// Nothing to do just help users to deal with incompatible changes.
setTransactionControlFilter(invocation.getMicroserviceName());
loadServerListFilters();
- return loadBalancerCreator.createLoadBalancer(serversVersionedCache.data());
+ return loadBalancer;
}
- private LoadBalancerCreator createLoadBalancerCreator(String microserviceName) {
+ private LoadBalancer createLoadBalancer(String microserviceName) {
RuleExt rule = ExtensionsManager.createLoadBalancerRule(microserviceName);
- LoadBalancerCreator creator = new LoadBalancerCreator(rule, microserviceName);
- return creator;
+ return new LoadBalancer(rule, microserviceName);
}
private void loadServerListFilters() {
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
index 4c5373a..e0019b7 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
@@ -33,7 +33,6 @@ import com.netflix.loadbalancer.Server;
import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Injectable;
-import mockit.Mocked;
public class TestLoadBalanceCreator {
@Test
@@ -54,7 +53,7 @@ public class TestLoadBalanceCreator {
servers.add(server);
servers.add(server2);
- LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "test");
+ LoadBalancer lb = new LoadBalancer(rule, "test");
List<ServerListFilterExt> filters = new ArrayList<>();
@@ -72,9 +71,14 @@ public class TestLoadBalanceCreator {
return filteredServers;
}
});
- lbCreator.setFilters(filters);
+ lb.setFilters(filters);
- LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ new Expectations() {
+ {
+ invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
+ result = servers;
+ }
+ };
Server s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
s = lb.chooseServer(invocation);
@@ -88,7 +92,7 @@ public class TestLoadBalanceCreator {
@Injectable Transport transport) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
RandomRuleExt rule = new RandomRuleExt();
- LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
+ LoadBalancer lb = new LoadBalancer(rule, "service");
List<ServiceCombServer> servers = new ArrayList<>();
Endpoint host1 = new Endpoint(transport, "host1");
@@ -119,8 +123,13 @@ public class TestLoadBalanceCreator {
return filteredServers;
}
});
- lbCreator.setFilters(filters);
- LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ lb.setFilters(filters);
+ new Expectations() {
+ {
+ invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
+ result = servers;
+ }
+ };
Server s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
s = lb.chooseServer(invocation);
@@ -130,11 +139,11 @@ public class TestLoadBalanceCreator {
}
@Test
- public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Injectable Endpoint endpoint1, @Injectable Endpoint endpoint2, @Injectable Invocation invocation) {
+ public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Injectable Endpoint endpoint1,
+ @Injectable Endpoint endpoint2, @Injectable Invocation invocation) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
- LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
-
+ LoadBalancer lb = new LoadBalancer(rule, "service");
List<ServiceCombServer> servers = new ArrayList<>();
MicroserviceInstance instance1 = new MicroserviceInstance();
@@ -170,8 +179,13 @@ public class TestLoadBalanceCreator {
return filteredServers;
}
});
- lbCreator.setFilters(filters);
- LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ lb.setFilters(filters);
+ new Expectations() {
+ {
+ invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
+ result = servers;
+ }
+ };
Server s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
s = lb.chooseServer(invocation);
@@ -184,7 +198,7 @@ public class TestLoadBalanceCreator {
public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation invocation,
@Injectable Transport transport) {
SessionStickinessRule rule = new SessionStickinessRule();
- LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
+ LoadBalancer lb = new LoadBalancer(rule, "service");
List<ServiceCombServer> servers = new ArrayList<>();
Endpoint host1 = new Endpoint(transport, "host1");
@@ -200,8 +214,14 @@ public class TestLoadBalanceCreator {
servers.add(server);
servers.add(server2);
- lbCreator.setFilters(new ArrayList<>());
- LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ lb.setFilters(new ArrayList<>());
+ new Expectations() {
+ {
+ invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
+ result = servers;
+ }
+ };
+
Server s = lb.chooseServer(invocation);
Assert.assertEquals(server, s);
s = lb.chooseServer(invocation);
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
index 906529f..3dbfa32 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
@@ -17,6 +17,8 @@
package org.apache.servicecomb.loadbalance;
+import static org.mockito.Mockito.when;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -25,6 +27,10 @@ import java.util.Map;
import org.apache.servicecomb.core.CseContext;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.Transport;
+import org.apache.servicecomb.core.definition.MicroserviceMeta;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.definition.SchemaMeta;
+import org.apache.servicecomb.core.provider.consumer.ReferenceConfig;
import org.apache.servicecomb.core.transport.TransportManager;
import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
import org.apache.servicecomb.serviceregistry.RegistryUtils;
@@ -58,7 +64,18 @@ public class TestLoadBalanceHandler2 {
@Test
public void testZoneAwareAndIsolationFilterWorks() {
- Invocation invocation = Mockito.mock(Invocation.class);
+ ReferenceConfig referenceConfig = Mockito.mock(ReferenceConfig.class);
+ OperationMeta operationMeta = Mockito.mock(OperationMeta.class);
+ SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);
+ when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
+ MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);
+ when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
+ when(schemaMeta.getMicroserviceName()).thenReturn("testMicroserviceName");
+ when(microserviceMeta.getAppId()).thenReturn("testApp");
+ when(referenceConfig.getVersionRule()).thenReturn("0.0.0+");
+ when(referenceConfig.getTransport()).thenReturn("rest");
+ Invocation invocation = new Invocation(referenceConfig, operationMeta, new Object[0]);
+
InstanceCacheManager instanceCacheManager = Mockito.mock(InstanceCacheManager.class);
ServiceRegistry serviceRegistry = Mockito.mock(ServiceRegistry.class);
TransportManager transportManager = Mockito.mock(TransportManager.class);
@@ -112,15 +129,11 @@ public class TestLoadBalanceHandler2 {
RegistryUtils.setServiceRegistry(serviceRegistry);
- Mockito.when(invocation.getAppId()).thenReturn("testApp");
- Mockito.when(invocation.getMicroserviceName()).thenReturn("testMicroserviceName");
- Mockito.when(invocation.getMicroserviceVersionRule()).thenReturn("0.0.0+");
- Mockito.when(invocation.getConfigTransportName()).thenReturn("rest");
- Mockito.when(serviceRegistry.getMicroserviceInstance()).thenReturn(myself);
- Mockito.when(serviceRegistry.getInstanceCacheManager()).thenReturn(instanceCacheManager);
- Mockito.when(instanceCacheManager.getOrCreateVersionedCache("testApp", "testMicroserviceName", "0.0.0+"))
+ when(serviceRegistry.getMicroserviceInstance()).thenReturn(myself);
+ when(serviceRegistry.getInstanceCacheManager()).thenReturn(instanceCacheManager);
+ when(instanceCacheManager.getOrCreateVersionedCache("testApp", "testMicroserviceName", "0.0.0+"))
.thenReturn(parent);
- Mockito.when(transportManager.findTransport("rest")).thenReturn(transport);
+ when(transportManager.findTransport("rest")).thenReturn(transport);
LoadbalanceHandler handler = null;
LoadBalancer loadBalancer = null;
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
index 7b26368..761c23c 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
@@ -17,6 +17,8 @@
package org.apache.servicecomb.loadbalance;
+import static org.mockito.Mockito.when;
+
import java.util.ArrayList;
import java.util.List;
@@ -34,14 +36,14 @@ public class TestLoadBalancer {
ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
Invocation invocation = Mockito.mock(Invocation.class);
newServers.add(server);
- List<ServerListFilterExt> filterExts = new ArrayList<>();
- LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null, filterExts, newServers);
+ when(invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST)).thenReturn(newServers);
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "test");
loadBalancer.chooseServer(invocation);
- Mockito.when(rule.choose(newServers, invocation)).thenReturn(server);
+ when(rule.choose(newServers, invocation)).thenReturn(server);
Assert.assertEquals(server, loadBalancer.chooseServer(invocation));
- Assert.assertEquals(null, loadBalancer.getLoadBalancerStats());
+ Assert.assertNotNull(loadBalancer.getLoadBalancerStats());
Assert.assertEquals("test", loadBalancer.getMicroServiceName());
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
index 468e482..eedf60c 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
@@ -74,7 +74,7 @@ public class TestLoadbalanceHandler {
LoadbalanceHandler handler;
- Map<String, LoadBalancerCreator> loadBalancerMap;
+ Map<String, LoadBalancer> loadBalancerMap;
@Injectable
Invocation invocation;
@@ -154,34 +154,6 @@ public class TestLoadbalanceHandler {
}
@Test
- public void getOrCreateLoadBalancer() throws Exception {
- LoadbalanceHandler handler = new LoadbalanceHandler();
-
- MicroserviceInstance instance = new MicroserviceInstance();
- instance.setInstanceId("id");
- instance.getEndpoints().add("rest://localhost:8080");
-
- Map<String, MicroserviceInstance> instanceMap = new HashMap<>();
- instanceMap.put(instance.getInstanceId(), instance);
-
- VersionedCache instanceVersionedCache =
- new VersionedCache().autoCacheVersion().name("instanceCache").data(instanceMap);
-
- new Expectations() {
- {
- invocation.getConfigTransportName();
- result = "rest";
- instanceCacheManager.getOrCreateVersionedCache(anyString, anyString, anyString);
- result = instanceVersionedCache;
- }
- };
-
- LoadBalancer lb = handler.getOrCreateLoadBalancer(invocation);
-
- Assert.assertEquals("[rest://localhost:8080]", Deencapsulation.getField(lb, "servers").toString());
- }
-
- @Test
public void send_noEndPoint(@Injectable LoadBalancer loadBalancer) {
new Expectations(loadBalancer) {
{
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
index dd2319e..303735c 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
@@ -255,8 +255,8 @@ public class TestSessionSticknessRule {
mockedServer.setReadyToServe(true);
mockedServer.setId("mockedServer");
List<ServiceCombServer> allServers = Arrays.asList(mockedServer);
- LoadBalancer lb = new LoadBalancer(rule, "mockedServer", null, new ArrayList<>(), allServers);
-
+ LoadBalancer lb = new LoadBalancer(rule, "mockedServer");
+ when(invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST)).thenReturn(allServers);
rule.setLoadBalancer(lb);
ServiceCombServer server = new ServiceCombServer(transport, new CacheEndpoint("rest:127.0.0.1:8890", instance1));
Deencapsulation.setField(rule, "lastServer", server);
[incubator-servicecomb-java-chassis] 02/08: [SBC-870]remove not
correct test.
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 32eefbc13e58fa4990a017a16492f2c3c77786f2
Author: liubao <ba...@huawei.com>
AuthorDate: Sat Aug 25 09:15:51 2018 +0800
[SBC-870]remove not correct test.
---
.../apache/servicecomb/demo/pojo/client/PojoClient.java | 15 +--------------
.../pojo-server/src/main/resources/microservice.yaml | 4 ++--
2 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
index 3b55ebb..ccb01ca 100644
--- a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
+++ b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
@@ -111,24 +111,11 @@ public class PojoClient {
testNull(testFromXml);
testNull(test);
testEmpty(test);
+
// This test case shows destroy of WeightedResponseTimeRule timer task. after test finished will not print:
// "Weight adjusting job started" and thread "NFLoadBalancer-serverWeightTimer-unknown" destroyed.
ArchaiusUtils.setProperty("servicecomb.loadbalance.strategy.name", "WeightedResponse");
testStringArray(test);
- boolean checkerStated = false;
- // Timer may not start thread very fast so check for 3 times.
- for (int i = 0; i < 3; i++) {
- Set<Thread> allThreads = Thread.getAllStackTraces().keySet();
- for (Thread t : allThreads) {
- if (t.getName().equals("NFLoadBalancer-serverWeightTimer-unknown")) {
- checkerStated = true;
- break;
- }
- }
- Thread.sleep(1000);
- }
- TestMgr.check(checkerStated, true);
-
ArchaiusUtils.setProperty("servicecomb.loadbalance.strategy.name", "RoundRobin");
testStringArray(test);
diff --git a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
index e705183..77e9502 100644
--- a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
+++ b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
@@ -24,9 +24,9 @@ servicecomb:
registry:
address: http://127.0.0.1:30100
rest:
- address: 0.0.0.0:8080?protocol=http2
+ address: 0.0.0.0:8086?protocol=http2
highway:
- address: 0.0.0.0:7070
+ address: 0.0.0.0:7076
#executors:
#default: test
#Provider:
[incubator-servicecomb-java-chassis] 06/08: [SBC-870] give users a
error message when use old configurations
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 7e274a7773bacf432ca0e66000adb8ddf0256385
Author: liubao <ba...@huawei.com>
AuthorDate: Sat Aug 25 15:21:35 2018 +0800
[SBC-870] give users a error message when use old configurations
---
.../servicecomb/loadbalance/Configuration.java | 17 --------
.../loadbalance/LoadbalanceHandler.java | 46 +++++++++++-----------
2 files changed, 22 insertions(+), 41 deletions(-)
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
index 2268855..2ce09e3 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
@@ -54,17 +54,6 @@ public final class Configuration {
public static final String SUCCESSIVE_FAILED_TIMES = "SessionStickinessRule.successiveFailedTimes";
- // Begin: ServerListFilters configurations
- //Enabled filter lists, e.g servicecomb.loadbalance.serverListFilters=a,b,c
- public static final String SERVER_LIST_FILTERS = "servicecomb.loadbalance.serverListFilters";
-
- //Class name of each filter: e.g servicecomb.loadbalance.serverListFilter.a.className=org.apache.servicecomb.MyServerListFilterExt
- public static final String SERVER_LIST_FILTER_CLASS_HOLDER = "servicecomb.loadbalance.serverListFilter.%s.className";
-
- //Property of the class: e.g servicecomb.loadbalance.serverListFilter.a.myproperty=sample
- public static final String SERVER_LIST_FILTER_PROPERTY_HOLDER = "servicecomb.loadbalance.serverListFilter.%s.%s";
- //End: ServerListFilters configurations
-
private static final double PERCENT = 100;
public static final String FILTER_ISOLATION = "isolation.";
@@ -82,8 +71,6 @@ public final class Configuration {
public static final String TRANSACTIONCONTROL_OPTIONS_PREFIX_PATTERN =
"servicecomb.loadbalance.%s.transactionControl.options";
- public static final String TRANSACTIONCONTROL_POLICY_KEY_PATTERN = "servicecomb.loadbalance.%s.transactionControl.policy";
-
public static final Configuration INSTANCE = new Configuration();
private Configuration() {
@@ -224,10 +211,6 @@ public final class Configuration {
}
}
- public String getFlowsplitFilterPolicy(String microservice) {
- return getStringProperty("", String.format(TRANSACTIONCONTROL_POLICY_KEY_PATTERN, microservice));
- }
-
public Map<String, String> getFlowsplitFilterOptions(String microservice) {
String keyPrefix = String.format(TRANSACTIONCONTROL_OPTIONS_PREFIX_PATTERN, microservice);
return ConfigurePropertyUtils.getPropertiesWithPrefix(keyPrefix);
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
index 9055672..30ee21b 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
@@ -44,6 +44,7 @@ import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.netflix.config.DynamicPropertyFactory;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.reactive.ExecutionContext;
@@ -139,11 +140,31 @@ public class LoadbalanceHandler implements Handler {
public LoadbalanceHandler() {
+ preCheck();
discoveryTree.loadFromSPI(DiscoveryFilter.class);
discoveryTree.addFilter(new ServerDiscoveryFilter());
discoveryTree.sort();
}
+ private void preCheck() {
+ // Old configurations check.Just print an error, because configurations may given in dynamic and fail on runtime.
+
+ String policyName = DynamicPropertyFactory.getInstance()
+ .getStringProperty("servicecomb.loadbalance.NFLoadBalancerRuleClassName", null).get();
+ if (!StringUtils.isEmpty(policyName)) {
+ LOGGER.error("[servicecomb.loadbalance.NFLoadBalancerRuleClassName] is not supported anymore." +
+ "use [servicecomb.loadbalance.strategy.name] instead.");
+ }
+
+ String filterNames = Configuration.getStringProperty(null, "servicecomb.loadbalance.serverListFilters");
+ if (!StringUtils.isEmpty(filterNames)) {
+ LOGGER.error(
+ "Server list implementation changed to SPI. Configuration [servicecomb.loadbalance.serverListFilters]" +
+ " is not used any more. For ServiceComb defined filters, you do not need config and can "
+ + "remove this configuration safely. If you define your own filter, need to change it to SPI to make it work.");
+ }
+ }
+
@Override
public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
String strategy = Configuration.INSTANCE.getRuleStrategyName(invocation.getMicroserviceName());
@@ -168,14 +189,6 @@ public class LoadbalanceHandler implements Handler {
loadBalancerMap.clear();
}
- protected void setTransactionControlFilter(String microserviceName) {
- String policyClsName = Configuration.INSTANCE.getFlowsplitFilterPolicy(microserviceName);
- if (!policyClsName.isEmpty()) {
- LOGGER.error(Configuration.TRANSACTIONCONTROL_POLICY_KEY_PATTERN + " is not supported anymore." +
- "You can change this class to SPI, and filters will be loaded by SPI.");
- }
- }
-
private void send(Invocation invocation, AsyncResponse asyncResp, final LoadBalancer chosenLB) throws Exception {
long time = System.currentTimeMillis();
ServiceCombServer server = (ServiceCombServer) chosenLB.chooseServer(invocation);
@@ -350,16 +363,10 @@ public class LoadbalanceHandler implements Handler {
invocation.getMicroserviceVersionRule());
invocation.addLocalContext(CONTEXT_KEY_SERVER_LIST, serversVersionedCache.data());
- LoadBalancer loadBalancer = loadBalancerMap
+ return loadBalancerMap
.computeIfAbsent(serversVersionedCache.name(), name -> {
return createLoadBalancer(invocation.getMicroserviceName());
});
-
- // Nothing to do just help users to deal with incompatible changes.
- setTransactionControlFilter(invocation.getMicroserviceName());
- loadServerListFilters();
-
- return loadBalancer;
}
private LoadBalancer createLoadBalancer(String microserviceName) {
@@ -367,15 +374,6 @@ public class LoadbalanceHandler implements Handler {
return new LoadBalancer(rule, microserviceName);
}
- private void loadServerListFilters() {
- String filterNames = Configuration.getStringProperty(null, Configuration.SERVER_LIST_FILTERS);
- if (!StringUtils.isEmpty(filterNames)) {
- LOGGER.error("Server list implementation changed to SPI. Configuration " + Configuration.SERVER_LIST_FILTERS +
- " is not used any more. For ServiceComb defined filters, you do not need config and can "
- + "remove this configuration safely. If you define your own filter, need to change it to SPI to make it work.");
- }
- }
-
public boolean isEqual(String str1, String str2) {
return (str1 == null ? str2 == null : str1.equals(str2));
}
[incubator-servicecomb-java-chassis] 04/08: [SBC-870]fix test error.
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit d12f88cb12717c7557428c62d3e057ad451f0955
Author: liubao <ba...@huawei.com>
AuthorDate: Sat Aug 25 11:20:25 2018 +0800
[SBC-870]fix test error.
---
.../servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java | 2 +-
demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml | 4 ++--
demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml | 4 ++--
.../src/main/resources/microservice.yaml | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
index 2481e52..38ae6e9 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
@@ -110,7 +110,7 @@ public class CodeFirstRestTemplateJaxrs extends CodeFirstRestTemplate {
private void test404(RestTemplate template) {
HttpClientErrorException exception = null;
try {
- template.getForEntity("http://127.0.0.1:8086/aPathNotExist", String.class);
+ template.getForEntity("http://127.0.0.1:8080/aPathNotExist", String.class);
} catch (RestClientException e) {
if (e instanceof HttpClientErrorException) {
exception = (HttpClientErrorException) e;
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
index c4bbcdd..89f324c 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
@@ -24,9 +24,9 @@ servicecomb:
registry:
address: http://127.0.0.1:30100
rest:
- address: 0.0.0.0:8086
+ address: 0.0.0.0:8080
highway:
- address: 0.0.0.0:7076
+ address: 0.0.0.0:7070
handler:
chain:
Provider:
diff --git a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
index 77e9502..e705183 100644
--- a/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
+++ b/demo/demo-pojo/pojo-server/src/main/resources/microservice.yaml
@@ -24,9 +24,9 @@ servicecomb:
registry:
address: http://127.0.0.1:30100
rest:
- address: 0.0.0.0:8086?protocol=http2
+ address: 0.0.0.0:8080?protocol=http2
highway:
- address: 0.0.0.0:7076
+ address: 0.0.0.0:7070
#executors:
#default: test
#Provider:
diff --git a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
index 89e1297..09c50e3 100644
--- a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
@@ -25,9 +25,9 @@ servicecomb:
registry:
address: http://127.0.0.1:30100
rest:
- address: 0.0.0.0:8086
+ address: 0.0.0.0:8080
highway:
- address: 0.0.0.0:7076
+ address: 0.0.0.0:7070
handler:
chain:
Provider:
[incubator-servicecomb-java-chassis] 03/08: [SBC-870]fix test error.
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 479a665fe0532e044278e9bd34659456a4f8d426
Author: liubao <ba...@huawei.com>
AuthorDate: Sat Aug 25 10:02:35 2018 +0800
[SBC-870]fix test error.
---
.../src/main/resources/microservice.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
index 09c50e3..89e1297 100644
--- a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/microservice.yaml
@@ -25,9 +25,9 @@ servicecomb:
registry:
address: http://127.0.0.1:30100
rest:
- address: 0.0.0.0:8080
+ address: 0.0.0.0:8086
highway:
- address: 0.0.0.0:7070
+ address: 0.0.0.0:7076
handler:
chain:
Provider:
[incubator-servicecomb-java-chassis] 07/08: [SBC-870] change
weights to Robin Weights and change algorithm
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 5ad67e04fa299b1ee07f7783380885f76ced80b2
Author: liubao <ba...@huawei.com>
AuthorDate: Sat Aug 25 17:50:52 2018 +0800
[SBC-870] change weights to Robin Weights and change algorithm
---
.../servicecomb/loadbalance/LoadBalancer.java | 5 +-
.../loadbalance/LoadbalanceHandler.java | 8 +-
.../loadbalance/ServiceCombLoadBalancerStats.java | 11 +-
.../loadbalance/ServiceCombServerStats.java | 19 +---
.../loadbalance/WeightedResponseTimeRuleExt.java | 76 +++++++++----
.../loadbalance/TestLoadBalanceHandler2.java | 16 +--
.../loadbalance/TestRoundRobinRuleExt.java | 76 +++++++++++++
.../TestServiceCombLoadBalancerStats.java | 18 +--
.../loadbalance/TestServiceCombServerStats.java | 22 ++--
.../TestWeightedResponseTimeRuleExt.java | 126 +++++++++++++++++++++
10 files changed, 302 insertions(+), 75 deletions(-)
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
index 463ea19..bcc9fea 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
@@ -18,6 +18,7 @@
package org.apache.servicecomb.loadbalance;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
@@ -29,6 +30,8 @@ import com.netflix.loadbalancer.LoadBalancerStats;
* A load balancer with RuleExt and ServerListFilterExt
*/
public class LoadBalancer {
+ private static AtomicInteger id = new AtomicInteger(0);
+
private RuleExt rule;
private LoadBalancerStats lbStats;
@@ -40,7 +43,7 @@ public class LoadBalancer {
public LoadBalancer(RuleExt rule, String microServiceName) {
this.microServiceName = microServiceName;
this.rule = rule;
- this.lbStats = new LoadBalancerStats(null);
+ this.lbStats = new LoadBalancerStats(microServiceName + id.getAndDecrement());
// load new instances, because filters work on service information
this.filters = SPIServiceUtils.loadSortedService(ServerListFilterExt.class);
this.rule.setLoadBalancer(this);
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
index 30ee21b..95db713 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
@@ -205,10 +205,10 @@ public class LoadbalanceHandler implements Handler {
chosenLB.getLoadBalancerStats().noteResponseTime(server, (System.currentTimeMillis() - time));
if (isFailedResponse(resp)) {
chosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(server);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, System.currentTimeMillis() - time);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
} else {
chosenLB.getLoadBalancerStats().incrementActiveRequestsCount(server);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, (System.currentTimeMillis() - time));
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
}
asyncResp.handle(resp);
});
@@ -315,13 +315,13 @@ public class LoadbalanceHandler implements Handler {
((Throwable) resp.getResult()).getMessage(),
s);
chosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, System.currentTimeMillis() - time);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
f.onError(resp.getResult());
} else {
chosenLB.getLoadBalancerStats().incrementActiveRequestsCount(s);
chosenLB.getLoadBalancerStats().noteResponseTime(s,
(System.currentTimeMillis() - time));
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, (System.currentTimeMillis() - time));
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
f.onNext(resp);
f.onCompleted();
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
index ac01152..ffde2d7 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
@@ -78,17 +78,17 @@ public class ServiceCombLoadBalancerStats {
}
}
- public void markSuccess(ServiceCombServer server, long execTime) {
+ public void markSuccess(ServiceCombServer server) {
try {
- serverStatsCache.get(server).markSuccess(execTime);
+ serverStatsCache.get(server).markSuccess();
} catch (ExecutionException e) {
LOGGER.error("Not expected to happen, maybe a bug.", e);
}
}
- public void markFailure(ServiceCombServer server, long execTime) {
+ public void markFailure(ServiceCombServer server) {
try {
- serverStatsCache.get(server).markFailure(execTime);
+ serverStatsCache.get(server).markFailure();
} catch (ExecutionException e) {
LOGGER.error("Not expected to happen, maybe a bug.", e);
}
@@ -167,11 +167,10 @@ public class ServiceCombLoadBalancerStats {
while (instances.hasNext()) {
ServiceCombServer server = instances.next();
ServiceCombServerStats stats = allServers.get(server);
- long startTime = System.currentTimeMillis();
if ((System.currentTimeMillis() - stats.getLastVisitTime() > timerIntervalInMilis) && !ping
.ping(server.getInstance())) {
LOGGER.info("ping mark server {} failure.", server.getInstance().getInstanceId());
- stats.markFailure(System.currentTimeMillis() - startTime);
+ stats.markFailure();
}
}
serverStatsCache.cleanUp();
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
index 03b458e..b33771b 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
@@ -45,47 +45,33 @@ public class ServiceCombServerStats {
private boolean isolated = false;
- private long averageResponseTime = 0;
-
- public long getAverageResponseTime() {
- return averageResponseTime;
- }
-
public void markIsolated(boolean isolated) {
this.isolated = isolated;
}
- public void markSuccess(long execTime) {
+ public void markSuccess() {
long time = System.currentTimeMillis();
ensureWindow(time);
lastVisitTime = time;
lastActiveTime = time;
- updateAvgTime(execTime);
totalRequests.incrementAndGet();
successRequests.incrementAndGet();
continuousFailureCount.set(0);
}
- public void markFailure(long execTime) {
+ public void markFailure() {
long time = System.currentTimeMillis();
ensureWindow(time);
lastVisitTime = time;
// when isolated, do not update any failure statistics, or we can not recover from failure very quickly
if (!isolated) {
- updateAvgTime(execTime);
totalRequests.incrementAndGet();
failedRequests.incrementAndGet();
continuousFailureCount.incrementAndGet();
}
}
- private void updateAvgTime(long execTime) {
- // There maybe concurrent problems. But we do not care.
- long total = totalRequests.get();
- averageResponseTime = (averageResponseTime * total + execTime) / (total + 1);
- }
-
private void ensureWindow(long time) {
if (time - lastWindow > TIME_WINDOW_IN_MILLISECONDS) {
synchronized (lock) {
@@ -95,7 +81,6 @@ public class ServiceCombServerStats {
totalRequests.set(0);
successRequests.set(0);
failedRequests.set(0);
- averageResponseTime = 0;
}
lastWindow = time;
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
index 06aba4f..529c0a3 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
@@ -20,46 +20,84 @@ package org.apache.servicecomb.loadbalance;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import java.util.concurrent.atomic.AtomicInteger;
import org.apache.servicecomb.core.Invocation;
+import com.netflix.loadbalancer.ServerStats;
+
/**
* Rule based on response time.
*/
public class WeightedResponseTimeRuleExt extends RoundRobinRuleExt {
// 10ms
- private static final int MIN_GAP = 10;
+ private static final double MIN_GAP = 10d;
+
+ private static final int RANDOM_PERCENT = 10;
private Random random = new Random();
+ private LoadBalancer loadBalancer;
+
+ private double totalWeightsCache = 0d;
+
+ @Override
+ public void setLoadBalancer(LoadBalancer loadBalancer) {
+ this.loadBalancer = loadBalancer;
+ }
+
@Override
public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
- List<AtomicInteger> stats = new ArrayList<>(servers.size());
- int totalWeights = 0;
+ List<Double> stats = calculateTotalWeights(servers);
+
+ if (stats.size() > 0) {
+ double finalTotal = stats.get(stats.size() - 1);
+ List<Double> weights = new ArrayList<>(servers.size());
+ for (int i = 0; i < stats.size() - 1; i++) {
+ weights.add(finalTotal - stats.get(i));
+ }
+ double ran = random.nextDouble() * finalTotal * (servers.size() - 1);
+ for (int i = 0; i < weights.size(); i++) {
+ ran -= weights.get(i);
+ if (ran < 0) {
+ return servers.get(i);
+ }
+ }
+ return servers.get(servers.size() - 1);
+ }
+ return super.choose(servers, invocation);
+ }
+
+ private List<Double> calculateTotalWeights(List<ServiceCombServer> servers) {
+ if (totalWeightsCache > MIN_GAP * servers.size()) {
+ return doCalculateTotalWeights(servers);
+ }
+ // 10% possibilities to use weighed response rule when the normal access is very fast.
+ if (random.nextInt(RANDOM_PERCENT) == 0) {
+ return doCalculateTotalWeights(servers);
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ private List<Double> doCalculateTotalWeights(List<ServiceCombServer> servers) {
+ List<Double> stats = new ArrayList<>(servers.size() + 1);
+ double totalWeights = 0;
boolean needRandom = false;
for (ServiceCombServer server : servers) {
- ServiceCombServerStats serverStats = ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(server);
- int avgTime = (int) serverStats.getAverageResponseTime();
+ ServerStats serverStats = loadBalancer.getLoadBalancerStats().getSingleServerStat(server);
+ double avgTime = serverStats.getResponseTimeAvg();
if (!needRandom && avgTime > MIN_GAP) {
needRandom = true;
}
totalWeights += avgTime;
- stats.add(new AtomicInteger(avgTime));
+ stats.add(avgTime);
}
-
+ stats.add(totalWeights);
+ totalWeightsCache = totalWeights;
if (needRandom) {
- int finalTotal = totalWeights;
- stats.forEach(item -> item.set(finalTotal - item.get()));
- int ran = random
- .nextInt(Math.max(totalWeights * stats.size() - totalWeights, 1));
- for (int i = 0; i < stats.size(); i++) {
- ran -= stats.get(i).get();
- if (ran < 0) {
- return servers.get(i);
- }
- }
+ return stats;
+ } else {
+ return new ArrayList<>();
}
- return super.choose(servers, invocation);
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
index 3dbfa32..276e454 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
@@ -163,11 +163,11 @@ public class TestLoadBalanceHandler2 {
server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
//if errorThresholdPercentage is 0,that means errorThresholdPercentage is not active.
ArchaiusUtils.setProperty("servicecomb.loadbalance.isolation.errorThresholdPercentage", "0");
@@ -181,12 +181,12 @@ public class TestLoadBalanceHandler2 {
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server2, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server2);
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2);
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java
new file mode 100644
index 0000000..d80f17c
--- /dev/null
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.servicecomb.loadbalance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.core.Invocation;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class TestRoundRobinRuleExt {
+ @Test
+ public void testRoundRobin() {
+ RoundRobinRuleExt rule = new RoundRobinRuleExt();
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "testService");
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ for (int i = 0; i < 2; i++) {
+ ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+ Mockito.when(server.toString()).thenReturn("server " + i);
+ servers.add(server);
+ loadBalancer.getLoadBalancerStats().noteResponseTime(server, 1);
+ }
+
+ AtomicInteger server1 = new AtomicInteger(0);
+ AtomicInteger server2 = new AtomicInteger(0);
+ for (int i = 0; i < 2000; i++) {
+ if (rule.choose(servers, invocation).toString().equals("server 0")) {
+ server1.incrementAndGet();
+ } else {
+ server2.incrementAndGet();
+ }
+ }
+ Assert.assertEquals(server1.get(), server2.get());
+ }
+
+ @Test
+ public void testBenchmarkRobin() {
+ // less than 0.001ms
+ RoundRobinRuleExt rule = new RoundRobinRuleExt();
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "testService");
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ for (int i = 0; i < 100; i++) {
+ ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+ Mockito.when(server.toString()).thenReturn("server " + i);
+ servers.add(server);
+ loadBalancer.getLoadBalancerStats().noteResponseTime(server, 2);
+ }
+ long begin = System.currentTimeMillis();
+ for (int i = 0; i < 10000; i++) {
+ rule.choose(servers, invocation);
+ }
+ long taken = System.currentTimeMillis() - begin;
+ System.out.println("taken " + taken);
+ Assert.assertEquals(taken < 10 * 2, true); // 2 * times make slow machine happy
+ }
+}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
index 23352c8..fb88452 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
@@ -64,7 +64,7 @@ public class TestServiceCombLoadBalancerStats {
ServiceCombServer serviceCombServer = new ServiceCombServer(transport,
new CacheEndpoint("rest://localhost:8080", instance));
- serviceCombLoadBalancerStats.markSuccess(serviceCombServer, 0);
+ serviceCombLoadBalancerStats.markSuccess(serviceCombServer);
ServiceCombServerStats stats = serviceCombLoadBalancerStats.getServiceCombServerStats(serviceCombServer);
Assert.assertEquals(serviceCombLoadBalancerStats.getPingView().size(), 1);
await().atMost(5, TimeUnit.SECONDS)
@@ -83,16 +83,16 @@ public class TestServiceCombLoadBalancerStats {
instance.setInstanceId("instance1");
ServiceCombServer serviceCombServer = new ServiceCombServer(transport,
new CacheEndpoint("rest://localhost:8080", instance));
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
Assert.assertEquals(
ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getCountinuousFailureCount(),
2);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
Assert.assertEquals(
ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getCountinuousFailureCount(),
0);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
Assert
.assertEquals(
ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getTotalRequests(), 4);
@@ -119,10 +119,10 @@ public class TestServiceCombLoadBalancerStats {
for (int i = 0; i < 10; i++) {
new Thread() {
public void run() {
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
latch.countDown();
}
}.start();
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
index 3fda339..3010368 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
@@ -31,12 +31,12 @@ public class TestServiceCombServerStats {
public void testSimpleThread() {
long time = System.currentTimeMillis();
ServiceCombServerStats stats = new ServiceCombServerStats();
- stats.markFailure(0);
- stats.markFailure(0);
+ stats.markFailure();
+ stats.markFailure();
Assert.assertEquals(stats.getCountinuousFailureCount(), 2);
- stats.markSuccess(0);
+ stats.markSuccess();
Assert.assertEquals(stats.getCountinuousFailureCount(), 0);
- stats.markSuccess(0);
+ stats.markSuccess();
Assert.assertEquals(stats.getTotalRequests(), 4);
Assert.assertEquals(stats.getFailedRate(), 50);
Assert.assertEquals(stats.getSuccessRate(), 50);
@@ -52,10 +52,10 @@ public class TestServiceCombServerStats {
for (int i = 0; i < 10; i++) {
new Thread() {
public void run() {
- stats.markFailure(0);
- stats.markFailure(0);
- stats.markSuccess(0);
- stats.markSuccess(0);
+ stats.markFailure();
+ stats.markFailure();
+ stats.markSuccess();
+ stats.markSuccess();
latch.countDown();
}
}.start();
@@ -78,8 +78,8 @@ public class TestServiceCombServerStats {
};
ServiceCombServerStats stats = new ServiceCombServerStats();
Assert.assertEquals(stats.getLastVisitTime(), 1000);
- stats.markSuccess(0);
- stats.markFailure(0);
+ stats.markSuccess();
+ stats.markFailure();
Assert.assertEquals(stats.getTotalRequests(), 2);
Assert.assertEquals(stats.getFailedRate(), 50);
Assert.assertEquals(stats.getSuccessRate(), 50);
@@ -89,7 +89,7 @@ public class TestServiceCombServerStats {
return 60000 + 2000;
}
};
- stats.markSuccess(0);
+ stats.markSuccess();
Assert.assertEquals(stats.getTotalRequests(), 1);
Assert.assertEquals(stats.getFailedRate(), 0);
Assert.assertEquals(stats.getSuccessRate(), 100);
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java
new file mode 100644
index 0000000..54e1663
--- /dev/null
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.servicecomb.loadbalance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.core.Invocation;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class TestWeightedResponseTimeRuleExt {
+ @Test
+ public void testRoundRobin() {
+ WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "testService");
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ for (int i = 0; i < 2; i++) {
+ ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+ Mockito.when(server.toString()).thenReturn("server " + i);
+ servers.add(server);
+ loadBalancer.getLoadBalancerStats().noteResponseTime(server, 1);
+ }
+
+ AtomicInteger server1 = new AtomicInteger(0);
+ AtomicInteger server2 = new AtomicInteger(0);
+ for (int i = 0; i < 2000; i++) {
+ if (rule.choose(servers, invocation).toString().equals("server 0")) {
+ server1.incrementAndGet();
+ } else {
+ server2.incrementAndGet();
+ }
+ }
+ Assert.assertEquals(server1.get(), server2.get());
+ }
+
+ @Test
+ public void testWeighed() {
+ WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "testService");
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ for (int i = 0; i < 2; i++) {
+ ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+ Mockito.when(server.toString()).thenReturn("server " + i);
+ servers.add(server);
+ loadBalancer.getLoadBalancerStats().noteResponseTime(server, 20 * Math.pow(4, i + 1));
+ }
+
+ AtomicInteger server1 = new AtomicInteger(0);
+ AtomicInteger server2 = new AtomicInteger(0);
+ for (int i = 0; i < 2000; i++) {
+ if (rule.choose(servers, invocation).toString().equals("server 0")) {
+ server1.incrementAndGet();
+ } else {
+ server2.incrementAndGet();
+ }
+ }
+ double percent = (double) server1.get() / (server2.get() + server1.get());
+ System.out.println("percent" + percent);
+ Assert.assertEquals(0.70d < percent, percent < 0.90d);
+ }
+
+ @Test
+ public void testBenchmark() {
+ // 100 instances will taken less than 0.1ms. Because we use weighed rule when response time more than 10ms,
+ // This only taken 1/1000 time.
+ WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "testService");
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ for (int i = 0; i < 100; i++) {
+ ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+ Mockito.when(server.toString()).thenReturn("server " + i);
+ servers.add(server);
+ loadBalancer.getLoadBalancerStats().noteResponseTime(server, i);
+ }
+ long begin = System.currentTimeMillis();
+ for (int i = 0; i < 10000; i++) {
+ rule.choose(servers, invocation);
+ }
+ long taken = System.currentTimeMillis() - begin;
+ System.out.println("taken " + taken);
+ Assert.assertEquals(taken < 1000 * 2, true); // 2 * times make slow machine happy
+ }
+
+ @Test
+ public void testBenchmarkRobin() {
+ // 100 instances will taken less than 0.02ms. Not as good as RoundRobinRule, which taken less than 0.001ms
+ WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "testService");
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ for (int i = 0; i < 100; i++) {
+ ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+ Mockito.when(server.toString()).thenReturn("server " + i);
+ servers.add(server);
+ loadBalancer.getLoadBalancerStats().noteResponseTime(server, 2);
+ }
+ long begin = System.currentTimeMillis();
+ for (int i = 0; i < 10000; i++) {
+ rule.choose(servers, invocation);
+ }
+ long taken = System.currentTimeMillis() - begin;
+ System.out.println("taken " + taken);
+ Assert.assertEquals(taken < 200 * 2, true); // 2 * times make slow machine happy
+ }
+}
[incubator-servicecomb-java-chassis] 08/08: [SBC-870] make slow
machine happy
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit b9eed066509b4cf607b7c346ae9310d6e1d85c39
Author: liubao <ba...@huawei.com>
AuthorDate: Sat Aug 25 18:12:02 2018 +0800
[SBC-870] make slow machine happy
---
.../org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java | 2 +-
.../servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java
index d80f17c..ce78b50 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestRoundRobinRuleExt.java
@@ -71,6 +71,6 @@ public class TestRoundRobinRuleExt {
}
long taken = System.currentTimeMillis() - begin;
System.out.println("taken " + taken);
- Assert.assertEquals(taken < 10 * 2, true); // 2 * times make slow machine happy
+ Assert.assertEquals("actual token " + taken, taken < 10 * 5, true); // 5 * times make slow machine happy
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java
index 54e1663..0d4e003 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestWeightedResponseTimeRuleExt.java
@@ -76,7 +76,7 @@ public class TestWeightedResponseTimeRuleExt {
}
double percent = (double) server1.get() / (server2.get() + server1.get());
System.out.println("percent" + percent);
- Assert.assertEquals(0.70d < percent, percent < 0.90d);
+ Assert.assertEquals("actually percent: " + percent, 0.70d < percent, percent < 0.90d);
}
@Test
@@ -99,7 +99,7 @@ public class TestWeightedResponseTimeRuleExt {
}
long taken = System.currentTimeMillis() - begin;
System.out.println("taken " + taken);
- Assert.assertEquals(taken < 1000 * 2, true); // 2 * times make slow machine happy
+ Assert.assertEquals("actually taken: " + taken, taken < 1000 * 5, true); // 5 * times make slow machine happy
}
@Test
@@ -121,6 +121,6 @@ public class TestWeightedResponseTimeRuleExt {
}
long taken = System.currentTimeMillis() - begin;
System.out.println("taken " + taken);
- Assert.assertEquals(taken < 200 * 2, true); // 2 * times make slow machine happy
+ Assert.assertEquals("actually taken: " + taken, taken < 200 * 2, true); // 5 * times make slow machine happy
}
}
[incubator-servicecomb-java-chassis] 01/08: [SBC-870]refractor to
using custom RuleExt, not using Robin IRule.
Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 1878b4b3d0b79963e6892592be0ce32fa537da78
Author: liubao <ba...@huawei.com>
AuthorDate: Fri Aug 24 21:40:40 2018 +0800
[SBC-870]refractor to using custom RuleExt, not using Robin IRule.
---
.../common/rest/codec/RestObjectMapper.java | 2 +
.../jaxrs/client/CodeFirstRestTemplateJaxrs.java | 2 +-
.../client/CustomLoadbalanceExtensionsFactory.java | 6 +-
.../src/main/resources/microservice.yaml | 4 +-
.../demo/springmvc/client/SpringmvcClient.java | 12 ++
.../src/main/resources/microservice.yaml | 3 +-
.../servicecomb/loadbalance/Configuration.java | 10 --
.../servicecomb/loadbalance/ExtensionsFactory.java | 2 +-
.../servicecomb/loadbalance/ExtensionsManager.java | 14 +-
.../servicecomb/loadbalance/LoadBalancer.java | 78 +++-------
.../loadbalance/LoadBalancerCreator.java | 44 +-----
.../loadbalance/LoadbalanceHandler.java | 48 +++----
.../servicecomb/loadbalance/RandomRuleExt.java} | 20 +--
.../loadbalance/RoundRobinRuleExt.java} | 20 +--
.../RuleClassNameExtentionsFactory.java | 62 --------
.../apache/servicecomb/loadbalance/RuleExt.java} | 17 +--
.../loadbalance/RuleNameExtentionsFactory.java | 12 +-
.../loadbalance/ServerListFilterExt.java | 12 +-
.../loadbalance/ServiceCombLoadBalancerStats.java | 23 ++-
.../servicecomb/loadbalance/ServiceCombServer.java | 16 +++
.../loadbalance/ServiceCombServerStats.java | 19 ++-
.../loadbalance/SessionStickinessRule.java | 70 ++++-----
.../loadbalance/WeightedResponseTimeRuleExt.java | 65 +++++++++
.../loadbalance/MyServerListFilterExt.java | 2 +-
.../servicecomb/loadbalance/TestConfiguration.java | 2 -
.../loadbalance/TestExtensionsManager.java | 31 +---
.../loadbalance/TestLoadBalanceCreator.java | 159 ++++++++++++---------
.../loadbalance/TestLoadBalanceHandler2.java | 38 ++---
.../servicecomb/loadbalance/TestLoadBalancer.java | 110 ++------------
.../loadbalance/TestLoadbalanceHandler.java | 3 +-
.../TestServiceCombLoadBalancerStats.java | 20 +--
.../loadbalance/TestServiceCombServerStats.java | 22 +--
.../loadbalance/TestSessionSticknessRule.java | 91 ++++++------
.../filter/TestServerDiscoveryFilter.java | 1 +
.../swagger/engine/SwaggerProducerOperation.java | 8 ++
35 files changed, 455 insertions(+), 593 deletions(-)
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
index f94ec2c..327175b 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
@@ -65,6 +65,8 @@ public class RestObjectMapper extends AbstractRestObjectMapper {
disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
+ // If required=true, need to fail, while required=false, default values is given.
+ enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
SimpleModule module = new SimpleModule();
// custom types
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
index 38ae6e9..2481e52 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
@@ -110,7 +110,7 @@ public class CodeFirstRestTemplateJaxrs extends CodeFirstRestTemplate {
private void test404(RestTemplate template) {
HttpClientErrorException exception = null;
try {
- template.getForEntity("http://127.0.0.1:8080/aPathNotExist", String.class);
+ template.getForEntity("http://127.0.0.1:8086/aPathNotExist", String.class);
} catch (RestClientException e) {
if (e instanceof HttpClientErrorException) {
exception = (HttpClientErrorException) e;
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java
index cb0eef6..c015165 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java
@@ -18,6 +18,8 @@ package org.apache.servicecomb.demo.jaxrs.client;
import org.apache.servicecomb.loadbalance.Configuration;
import org.apache.servicecomb.loadbalance.ExtensionsFactory;
+import org.apache.servicecomb.loadbalance.RoundRobinRuleExt;
+import org.apache.servicecomb.loadbalance.RuleExt;
import org.springframework.stereotype.Component;
import com.netflix.client.DefaultLoadBalancerRetryHandler;
@@ -29,7 +31,7 @@ import com.netflix.loadbalancer.RoundRobinRule;
@Component
public class CustomLoadbalanceExtensionsFactory implements ExtensionsFactory {
- class MyCustomRule extends RoundRobinRule {
+ class MyCustomRule extends RoundRobinRuleExt {
}
@@ -56,7 +58,7 @@ public class CustomLoadbalanceExtensionsFactory implements ExtensionsFactory {
}
@Override
- public IRule createLoadBalancerRule(String ruleName) {
+ public RuleExt createLoadBalancerRule(String ruleName) {
return new MyCustomRule();
}
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
index 89f324c..c4bbcdd 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
@@ -24,9 +24,9 @@ servicecomb:
registry:
address: http://127.0.0.1:30100
rest:
- address: 0.0.0.0:8080
+ address: 0.0.0.0:8086
highway:
- address: 0.0.0.0:7070
+ address: 0.0.0.0:7076
handler:
chain:
Provider:
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index 3e5aa1c..2a41e0a 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -167,6 +167,18 @@ public class SpringmvcClient {
private static void testController(RestTemplate template, String microserviceName) {
String prefix = "cse://" + microserviceName;
+ TestMgr.check(7,
+ template.getForObject(prefix + "/controller/add?a=3&b=4",
+ Integer.class));
+
+ try {
+ template.getForObject(prefix + "/controller/add",
+ Integer.class);
+ TestMgr.check("failed", "success");
+ } catch (InvocationException e) {
+ TestMgr.check(e.getStatusCode(), 400);
+ }
+
TestMgr.check("hi world [world]",
template.getForObject(prefix + "/controller/sayhi?name=world",
String.class));
diff --git a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
index 2290b6f..03b137c 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
+++ b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
@@ -56,7 +56,8 @@ servicecomb:
enabled: true
samplingRate: 0.5
loadbalance:
- NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
+ strategy:
+ name: WeightedResponse
retryEnabled: true
retryOnSame: 1
retryOnNext: 1
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
index f2f8f62..2268855 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java
@@ -35,8 +35,6 @@ public final class Configuration {
public static final String RPOP_TIMER_INTERVAL_IN_MINIS = "servicecomb.loadbalance.stats.timerIntervalInMilis";
- public static final String PROP_POLICY = "NFLoadBalancerRuleClassName";
-
public static final String PROP_RULE_STRATEGY_NAME = "strategy.name";
// 2.0 configuration items
@@ -91,14 +89,6 @@ public final class Configuration {
private Configuration() {
}
- public String getPolicy(String microservice) {
- return getStringProperty(null,
- PROP_ROOT + microservice + "." + PROP_POLICY,
- PROP_ROOT_20 + microservice + "." + PROP_POLICY,
- PROP_ROOT + PROP_POLICY,
- PROP_ROOT_20 + PROP_POLICY);
- }
-
public String getRuleStrategyName(String microservice) {
return getStringProperty(null,
PROP_ROOT + microservice + "." + PROP_RULE_STRATEGY_NAME,
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java
index fa97372..9077575 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsFactory.java
@@ -25,7 +25,7 @@ import com.netflix.loadbalancer.IRule;
public interface ExtensionsFactory {
boolean isSupport(String key, String value);
- default IRule createLoadBalancerRule(String ruleName) {
+ default RuleExt createLoadBalancerRule(String ruleName) {
return null;
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java
index 15edefe..2df0395 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ExtensionsManager.java
@@ -23,8 +23,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.client.RetryHandler;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.RoundRobinRule;
public class ExtensionsManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionsManager.class);
@@ -35,15 +33,11 @@ public class ExtensionsManager {
extentionFactories.add(factory);
}
- public static IRule createLoadBalancerRule(String microservice) {
- IRule rule = null;
+ public static RuleExt createLoadBalancerRule(String microservice) {
+ RuleExt rule = null;
for (ExtensionsFactory factory : extentionFactories) {
- if (factory.isSupport(Configuration.PROP_POLICY, Configuration.INSTANCE.getPolicy(microservice))) {
- rule = factory.createLoadBalancerRule(
- Configuration.INSTANCE.getPolicy(microservice));
- break;
- } else if (factory.isSupport(Configuration.PROP_RULE_STRATEGY_NAME,
+ if (factory.isSupport(Configuration.PROP_RULE_STRATEGY_NAME,
Configuration.INSTANCE.getRuleStrategyName(microservice))) {
rule = factory.createLoadBalancerRule(
Configuration.INSTANCE.getRuleStrategyName(microservice));
@@ -52,7 +46,7 @@ public class ExtensionsManager {
}
if (rule == null) {
- rule = new RoundRobinRule();
+ rule = new RoundRobinRuleExt();
}
LOGGER.info("Using load balance rule {} for microservice {}.", rule.getClass().getName(), microservice);
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
index 56db6ff..3a96b59 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancer.java
@@ -17,83 +17,45 @@
package org.apache.servicecomb.loadbalance;
-import java.util.Collections;
import java.util.List;
-import com.netflix.loadbalancer.AbstractLoadBalancer;
-import com.netflix.loadbalancer.IRule;
+import org.apache.servicecomb.core.Invocation;
+
import com.netflix.loadbalancer.LoadBalancerStats;
-import com.netflix.loadbalancer.Server;
/**
- * Robbin LoadBalancer implementation. Only support IRule and basic operations.
+ * A load balancer with RuleExt and ServerListFilterExt
*/
-public class LoadBalancer extends AbstractLoadBalancer {
- private List<Server> serverList = Collections.emptyList();
-
- private IRule rule;
+public class LoadBalancer {
+ private RuleExt rule;
private LoadBalancerStats lbStats;
private String microServiceName;
- public LoadBalancer(IRule rule, String microServiceName,
- LoadBalancerStats stats) {
+ private List<ServerListFilterExt> filters;
+
+ private List<ServiceCombServer> servers;
+
+ public LoadBalancer(RuleExt rule, String microServiceName,
+ LoadBalancerStats stats, List<ServerListFilterExt> filters, List<ServiceCombServer> servers) {
this.microServiceName = microServiceName;
this.rule = rule;
this.lbStats = stats;
- }
-
- public void setServerList(List<Server> serverList) {
- this.serverList = Collections.unmodifiableList(serverList);
- }
-
- @Override
- public void addServers(List<Server> newServers) {
- throw new UnsupportedOperationException("Not implemented.");
- }
-
- @Override
- public Server chooseServer(Object key) {
- // rule is shared across loadbalancers, so it will get concurrent access problems that it's owned loadbalancer is
- // not 'this', but this is fine to use other loadbalancer instances only when serverList is correctly set
+ this.filters = filters;
+ this.servers = servers;
this.rule.setLoadBalancer(this);
- return rule.choose(key);
- }
-
- @Override
- public void markServerDown(Server server) {
- throw new UnsupportedOperationException("Not implemented.");
- }
-
- @Override
- @Deprecated
- public List<Server> getServerList(boolean availableOnly) {
- return getAllServers();
- }
-
- @Override
- public List<Server> getReachableServers() {
- return getAllServers();
- }
-
- @Override
- // Different types of Robin Component Rule have different usages for server status and list.
- // e.g. RoundRobinRule using getAllServers & alive & readyToServe
- // RandomRule using getReachableServers & alive
- // WeightedResponseTimeRule using getAllServers & alive
- // To make all rules work only on "how to choose a server from alive servers", we do not rely on Robbin getReachableServers.
- // We ensure getReachableServers & getAllServers work in the same way.
- public List<Server> getAllServers() {
- return serverList;
+ this.filters.forEach((item) -> item.setLoadBalancer(this));
}
- @Override
- public List<Server> getServerList(ServerGroup serverGroup) {
- throw new UnsupportedOperationException("Not implemented.");
+ public ServiceCombServer chooseServer(Invocation invocation) {
+ List<ServiceCombServer> temp = this.servers;
+ for (ServerListFilterExt filterExt : filters) {
+ temp = filterExt.getFilteredListOfServers(temp, invocation);
+ }
+ return rule.choose(temp, invocation);
}
- @Override
public LoadBalancerStats getLoadBalancerStats() {
return lbStats;
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
index eedbb9c..5cb18dc 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadBalancerCreator.java
@@ -17,19 +17,12 @@
package org.apache.servicecomb.loadbalance;
-import java.util.Collections;
import java.util.List;
-import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
-import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.LoadBalancerStats;
-import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.WeightedResponseTimeRule;
/**
* Create a suitable load balancer for each invocation.
@@ -45,11 +38,7 @@ import com.netflix.loadbalancer.WeightedResponseTimeRule;
* on the result of ServerListFilter, they should not contain operation level state information in instance fields.
*/
public class LoadBalancerCreator {
- private static final Logger LOGGER = LoggerFactory.getLogger(LoadBalancerCreator.class);
-
- private List<Server> serverList = Collections.emptyList();
-
- private IRule rule;
+ private RuleExt rule;
private LoadBalancerStats lbStats;
@@ -57,7 +46,7 @@ public class LoadBalancerCreator {
private String microServiceName;
- public LoadBalancerCreator(IRule rule, String microServiceName) {
+ public LoadBalancerCreator(RuleExt rule, String microServiceName) {
this.rule = rule;
this.microServiceName = microServiceName;
this.lbStats = new LoadBalancerStats(null);
@@ -66,20 +55,7 @@ public class LoadBalancerCreator {
}
public void shutdown() {
- // netflix components does not have a proper way to shutdown laodbalancers so we do it in a not quite elegant way.
- if (this.rule instanceof WeightedResponseTimeRule) {
- ((WeightedResponseTimeRule) this.rule).shutdown();
- }
- }
-
- // every filter group has a loadBalancer instance
- // serverList almost not changed for different invocation
- // so every invocation will call setServerList, this is no problem
- public void setServerList(List<Server> serverList) {
- if (serverList.isEmpty()) {
- LOGGER.warn("Set empty server list.");
- }
- this.serverList = Collections.unmodifiableList(serverList);
+ // nothing to do now
}
@VisibleForTesting
@@ -87,17 +63,7 @@ public class LoadBalancerCreator {
this.filters = filters;
}
- public LoadBalancer createLoadBalancer(Invocation invocation) {
- LoadBalancer loadBalancer = new LoadBalancer(rule, microServiceName, lbStats);
- List<Server> servers = this.serverList;
- for (ServerListFilterExt filter : this.filters) {
- filter.setLoadBalancer(loadBalancer);
- servers = filter.getFilteredListOfServers(servers, invocation);
- if (servers.isEmpty()) {
- LOGGER.warn("Filter {} get empty list.", filter.getClass().getName());
- }
- }
- loadBalancer.setServerList(servers);
- return loadBalancer;
+ public LoadBalancer createLoadBalancer(List<ServiceCombServer> servers) {
+ return new LoadBalancer(rule, microServiceName, lbStats, filters, servers);
}
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
index 7d6394a..06f4b10 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/LoadbalanceHandler.java
@@ -45,7 +45,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.loadbalancer.ILoadBalancer;
-import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.reactive.ExecutionContext;
import com.netflix.loadbalancer.reactive.ExecutionInfo;
@@ -56,8 +55,7 @@ import com.netflix.loadbalancer.reactive.ServerOperation;
import rx.Observable;
/**
- * 负载均衡处理链
- *
+ * Load balance handler.
*/
public class LoadbalanceHandler implements Handler {
// just a wrapper to make sure in retry mode to choose a different server.
@@ -67,21 +65,23 @@ public class LoadbalanceHandler implements Handler {
Server lastServer = null;
- ILoadBalancer delegate;
+ LoadBalancer delegate;
+
+ Invocation invocation;
- RetryLoadBalancer(ILoadBalancer delegate) {
+ RetryLoadBalancer(LoadBalancer delegate, Invocation invocation) {
this.delegate = delegate;
}
@Override
public void addServers(List<Server> newServers) {
- delegate.addServers(newServers);
+ throw new UnsupportedOperationException("Not implemented.");
}
@Override
public Server chooseServer(Object key) {
for (int i = 0; i < COUNT; i++) {
- Server s = delegate.chooseServer(key);
+ Server s = delegate.chooseServer(invocation);
if (s != null && !s.equals(lastServer)) {
lastServer = s;
break;
@@ -94,23 +94,23 @@ public class LoadbalanceHandler implements Handler {
@Override
public void markServerDown(Server server) {
- delegate.markServerDown(server);
+ throw new UnsupportedOperationException("Not implemented.");
}
@Override
@Deprecated
public List<Server> getServerList(boolean availableOnly) {
- return delegate.getServerList(availableOnly);
+ throw new UnsupportedOperationException("Not implemented.");
}
@Override
public List<Server> getReachableServers() {
- return delegate.getReachableServers();
+ throw new UnsupportedOperationException("Not implemented.");
}
@Override
public List<Server> getAllServers() {
- return delegate.getAllServers();
+ throw new UnsupportedOperationException("Not implemented.");
}
}
@@ -135,8 +135,6 @@ public class LoadbalanceHandler implements Handler {
private final Object lock = new Object();
- private String policy = null;
-
private String strategy = null;
@@ -148,16 +146,13 @@ public class LoadbalanceHandler implements Handler {
@Override
public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
- String policy = Configuration.INSTANCE.getPolicy(invocation.getMicroserviceName());
String strategy = Configuration.INSTANCE.getRuleStrategyName(invocation.getMicroserviceName());
- boolean isRuleNotChanged = isEqual(policy, this.policy) && isEqual(strategy, this.strategy);
- if (!isRuleNotChanged) {
+ if (!isEqual(strategy, this.strategy)) {
//配置变化,需要重新生成所有的lb实例
synchronized (lock) {
clearLoadBalancer();
}
}
- this.policy = policy;
this.strategy = strategy;
LoadBalancer loadBalancer = getOrCreateLoadBalancer(invocation);
@@ -199,10 +194,10 @@ public class LoadbalanceHandler implements Handler {
chosenLB.getLoadBalancerStats().noteResponseTime(server, (System.currentTimeMillis() - time));
if (isFailedResponse(resp)) {
chosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(server);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, System.currentTimeMillis() - time);
} else {
chosenLB.getLoadBalancerStats().incrementActiveRequestsCount(server);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, (System.currentTimeMillis() - time));
}
asyncResp.handle(resp);
});
@@ -287,7 +282,7 @@ public class LoadbalanceHandler implements Handler {
ExecutionContext<Invocation> context = new ExecutionContext<>(invocation, null, null, null);
LoadBalancerCommand<Response> command = LoadBalancerCommand.<Response>builder()
- .withLoadBalancer(new RetryLoadBalancer(chosenLB))
+ .withLoadBalancer(new RetryLoadBalancer(chosenLB, invocation))
.withServerLocator(invocation)
.withRetryHandler(ExtensionsManager.createRetryHandler(invocation.getMicroserviceName()))
.withListeners(listeners)
@@ -309,13 +304,13 @@ public class LoadbalanceHandler implements Handler {
((Throwable) resp.getResult()).getMessage(),
s);
chosenLB.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, System.currentTimeMillis() - time);
f.onError(resp.getResult());
} else {
chosenLB.getLoadBalancerStats().incrementActiveRequestsCount(s);
chosenLB.getLoadBalancerStats().noteResponseTime(s,
(System.currentTimeMillis() - time));
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, (System.currentTimeMillis() - time));
f.onNext(resp);
f.onCompleted();
}
@@ -359,15 +354,16 @@ public class LoadbalanceHandler implements Handler {
LoadBalancerCreator loadBalancerCreator = loadBalancerMap.computeIfAbsent(serversVersionedCache.name(), name -> {
return createLoadBalancerCreator(invocation.getMicroserviceName());
});
- loadBalancerCreator.setServerList(serversVersionedCache.data());
- // help users to deal with incompatible changes.
+
+ // Nothing to do just help users to deal with incompatible changes.
setTransactionControlFilter(invocation.getMicroserviceName());
loadServerListFilters();
- return loadBalancerCreator.createLoadBalancer(invocation);
+
+ return loadBalancerCreator.createLoadBalancer(serversVersionedCache.data());
}
private LoadBalancerCreator createLoadBalancerCreator(String microserviceName) {
- IRule rule = ExtensionsManager.createLoadBalancerRule(microserviceName);
+ RuleExt rule = ExtensionsManager.createLoadBalancerRule(microserviceName);
LoadBalancerCreator creator = new LoadBalancerCreator(rule, microserviceName);
return creator;
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
similarity index 72%
copy from handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
copy to handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
index ed08789..60eedac 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java
@@ -17,23 +17,23 @@
package org.apache.servicecomb.loadbalance;
-import java.util.ArrayList;
import java.util.List;
+import java.util.Random;
import org.apache.servicecomb.core.Invocation;
-import com.netflix.loadbalancer.Server;
-
/**
- * @author l00168639
- *
+ * A random rule.
*/
-public class MyServerListFilterExt implements ServerListFilterExt {
+public class RandomRuleExt implements RuleExt {
+ private Random random = new Random();
+
@Override
- public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
- if (invocation.getAppId().equals("test")) {
- return new ArrayList<>();
+ public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
+ if (servers.size() == 0) {
+ return null;
}
- return serverList;
+ int index = Math.abs(random.nextInt()) % servers.size();
+ return servers.get(index);
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
similarity index 69%
copy from handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
copy to handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
index ed08789..c3a887d 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RoundRobinRuleExt.java
@@ -17,23 +17,23 @@
package org.apache.servicecomb.loadbalance;
-import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
import org.apache.servicecomb.core.Invocation;
-import com.netflix.loadbalancer.Server;
-
/**
- * @author l00168639
- *
+ * A round robin rule
*/
-public class MyServerListFilterExt implements ServerListFilterExt {
+public class RoundRobinRuleExt implements RuleExt {
+ private AtomicInteger counter = new AtomicInteger(0);
+
@Override
- public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
- if (invocation.getAppId().equals("test")) {
- return new ArrayList<>();
+ public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
+ if (servers.size() == 0) {
+ return null;
}
- return serverList;
+ int index = Math.abs(counter.getAndIncrement()) % servers.size();
+ return servers.get(index);
}
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
deleted file mode 100644
index b6df5ef..0000000
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleClassNameExtentionsFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 org.apache.servicecomb.loadbalance;
-
-import java.util.Collection;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.servicecomb.foundation.common.utils.JvmUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import com.google.common.collect.Lists;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.RoundRobinRule;
-
-/**
- * 兼容老版本的Rule相关的配置项
- */
-@Component
-public class RuleClassNameExtentionsFactory implements ExtensionsFactory {
- private static final Logger LOGGER = LoggerFactory.getLogger(RuleClassNameExtentionsFactory.class);
-
- private static final Collection<String> ACCEPT_KEYS = Lists.newArrayList(
- Configuration.PROP_POLICY);
-
- // possible values
- // "com.netflix.loadbalancer.RoundRobinRule"
- // "com.netflix.loadbalancer.WeightedResponseTimeRule"
- // "com.netflix.loadbalancer.RandomRule"
- // "org.apache.servicecomb.loadbalance.SessionStickinessRule"
- @Override
- public boolean isSupport(String key, String value) {
- return ACCEPT_KEYS.contains(key) && StringUtils.isNotEmpty(value);
- }
-
- @Override
- public IRule createLoadBalancerRule(String ruleName) {
- IRule rule;
- try {
- rule = (IRule) Class.forName(ruleName, true, JvmUtils.findClassLoader()).newInstance();
- } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
- LOGGER.warn("Loadbalance rule [{}] is incorrect, using default RoundRobinRule.", ruleName);
- rule = new RoundRobinRule();
- }
- return rule;
- }
-}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
similarity index 71%
copy from handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
copy to handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
index ed08789..a95ccbc 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleExt.java
@@ -17,23 +17,16 @@
package org.apache.servicecomb.loadbalance;
-import java.util.ArrayList;
import java.util.List;
import org.apache.servicecomb.core.Invocation;
-import com.netflix.loadbalancer.Server;
-
/**
- * @author l00168639
- *
+ * Load balance rule to support invocation based filters.
*/
-public class MyServerListFilterExt implements ServerListFilterExt {
- @Override
- public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
- if (invocation.getAppId().equals("test")) {
- return new ArrayList<>();
- }
- return serverList;
+public interface RuleExt {
+ default void setLoadBalancer(LoadBalancer loadBalancer) {
}
+
+ ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation);
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java
index 92d5be2..5ab7cfb 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RuleNameExtentionsFactory.java
@@ -21,10 +21,6 @@ import java.util.Collection;
import org.springframework.stereotype.Component;
import com.google.common.collect.Lists;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.RandomRule;
-import com.netflix.loadbalancer.RoundRobinRule;
-import com.netflix.loadbalancer.WeightedResponseTimeRule;
@Component
public class RuleNameExtentionsFactory implements ExtensionsFactory {
@@ -51,13 +47,13 @@ public class RuleNameExtentionsFactory implements ExtensionsFactory {
}
@Override
- public IRule createLoadBalancerRule(String ruleName) {
+ public RuleExt createLoadBalancerRule(String ruleName) {
if (RULE_RoundRobin.equals(ruleName)) {
- return new RoundRobinRule();
+ return new RoundRobinRuleExt();
} else if (RULE_Random.equals(ruleName)) {
- return new RandomRule();
+ return new RandomRuleExt();
} else if (RULE_WeightedResponse.equals(ruleName)) {
- return new WeightedResponseTimeRule();
+ return new WeightedResponseTimeRuleExt();
} else if (RULE_SessionStickiness.equals(ruleName)) {
return new SessionStickinessRule();
} else {
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java
index 7695a68..9dba004 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServerListFilterExt.java
@@ -21,27 +21,23 @@ import java.util.List;
import org.apache.servicecomb.core.Invocation;
-import com.netflix.loadbalancer.Server;
-
/**
* Base interface for server list filters.
*
- * LoadBalancer.getAllServers ServerListFilterExt.getFilteredListOfServers IRule.choose
- *
* Robin ServerListFilter can not support invocation based filter strategies, so we create a new one to
* support this.
*/
public interface ServerListFilterExt {
- public default int getOrder() {
+ default int getOrder() {
return 0;
}
- public default boolean enabled() {
+ default boolean enabled() {
return true;
}
- public default void setLoadBalancer(LoadBalancer loadBalancer) {
+ default void setLoadBalancer(LoadBalancer loadBalancer) {
}
- public List<Server> getFilteredListOfServers(List<Server> servers, Invocation invocation);
+ List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> servers, Invocation invocation);
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
index 1b7be1d..ac01152 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombLoadBalancerStats.java
@@ -57,6 +57,8 @@ public class ServiceCombLoadBalancerStats {
public static final ServiceCombLoadBalancerStats INSTANCE;
+ private Timer timer;
+
static {
INSTANCE = new ServiceCombLoadBalancerStats();
INSTANCE.init();
@@ -76,17 +78,17 @@ public class ServiceCombLoadBalancerStats {
}
}
- public void markSuccess(ServiceCombServer server) {
+ public void markSuccess(ServiceCombServer server, long execTime) {
try {
- serverStatsCache.get(server).markSuccess();
+ serverStatsCache.get(server).markSuccess(execTime);
} catch (ExecutionException e) {
LOGGER.error("Not expected to happen, maybe a bug.", e);
}
}
- public void markFailure(ServiceCombServer server) {
+ public void markFailure(ServiceCombServer server, long execTime) {
try {
- serverStatsCache.get(server).markFailure();
+ serverStatsCache.get(server).markFailure(execTime);
} catch (ExecutionException e) {
LOGGER.error("Not expected to happen, maybe a bug.", e);
}
@@ -126,6 +128,14 @@ public class ServiceCombLoadBalancerStats {
}
void init() {
+ // for testing
+ if (timer != null) {
+ timer.cancel();
+ }
+ if (serverStatsCache != null) {
+ serverStatsCache.cleanUp();
+ }
+
serverStatsCache =
CacheBuilder.newBuilder()
.expireAfterAccess(serverExpireInSeconds, TimeUnit.SECONDS)
@@ -145,7 +155,7 @@ public class ServiceCombLoadBalancerStats {
}
});
- Timer timer = new Timer("LoadBalancerStatsTimer", true);
+ timer = new Timer("LoadBalancerStatsTimer", true);
timer.schedule(new TimerTask() {
private MicroserviceInstancePing ping = SPIServiceUtils.getPriorityHighestService(MicroserviceInstancePing.class);
@@ -157,10 +167,11 @@ public class ServiceCombLoadBalancerStats {
while (instances.hasNext()) {
ServiceCombServer server = instances.next();
ServiceCombServerStats stats = allServers.get(server);
+ long startTime = System.currentTimeMillis();
if ((System.currentTimeMillis() - stats.getLastVisitTime() > timerIntervalInMilis) && !ping
.ping(server.getInstance())) {
LOGGER.info("ping mark server {} failure.", server.getInstance().getInstanceId());
- stats.markFailure();
+ stats.markFailure(System.currentTimeMillis() - startTime);
}
}
serverStatsCache.cleanUp();
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
index 1d4edf3..800e2ae 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServer.java
@@ -22,6 +22,7 @@ import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
import org.apache.servicecomb.serviceregistry.cache.CacheEndpoint;
+import com.google.common.annotations.VisibleForTesting;
import com.netflix.loadbalancer.Server;
/**
@@ -35,6 +36,21 @@ public class ServiceCombServer extends Server {
// 所属服务实例
private final MicroserviceInstance instance;
+ @VisibleForTesting
+ ServiceCombServer(Endpoint endpoint, MicroserviceInstance instance) {
+ super(null);
+ this.endpoint = endpoint;
+ this.instance = instance;
+
+ // Different types of Robin Component Rule have different usages for server status and list.
+ // e.g. RoundRobinRule using getAllServers & alive & readyToServe
+ // RandomRule using getReachableServers & alive
+ // WeightedResponseTimeRule using getAllServers & alive
+ // To make all rules work only on "how to choose a server from alive servers", we do not rely on Robbin defined status
+ this.setAlive(true);
+ this.setReadyToServe(true);
+ }
+
public ServiceCombServer(Transport transport, CacheEndpoint cacheEndpoint) {
super(null);
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
index b33771b..03b458e 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/ServiceCombServerStats.java
@@ -45,33 +45,47 @@ public class ServiceCombServerStats {
private boolean isolated = false;
+ private long averageResponseTime = 0;
+
+ public long getAverageResponseTime() {
+ return averageResponseTime;
+ }
+
public void markIsolated(boolean isolated) {
this.isolated = isolated;
}
- public void markSuccess() {
+ public void markSuccess(long execTime) {
long time = System.currentTimeMillis();
ensureWindow(time);
lastVisitTime = time;
lastActiveTime = time;
+ updateAvgTime(execTime);
totalRequests.incrementAndGet();
successRequests.incrementAndGet();
continuousFailureCount.set(0);
}
- public void markFailure() {
+ public void markFailure(long execTime) {
long time = System.currentTimeMillis();
ensureWindow(time);
lastVisitTime = time;
// when isolated, do not update any failure statistics, or we can not recover from failure very quickly
if (!isolated) {
+ updateAvgTime(execTime);
totalRequests.incrementAndGet();
failedRequests.incrementAndGet();
continuousFailureCount.incrementAndGet();
}
}
+ private void updateAvgTime(long execTime) {
+ // There maybe concurrent problems. But we do not care.
+ long total = totalRequests.get();
+ averageResponseTime = (averageResponseTime * total + execTime) / (total + 1);
+ }
+
private void ensureWindow(long time) {
if (time - lastWindow > TIME_WINDOW_IN_MILLISECONDS) {
synchronized (lock) {
@@ -81,6 +95,7 @@ public class ServiceCombServerStats {
totalRequests.set(0);
successRequests.set(0);
failedRequests.set(0);
+ averageResponseTime = 0;
}
lastWindow = time;
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java
index d589b4d..a489860 100644
--- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java
@@ -17,15 +17,13 @@
package org.apache.servicecomb.loadbalance;
+import java.util.List;
+
+import org.apache.servicecomb.core.Invocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.netflix.loadbalancer.AbstractLoadBalancer;
-import com.netflix.loadbalancer.ILoadBalancer;
-import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.LoadBalancerStats;
-import com.netflix.loadbalancer.RoundRobinRule;
-import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerStats;
/**
@@ -33,17 +31,17 @@ import com.netflix.loadbalancer.ServerStats;
* 提供当会话过期或者失败次数超过限制后,轮询选择其他服务器的能力。
*
*/
-public class SessionStickinessRule implements IRule {
+public class SessionStickinessRule implements RuleExt {
private static final Logger LOG = LoggerFactory.getLogger(SessionStickinessRule.class);
private final Object lock = new Object();
- private ILoadBalancer lb;
+ private LoadBalancer loadBalancer;
// use random rule as the trigger rule, to prevent consumer instance select the same producer instance.
- private IRule triggerRule;
+ private RuleExt triggerRule;
- private volatile Server lastServer = null;
+ private volatile ServiceCombServer lastServer = null;
private long lastAccessedTime = 0;
@@ -54,39 +52,41 @@ public class SessionStickinessRule implements IRule {
private String microserviceName;
public SessionStickinessRule() {
- triggerRule = new RoundRobinRule();
+ triggerRule = new RoundRobinRuleExt();
+ }
+
+ public void setLoadBalancer(LoadBalancer loadBalancer) {
+ this.loadBalancer = loadBalancer;
}
- private Server chooseNextServer(Object key) {
- AbstractLoadBalancer lb = (AbstractLoadBalancer) getLoadBalancer();
- triggerRule.setLoadBalancer(lb);
- lastServer = triggerRule.choose(key);
+ private ServiceCombServer chooseNextServer(List<ServiceCombServer> servers, Invocation invocation) {
+ lastServer = triggerRule.choose(servers, invocation);
lastAccessedTime = System.currentTimeMillis();
return lastServer;
}
- private Server chooseInitialServer(Object key) {
+ private ServiceCombServer chooseInitialServer(List<ServiceCombServer> servers, Invocation invocation) {
synchronized (lock) {
if (lastServer == null) {
- chooseNextServer(key);
+ chooseNextServer(servers, invocation);
}
}
return lastServer;
}
- private Server chooseServerWhenTimeout(Object key) {
+ private ServiceCombServer chooseServerWhenTimeout(List<ServiceCombServer> servers, Invocation invocation) {
synchronized (lock) {
if (isTimeOut()) {
- chooseNextServer(key);
+ chooseNextServer(servers, invocation);
}
}
return lastServer;
}
- private Server chooseServerErrorThresholdMet(Object key) {
+ private ServiceCombServer chooseServerErrorThresholdMet(List<ServiceCombServer> servers, Invocation invocation) {
synchronized (lock) {
if (errorThresholdMet) {
- chooseNextServer(key);
+ chooseNextServer(servers, invocation);
errorThresholdMet = false;
}
}
@@ -101,8 +101,7 @@ public class SessionStickinessRule implements IRule {
}
private boolean isErrorThresholdMet() {
- AbstractLoadBalancer lb = (AbstractLoadBalancer) getLoadBalancer();
- LoadBalancerStats stats = lb.getLoadBalancerStats();
+ LoadBalancerStats stats = loadBalancer.getLoadBalancerStats();
if (stats != null && stats.getServerStats() != null && stats.getServerStats().size() > 0) {
ServerStats serverStats = stats.getSingleServerStat(lastServer);
@@ -117,14 +116,14 @@ public class SessionStickinessRule implements IRule {
}
@Override
- public Server choose(Object key) {
+ public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
if (lastServer == null) {
- return chooseInitialServer(key);
+ return chooseInitialServer(servers, invocation);
}
if (isTimeOut()) {
LOG.warn("session timeout. choose another server.");
- return chooseServerWhenTimeout(key);
+ return chooseServerWhenTimeout(servers, invocation);
} else {
this.lastAccessedTime = System.currentTimeMillis();
}
@@ -132,28 +131,13 @@ public class SessionStickinessRule implements IRule {
if (isErrorThresholdMet()) {
LOG.warn("reached max error. choose another server.");
errorThresholdMet = true;
- return chooseServerErrorThresholdMet(key);
+ return chooseServerErrorThresholdMet(servers, invocation);
}
- if (!isLastServerExists(lastServer)) {
- return chooseNextServer(key);
+ if (!servers.contains(lastServer)) {
+ return chooseNextServer(servers, invocation);
}
return lastServer;
}
-
- private boolean isLastServerExists(Server lastServer2) {
- return this.lb.getReachableServers().contains(lastServer2);
- }
-
- @Override
- public void setLoadBalancer(ILoadBalancer lb) {
- this.lb = lb;
- this.microserviceName = ((LoadBalancer) lb).getMicroServiceName();
- }
-
- @Override
- public ILoadBalancer getLoadBalancer() {
- return this.lb;
- }
}
diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
new file mode 100644
index 0000000..06aba4f
--- /dev/null
+++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/WeightedResponseTimeRuleExt.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 org.apache.servicecomb.loadbalance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.servicecomb.core.Invocation;
+
+/**
+ * Rule based on response time.
+ */
+public class WeightedResponseTimeRuleExt extends RoundRobinRuleExt {
+ // 10ms
+ private static final int MIN_GAP = 10;
+
+ private Random random = new Random();
+
+ @Override
+ public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
+ List<AtomicInteger> stats = new ArrayList<>(servers.size());
+ int totalWeights = 0;
+ boolean needRandom = false;
+ for (ServiceCombServer server : servers) {
+ ServiceCombServerStats serverStats = ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(server);
+ int avgTime = (int) serverStats.getAverageResponseTime();
+ if (!needRandom && avgTime > MIN_GAP) {
+ needRandom = true;
+ }
+ totalWeights += avgTime;
+ stats.add(new AtomicInteger(avgTime));
+ }
+
+ if (needRandom) {
+ int finalTotal = totalWeights;
+ stats.forEach(item -> item.set(finalTotal - item.get()));
+ int ran = random
+ .nextInt(Math.max(totalWeights * stats.size() - totalWeights, 1));
+ for (int i = 0; i < stats.size(); i++) {
+ ran -= stats.get(i).get();
+ if (ran < 0) {
+ return servers.get(i);
+ }
+ }
+ }
+ return super.choose(servers, invocation);
+ }
+}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
index ed08789..6f93b44 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/MyServerListFilterExt.java
@@ -30,7 +30,7 @@ import com.netflix.loadbalancer.Server;
*/
public class MyServerListFilterExt implements ServerListFilterExt {
@Override
- public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
+ public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList, Invocation invocation) {
if (invocation.getAppId().equals("test")) {
return new ArrayList<>();
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java
index 08d498d..6ef2160 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestConfiguration.java
@@ -35,7 +35,6 @@ public class TestConfiguration {
public void testConstants() {
assertEquals("servicecomb.loadbalance.", Configuration.PROP_ROOT);
- assertEquals("NFLoadBalancerRuleClassName", Configuration.PROP_POLICY);
assertEquals("ribbon.", Configuration.PROP_ROOT_20);
assertEquals("retryEnabled", Configuration.PROP_RETRY_ENABLED);
assertEquals("retryOnNext", Configuration.PROP_RETRY_ONNEXT);
@@ -47,7 +46,6 @@ public class TestConfiguration {
@Test
public void testFullConfigurationWithArgsString() {
- assertNull(Configuration.INSTANCE.getPolicy("test"));
assertNotNull(Configuration.INSTANCE.getRetryOnNext("test"));
assertNotNull(Configuration.INSTANCE.getRetryOnSame("test"));
assertNotNull(Configuration.INSTANCE.isRetryEnabled("test"));
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java
index 69c4a1e..169e91a 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestExtensionsManager.java
@@ -60,17 +60,16 @@ public class TestExtensionsManager {
BeansHolder holder = new BeansHolder();
List<ExtensionsFactory> extensionsFactories = new ArrayList<>();
- extensionsFactories.add(new RuleClassNameExtentionsFactory());
extensionsFactories.add(new RuleNameExtentionsFactory());
extensionsFactories.add(new DefaultRetryExtensionsFactory());
Deencapsulation.setField(holder, "extentionsFactories", extensionsFactories);
holder.init();
- Assert.assertEquals(RoundRobinRule.class.getName(),
+ Assert.assertEquals(RoundRobinRuleExt.class.getName(),
ExtensionsManager.createLoadBalancerRule("mytest1").getClass().getName());
- Assert.assertEquals(RandomRule.class.getName(),
+ Assert.assertEquals(RandomRuleExt.class.getName(),
ExtensionsManager.createLoadBalancerRule("mytest2").getClass().getName());
- Assert.assertEquals(WeightedResponseTimeRule.class.getName(),
+ Assert.assertEquals(WeightedResponseTimeRuleExt.class.getName(),
ExtensionsManager.createLoadBalancerRule("mytest3").getClass().getName());
Assert.assertEquals(SessionStickinessRule.class.getName(),
ExtensionsManager.createLoadBalancerRule("mytest4").getClass().getName());
@@ -84,36 +83,12 @@ public class TestExtensionsManager {
@Test
public void testRuleClassName() {
- System.setProperty("servicecomb.loadbalance.mytest1.NFLoadBalancerRuleClassName",
- "com.netflix.loadbalancer.RoundRobinRule");
- System.setProperty("servicecomb.loadbalance.mytest2.NFLoadBalancerRuleClassName",
- "com.netflix.loadbalancer.WeightedResponseTimeRule");
- System.setProperty("servicecomb.loadbalance.mytest3.NFLoadBalancerRuleClassName", "com.netflix.loadbalancer.RandomRule");
- System.setProperty("servicecomb.loadbalance.mytest4.NFLoadBalancerRuleClassName",
- "org.apache.servicecomb.loadbalance.SessionStickinessRule");
-
BeansHolder holder = new BeansHolder();
List<ExtensionsFactory> extensionsFactories = new ArrayList<>();
- extensionsFactories.add(new RuleClassNameExtentionsFactory());
extensionsFactories.add(new RuleNameExtentionsFactory());
extensionsFactories.add(new DefaultRetryExtensionsFactory());
Deencapsulation.setField(holder, "extentionsFactories", extensionsFactories);
holder.init();
-
- Assert.assertEquals(RoundRobinRule.class.getName(),
- ExtensionsManager.createLoadBalancerRule("mytest1").getClass().getName());
- Assert.assertEquals(WeightedResponseTimeRule.class.getName(),
- ExtensionsManager.createLoadBalancerRule("mytest2").getClass().getName());
- Assert.assertEquals(RandomRule.class.getName(),
- ExtensionsManager.createLoadBalancerRule("mytest3").getClass().getName());
- Assert.assertEquals(SessionStickinessRule.class.getName(),
- ExtensionsManager.createLoadBalancerRule("mytest4").getClass().getName());
-
- System.getProperties().remove("servicecomb.loadbalance.mytest1.NFLoadBalancerRuleClassName");
- System.getProperties().remove("servicecomb.loadbalance.mytest2.NFLoadBalancerRuleClassName");
- System.getProperties().remove("servicecomb.loadbalance.mytest3.NFLoadBalancerRuleClassName");
- System.getProperties().remove("servicecomb.loadbalance.mytest4.NFLoadBalancerRuleClassName");
-
RetryHandler retryHandler = ExtensionsManager.createRetryHandler("mytest1");
Assert.assertTrue(DefaultLoadBalancerRetryHandler.class.isInstance(retryHandler));
Assert.assertFalse(retryHandler.isRetriableException(new InvocationException(400, "", ""), false));
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
index f088e71..4c5373a 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceCreator.java
@@ -20,15 +20,15 @@ package org.apache.servicecomb.loadbalance;
import java.util.ArrayList;
import java.util.List;
+import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
+import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
import org.junit.Assert;
import org.junit.Test;
-import com.netflix.loadbalancer.RandomRule;
-import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.WeightedResponseTimeRule;
import mockit.Deencapsulation;
import mockit.Expectations;
@@ -37,14 +37,21 @@ import mockit.Mocked;
public class TestLoadBalanceCreator {
@Test
- public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation invocation) {
+ public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation invocation,
+ @Injectable Transport transport) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
- RoundRobinRule rule = new RoundRobinRule();
- List<Server> servers = new ArrayList<>();
- Server server = new Server("host1", 80);
- server.setAlive(true);
- Server server2 = new Server("host2", 80);
- server2.setAlive(true);
+ RoundRobinRuleExt rule = new RoundRobinRuleExt();
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Endpoint host1 = new Endpoint(transport, "host1");
+ MicroserviceInstance instance1 = new MicroserviceInstance();
+ instance1.setInstanceId("instance1");
+ ServiceCombServer server = new ServiceCombServer(host1, instance1);
+
+ Endpoint host2 = new Endpoint(transport, "host2");
+ MicroserviceInstance instance2 = new MicroserviceInstance();
+ instance2.setInstanceId("instance2");
+ ServiceCombServer server2 = new ServiceCombServer(host2, instance2);
+
servers.add(server);
servers.add(server2);
LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "test");
@@ -53,9 +60,10 @@ public class TestLoadBalanceCreator {
filters.add(new ServerListFilterExt() {
@Override
- public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
- List<Server> filteredServers = new ArrayList<>();
- for (Server server : servers) {
+ public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList,
+ Invocation invocation) {
+ List<ServiceCombServer> filteredServers = new ArrayList<>();
+ for (ServiceCombServer server : servers) {
if (server.getHost().equals("host1")) {
continue;
}
@@ -66,35 +74,43 @@ public class TestLoadBalanceCreator {
});
lbCreator.setFilters(filters);
- LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
- Server s = lb.chooseServer("test");
+ LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ Server s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
- s = lb.chooseServer("test");
+ s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
- s = lb.chooseServer("test");
+ s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
}
@Test
- public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation invocation) {
+ public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation invocation,
+ @Injectable Transport transport) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
- RandomRule rule = new RandomRule();
+ RandomRuleExt rule = new RandomRuleExt();
LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
- List<Server> servers = new ArrayList<>();
- Server server = new Server("host1", 80);
- server.setAlive(true);
- Server server2 = new Server("host2", 80);
- server2.setAlive(true);
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Endpoint host1 = new Endpoint(transport, "host1");
+ MicroserviceInstance instance1 = new MicroserviceInstance();
+ instance1.setInstanceId("instance1");
+ ServiceCombServer server = new ServiceCombServer(host1, instance1);
+
+ Endpoint host2 = new Endpoint(transport, "host2");
+ MicroserviceInstance instance2 = new MicroserviceInstance();
+ instance2.setInstanceId("instance2");
+ ServiceCombServer server2 = new ServiceCombServer(host2, instance2);
+
servers.add(server);
servers.add(server2);
- lbCreator.setServerList(servers);
+
List<ServerListFilterExt> filters = new ArrayList<>();
filters.add(new ServerListFilterExt() {
@Override
- public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
- List<Server> filteredServers = new ArrayList<>();
- for (Server server : servers) {
+ public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList,
+ Invocation invocation) {
+ List<ServiceCombServer> filteredServers = new ArrayList<>();
+ for (ServiceCombServer server : servers) {
if (server.getHost().equals("host1")) {
continue;
}
@@ -104,46 +120,48 @@ public class TestLoadBalanceCreator {
}
});
lbCreator.setFilters(filters);
- LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
- Server s = lb.chooseServer("test");
+ LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ Server s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
- s = lb.chooseServer("test");
+ s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
- s = lb.chooseServer("test");
+ s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
}
@Test
- public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Mocked ServiceCombServer server,
- @Mocked ServiceCombServer server2, @Injectable Invocation invocation) {
+ public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Injectable Endpoint endpoint1, @Injectable Endpoint endpoint2, @Injectable Invocation invocation) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
- WeightedResponseTimeRule rule = new WeightedResponseTimeRule();
+ WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
- List<Server> servers = new ArrayList<>();
+
+
+ List<ServiceCombServer> servers = new ArrayList<>();
+ MicroserviceInstance instance1 = new MicroserviceInstance();
+ instance1.setInstanceId("ii01");
+ MicroserviceInstance instance2 = new MicroserviceInstance();
+ instance2.setInstanceId("ii02");
+ ServiceCombServer server = new ServiceCombServer(endpoint1, instance1);
+ ServiceCombServer server2 = new ServiceCombServer(endpoint2, instance2);
new Expectations() {
{
- server.getHost();
+ endpoint1.getEndpoint();
result = "host1";
-
- server2.isReadyToServe();
- result = true;
- server2.isAlive();
- result = true;
- server2.getHost();
+ endpoint2.getEndpoint();
result = "host2";
}
};
servers.add(server);
servers.add(server2);
- lbCreator.setServerList(servers);
List<ServerListFilterExt> filters = new ArrayList<>();
filters.add(new ServerListFilterExt() {
@Override
- public List<Server> getFilteredListOfServers(List<Server> serverList, Invocation invocation) {
- List<Server> filteredServers = new ArrayList<>();
- for (Server server : servers) {
+ public List<ServiceCombServer> getFilteredListOfServers(List<ServiceCombServer> serverList,
+ Invocation invocation) {
+ List<ServiceCombServer> filteredServers = new ArrayList<>();
+ for (ServiceCombServer server : servers) {
if (server.getHost().equals("host1")) {
continue;
}
@@ -153,40 +171,47 @@ public class TestLoadBalanceCreator {
}
});
lbCreator.setFilters(filters);
- LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
- Server s = lb.chooseServer("test");
+ LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ Server s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
- s = lb.chooseServer("test");
+ s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
- s = lb.chooseServer("test");
+ s = lb.chooseServer(invocation);
Assert.assertEquals(server2, s);
}
@Test
- public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation invocation) {
+ public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation invocation,
+ @Injectable Transport transport) {
SessionStickinessRule rule = new SessionStickinessRule();
LoadBalancerCreator lbCreator = new LoadBalancerCreator(rule, "service");
- List<Server> servers = new ArrayList<>();
- Server server = new Server("host1", 80);
- server.setAlive(true);
- Server server2 = new Server("host2", 80);
- server2.setAlive(true);
+ List<ServiceCombServer> servers = new ArrayList<>();
+ Endpoint host1 = new Endpoint(transport, "host1");
+ MicroserviceInstance instance1 = new MicroserviceInstance();
+ ServiceCombServer server = new ServiceCombServer(host1, instance1);
+ instance1.setInstanceId("instance1");
+
+ Endpoint host2 = new Endpoint(transport, "host2");
+ MicroserviceInstance instance2 = new MicroserviceInstance();
+ ServiceCombServer server2 = new ServiceCombServer(host2, instance2);
+ instance2.setInstanceId("instance2");
+
servers.add(server);
servers.add(server2);
- lbCreator.setServerList(servers);
+
lbCreator.setFilters(new ArrayList<>());
- LoadBalancer lb = lbCreator.createLoadBalancer(invocation);
- Server s = lb.chooseServer("test");
- Assert.assertEquals(server2, s);
- s = lb.chooseServer("test");
- Assert.assertEquals(server2, s);
+ LoadBalancer lb = lbCreator.createLoadBalancer(servers);
+ Server s = lb.chooseServer(invocation);
+ Assert.assertEquals(server, s);
+ s = lb.chooseServer(invocation);
+ Assert.assertEquals(server, s);
long time = Deencapsulation.getField(rule, "lastAccessedTime");
Deencapsulation.setField(rule, "lastAccessedTime", time - 1000 * 300);
ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.sessionTimeoutInSeconds", 9);
- s = lb.chooseServer("test");
- Assert.assertEquals(server, s);
+ s = lb.chooseServer(invocation);
+ Assert.assertEquals(server2, s);
ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.successiveFailedTimes", 5);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
@@ -194,7 +219,7 @@ public class TestLoadBalanceCreator {
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
- s = lb.chooseServer("test");
- Assert.assertEquals(server2, s);
+ s = lb.chooseServer(invocation);
+ Assert.assertEquals(server, s);
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
index b5262b5..906529f 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
@@ -35,6 +35,7 @@ import org.apache.servicecomb.serviceregistry.cache.InstanceCacheManager;
import org.apache.servicecomb.serviceregistry.discovery.DiscoveryTreeNode;
import org.junit.After;
import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
@@ -43,6 +44,11 @@ import org.mockito.Mockito;
*
*/
public class TestLoadBalanceHandler2 {
+ @BeforeClass
+ public static void beforeClass() {
+ // avoid mock
+ ServiceCombLoadBalancerStats.INSTANCE.init();
+ }
@After
public void teardown() {
@@ -122,54 +128,54 @@ public class TestLoadBalanceHandler2 {
handler = new LoadbalanceHandler();
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server, null);
data.put("noneMatchInstance", noneMatchInstance);
parent.cacheVersion(1);
handler = new LoadbalanceHandler();
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9092");
data.put("regionMatchInstance", regionMatchInstance);
parent.cacheVersion(parent.cacheVersion() + 1);
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
data.put("allmatchInstance", allmatchInstance);
parent.cacheVersion(parent.cacheVersion() + 1);
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server, 0);
//if errorThresholdPercentage is 0,that means errorThresholdPercentage is not active.
ArchaiusUtils.setProperty("servicecomb.loadbalance.isolation.errorThresholdPercentage", "0");
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
//if errorThresholdPercentage greater than 0, it will activate.
ArchaiusUtils.setProperty("servicecomb.loadbalance.isolation.errorThresholdPercentage", "20");
ServiceCombServer server2 = server;
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server2);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(server2, 0);
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9090");
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(server2, 0);
loadBalancer = handler.getOrCreateLoadBalancer(invocation);
- server = (ServiceCombServer) loadBalancer.chooseServer();
+ server = (ServiceCombServer) loadBalancer.chooseServer(invocation);
Assert.assertEquals(server.getEndpoint().getEndpoint(), "rest://localhost:9091");
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
index a61fa4f..7b26368 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalancer.java
@@ -17,117 +17,31 @@
package org.apache.servicecomb.loadbalance;
-import static org.junit.Assert.assertNotNull;
-
import java.util.ArrayList;
import java.util.List;
+import org.apache.servicecomb.core.Invocation;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
-import com.netflix.loadbalancer.AbstractLoadBalancer.ServerGroup;
-import com.netflix.loadbalancer.IRule;
-import com.netflix.loadbalancer.Server;
-
public class TestLoadBalancer {
- private IRule rule = Mockito.mock(IRule.class);
+ private RuleExt rule = Mockito.mock(RuleExt.class);
- @SuppressWarnings("deprecation")
@Test
public void testLoadBalancerFullOperationWithoutException() {
- List<Server> newServers = new ArrayList<>();
- Server server = Mockito.mock(Server.class);
+ List<ServiceCombServer> newServers = new ArrayList<>();
+ ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
+ Invocation invocation = Mockito.mock(Invocation.class);
newServers.add(server);
- LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
- loadBalancer.setServerList(newServers);
- loadBalancer.chooseServer();
-
- Object key = Mockito.mock(Object.class);
+ List<ServerListFilterExt> filterExts = new ArrayList<>();
+ LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null, filterExts, newServers);
+ loadBalancer.chooseServer(invocation);
- loadBalancer.chooseServer(key);
- loadBalancer.getAllServers();
- loadBalancer.getServerList(true);
- loadBalancer.getServerList(false);
- loadBalancer.getLoadBalancerStats();
- loadBalancer.getReachableServers();
-
- assertNotNull(loadBalancer.getAllServers());
- }
-
- @Test
- public void testAddServerException() {
- boolean status = true;
- List<Server> newServers = new ArrayList<>();
- Server server = Mockito.mock(Server.class);
-
- newServers.add(server);
- LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
- loadBalancer.setServerList(newServers);
- try {
+ Mockito.when(rule.choose(newServers, invocation)).thenReturn(server);
- loadBalancer.addServers(newServers);
- } catch (Exception e) {
-
- status = false;
-
- Assert.assertEquals("Not implemented.", e.getMessage());
- }
-
- Assert.assertFalse(status);
- }
-
- @Test
- public void testServerListException() {
- boolean status = true;
- List<Server> newServers = new ArrayList<>();
- Server server = Mockito.mock(Server.class);
-
- newServers.add(server);
- LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
- loadBalancer.setServerList(newServers);
- try {
-
- loadBalancer.getServerList(ServerGroup.ALL);
- } catch (Exception e) {
-
- status = false;
-
- Assert.assertEquals("Not implemented.", e.getMessage());
- }
-
- Assert.assertFalse(status);
- }
-
- @Test
- public void testMarkServerDownException() {
- boolean status = true;
- List<Server> newServers = new ArrayList<>();
- Server server = Mockito.mock(Server.class);
-
- newServers.add(server);
- LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
- loadBalancer.setServerList(newServers);
- try {
-
- loadBalancer.markServerDown(server);
- } catch (Exception e) {
-
- status = false;
-
- Assert.assertEquals("Not implemented.", e.getMessage());
- }
-
- Assert.assertFalse(status);
- }
-
- @Test
- public void testGetAllServers() {
- List<Server> servers = new ArrayList<>();
- Server server = Mockito.mock(Server.class);
- servers.add(server);
- LoadBalancer loadBalancer = new LoadBalancer(rule, "test", null);
- loadBalancer.setServerList(servers);
- Assert.assertEquals(servers, loadBalancer.getAllServers());
+ Assert.assertEquals(server, loadBalancer.chooseServer(invocation));
+ Assert.assertEquals(null, loadBalancer.getLoadBalancerStats());
+ Assert.assertEquals("test", loadBalancer.getMicroServiceName());
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
index faa86f9..468e482 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadbalanceHandler.java
@@ -137,7 +137,6 @@ public class TestLoadbalanceHandler {
BeansHolder holder = new BeansHolder();
List<ExtensionsFactory> extensionsFactories = new ArrayList<>();
- extensionsFactories.add(new RuleClassNameExtentionsFactory());
extensionsFactories.add(new RuleNameExtentionsFactory());
extensionsFactories.add(new DefaultRetryExtensionsFactory());
Deencapsulation.setField(holder, "extentionsFactories", extensionsFactories);
@@ -179,7 +178,7 @@ public class TestLoadbalanceHandler {
LoadBalancer lb = handler.getOrCreateLoadBalancer(invocation);
- Assert.assertEquals("[rest://localhost:8080]", Deencapsulation.getField(lb, "serverList").toString());
+ Assert.assertEquals("[rest://localhost:8080]", Deencapsulation.getField(lb, "servers").toString());
}
@Test
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
index 11dfe77..23352c8 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombLoadBalancerStats.java
@@ -39,7 +39,7 @@ public class TestServiceCombLoadBalancerStats {
@BeforeClass
public static void beforeClass() {
// avoid mock
- ServiceCombLoadBalancerStats.INSTANCE.getClass();
+ ServiceCombLoadBalancerStats.INSTANCE.init();
}
@Test
@@ -64,7 +64,7 @@ public class TestServiceCombLoadBalancerStats {
ServiceCombServer serviceCombServer = new ServiceCombServer(transport,
new CacheEndpoint("rest://localhost:8080", instance));
- serviceCombLoadBalancerStats.markSuccess(serviceCombServer);
+ serviceCombLoadBalancerStats.markSuccess(serviceCombServer, 0);
ServiceCombServerStats stats = serviceCombLoadBalancerStats.getServiceCombServerStats(serviceCombServer);
Assert.assertEquals(serviceCombLoadBalancerStats.getPingView().size(), 1);
await().atMost(5, TimeUnit.SECONDS)
@@ -83,16 +83,16 @@ public class TestServiceCombLoadBalancerStats {
instance.setInstanceId("instance1");
ServiceCombServer serviceCombServer = new ServiceCombServer(transport,
new CacheEndpoint("rest://localhost:8080", instance));
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
Assert.assertEquals(
ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getCountinuousFailureCount(),
2);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
Assert.assertEquals(
ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getCountinuousFailureCount(),
0);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
Assert
.assertEquals(
ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(serviceCombServer).getTotalRequests(), 4);
@@ -119,10 +119,10 @@ public class TestServiceCombLoadBalancerStats {
for (int i = 0; i < 10; i++) {
new Thread() {
public void run() {
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
- ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
- ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markFailure(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
+ ServiceCombLoadBalancerStats.INSTANCE.markSuccess(serviceCombServer, 0);
latch.countDown();
}
}.start();
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
index 3010368..3fda339 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestServiceCombServerStats.java
@@ -31,12 +31,12 @@ public class TestServiceCombServerStats {
public void testSimpleThread() {
long time = System.currentTimeMillis();
ServiceCombServerStats stats = new ServiceCombServerStats();
- stats.markFailure();
- stats.markFailure();
+ stats.markFailure(0);
+ stats.markFailure(0);
Assert.assertEquals(stats.getCountinuousFailureCount(), 2);
- stats.markSuccess();
+ stats.markSuccess(0);
Assert.assertEquals(stats.getCountinuousFailureCount(), 0);
- stats.markSuccess();
+ stats.markSuccess(0);
Assert.assertEquals(stats.getTotalRequests(), 4);
Assert.assertEquals(stats.getFailedRate(), 50);
Assert.assertEquals(stats.getSuccessRate(), 50);
@@ -52,10 +52,10 @@ public class TestServiceCombServerStats {
for (int i = 0; i < 10; i++) {
new Thread() {
public void run() {
- stats.markFailure();
- stats.markFailure();
- stats.markSuccess();
- stats.markSuccess();
+ stats.markFailure(0);
+ stats.markFailure(0);
+ stats.markSuccess(0);
+ stats.markSuccess(0);
latch.countDown();
}
}.start();
@@ -78,8 +78,8 @@ public class TestServiceCombServerStats {
};
ServiceCombServerStats stats = new ServiceCombServerStats();
Assert.assertEquals(stats.getLastVisitTime(), 1000);
- stats.markSuccess();
- stats.markFailure();
+ stats.markSuccess(0);
+ stats.markFailure(0);
Assert.assertEquals(stats.getTotalRequests(), 2);
Assert.assertEquals(stats.getFailedRate(), 50);
Assert.assertEquals(stats.getSuccessRate(), 50);
@@ -89,7 +89,7 @@ public class TestServiceCombServerStats {
return 60000 + 2000;
}
};
- stats.markSuccess();
+ stats.markSuccess(0);
Assert.assertEquals(stats.getTotalRequests(), 1);
Assert.assertEquals(stats.getFailedRate(), 0);
Assert.assertEquals(stats.getSuccessRate(), 100);
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
index 6ebead2..dd2319e 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestSessionSticknessRule.java
@@ -20,9 +20,11 @@ package org.apache.servicecomb.loadbalance;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
import org.apache.servicecomb.serviceregistry.cache.CacheEndpoint;
@@ -49,22 +51,20 @@ public class TestSessionSticknessRule {
instance1.setInstanceId("1234");
ServiceCombServer mockedServer =
new ServiceCombServer(transport, new CacheEndpoint("rest:127.0.0.1:8889", instance1));
- Object key = Mockito.mock(Object.class);
+ Invocation invocation = mock(Invocation.class);
LoadBalancerStats stats = mock(LoadBalancerStats.class);
Mockito.when(mockedLb.getLoadBalancerStats()).thenReturn(stats);
- Deencapsulation.invoke(rule, "chooseServerWhenTimeout", key);
+ Deencapsulation.invoke(rule, "chooseServerWhenTimeout", Arrays.asList(mockedServer), invocation);
mockedServer.setAlive(true);
mockedServer.setReadyToServe(true);
- List<Server> allServers = Arrays.asList(mockedServer);
- when(mockedLb.getReachableServers()).thenReturn(allServers);
- when(mockedLb.getAllServers()).thenReturn(allServers);
-
+ List<ServiceCombServer> allServers = Arrays.asList(mockedServer);
rule.setLoadBalancer(mockedLb);
- Assert.assertEquals(rule.getLoadBalancer(), mockedLb);
- Server s = rule.choose("default");
+
+
+ Server s = rule.choose(allServers, invocation);
Assert.assertEquals(s, mockedServer);
- s = rule.choose("default");
+ s = rule.choose(allServers, invocation);
Assert.assertEquals(s, mockedServer);
}
@@ -77,9 +77,12 @@ public class TestSessionSticknessRule {
Object key = new Object();
- Server s = new Server("test");
+ Invocation invocation = mock(Invocation.class);
+ ServiceCombServer server = mock(ServiceCombServer.class);
+ List<ServiceCombServer> servers = new ArrayList<>();
+ servers.add(server);
- Deencapsulation.setField(ss, "lastServer", s);
+ Deencapsulation.setField(ss, "lastServer", server);
new MockUp<SessionStickinessRule>() {
@@ -98,7 +101,7 @@ public class TestSessionSticknessRule {
};
try {
- ss.choose(key);
+ ss.choose(servers, invocation);
} catch (Exception e) {
status = false;
}
@@ -112,11 +115,12 @@ public class TestSessionSticknessRule {
SessionStickinessRule ss = new SessionStickinessRule();
- Object key = new Object();
-
- Server s = new Server("test");
+ Invocation invocation = mock(Invocation.class);
+ ServiceCombServer server = mock(ServiceCombServer.class);
+ List<ServiceCombServer> servers = new ArrayList<>();
+ servers.add(server);
- Deencapsulation.setField(ss, "lastServer", s);
+ Deencapsulation.setField(ss, "lastServer", server);
new MockUp<SessionStickinessRule>() {
@@ -127,7 +131,7 @@ public class TestSessionSticknessRule {
};
try {
- ss.choose(key);
+ ss.choose(servers, invocation);
} catch (Exception e) {
status = false;
}
@@ -144,9 +148,12 @@ public class TestSessionSticknessRule {
Object key = new Object();
- Server s = new Server("test");
+ Invocation invocation = mock(Invocation.class);
+ ServiceCombServer server = mock(ServiceCombServer.class);
+ List<ServiceCombServer> servers = new ArrayList<>();
+ servers.add(server);
- Deencapsulation.setField(ss, "lastServer", s);
+ Deencapsulation.setField(ss, "lastServer", server);
new MockUp<SessionStickinessRule>() {
@@ -157,7 +164,7 @@ public class TestSessionSticknessRule {
};
try {
- ss.choose(key);
+ ss.choose(servers, invocation);
} catch (Exception e) {
status = false;
}
@@ -173,9 +180,12 @@ public class TestSessionSticknessRule {
Object key = new Object();
- Server s = new Server("test");
+ Invocation invocation = mock(Invocation.class);
+ ServiceCombServer server = mock(ServiceCombServer.class);
+ List<ServiceCombServer> servers = new ArrayList<>();
+ servers.add(server);
- Deencapsulation.setField(ss, "lastServer", s);
+ Deencapsulation.setField(ss, "lastServer", server);
new MockUp<SessionStickinessRule>() {
@@ -202,7 +212,7 @@ public class TestSessionSticknessRule {
};
try {
- ss.choose(key);
+ ss.choose(servers, invocation);
} catch (Exception e) {
status = false;
}
@@ -217,26 +227,14 @@ public class TestSessionSticknessRule {
Object key = new Object();
- Server s = new Server("test");
+ Invocation invocation = mock(Invocation.class);
+ ServiceCombServer server = mock(ServiceCombServer.class);
+ List<ServiceCombServer> servers = new ArrayList<>();
+ servers.add(server);
- Deencapsulation.setField(ss, "lastServer", s);
- try {
- ss.choose(key);
- } catch (Exception e) {
- status = false;
- }
- Assert.assertTrue(status);
- }
-
- @Test
- public void testServerWithKey() {
-
- boolean status = true;
- SessionStickinessRule ss = new SessionStickinessRule();
-
- Object key = new Object();
+ Deencapsulation.setField(ss, "lastServer", server);
try {
- ss.choose(key);
+ ss.choose(servers, invocation);
} catch (Exception e) {
status = false;
}
@@ -248,6 +246,7 @@ public class TestSessionSticknessRule {
SessionStickinessRule rule = new SessionStickinessRule();
Transport transport = mock(Transport.class);
+ Invocation invocation = mock(Invocation.class);
MicroserviceInstance instance1 = new MicroserviceInstance();
instance1.setInstanceId("1234");
ServiceCombServer mockedServer =
@@ -255,13 +254,11 @@ public class TestSessionSticknessRule {
mockedServer.setAlive(true);
mockedServer.setReadyToServe(true);
mockedServer.setId("mockedServer");
- List<Server> allServers = Arrays.asList(mockedServer);
- LoadBalancer lb = new LoadBalancer(rule, "mockedServer", null);
- lb.setServerList(allServers);
+ List<ServiceCombServer> allServers = Arrays.asList(mockedServer);
+ LoadBalancer lb = new LoadBalancer(rule, "mockedServer", null, new ArrayList<>(), allServers);
rule.setLoadBalancer(lb);
- Assert.assertEquals(lb, rule.getLoadBalancer());
- Server server = new Server("test");
+ ServiceCombServer server = new ServiceCombServer(transport, new CacheEndpoint("rest:127.0.0.1:8890", instance1));
Deencapsulation.setField(rule, "lastServer", server);
new MockUp<SessionStickinessRule>(rule) {
@@ -276,7 +273,7 @@ public class TestSessionSticknessRule {
}
};
Object key = Mockito.mock(Object.class);
- Server s = rule.choose(key);
+ Server s = rule.choose(allServers, invocation);
Assert.assertEquals(mockedServer, s);
}
}
diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
index 3a5e8b9..5dbd6a4 100644
--- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
+++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestServerDiscoveryFilter.java
@@ -72,6 +72,7 @@ public class TestServerDiscoveryFilter {
}
};
MicroserviceInstance instance = new MicroserviceInstance();
+ instance.setInstanceId("0000001");
ServiceCombServer server = (ServiceCombServer) filter.createEndpoint(Const.RESTFUL, "rest://localhost:8080", instance);
Assert.assertSame(instance, server.getInstance());
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
index 5c3caf0..30e812f 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
@@ -21,13 +21,17 @@ import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.CompletableFuture;
+import javax.ws.rs.core.Response.Status;
+
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.Response;
import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapper;
import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
+import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtension;
import org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper;
@@ -159,6 +163,10 @@ public class SwaggerProducerOperation {
}
Object result = producerMethod.invoke(producerInstance, args);
response = responseMapper.mapResponse(invocation.getStatus(), result);
+ } catch (IllegalArgumentException ae) {
+ response = processException(invocation,
+ new InvocationException(Status.BAD_REQUEST.getStatusCode(), "",
+ new CommonExceptionData(ae.getMessage()), ae));
} catch (Throwable e) {
response = processException(invocation, e);
}