use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.
the class DegraderLoadBalancerTest method TestGetTrackerClients.
// Performance test, disabled by default
@Test(groups = { "small", "back-end" }, enabled = false)
public void TestGetTrackerClients() {
final DegraderLoadBalancerStrategyV3 strategy = getStrategy();
TestClock testClock = new TestClock();
String baseUri = "http://linkedin.com:9999";
int numberOfClients = 100;
int loopNumber = 100000;
Map<String, String> degraderProperties = new HashMap<String, String>();
degraderProperties.put(PropertyKeys.DEGRADER_HIGH_ERROR_RATE, "0.5");
degraderProperties.put(PropertyKeys.DEGRADER_LOW_ERROR_RATE, "0.2");
DegraderImpl.Config degraderConfig = DegraderConfigFactory.toDegraderConfig(degraderProperties);
RequestContext requestContext = new RequestContext();
Random random = new Random();
final List<TrackerClient> clients = new ArrayList<TrackerClient>(numberOfClients);
Map<TrackerClient, Integer> clientCount = new HashMap<>();
// create trackerclients
for (int i = 0; i < numberOfClients; i++) {
URI uri = URI.create(baseUri + i);
TrackerClient client = new TrackerClient(uri, getDefaultPartitionData(1, 1), new TestLoadBalancerClient(uri), testClock, degraderConfig);
clients.add(client);
}
for (int i = 0; i < loopNumber; ++i) {
TrackerClient client = strategy.getTrackerClient(null, requestContext, 1, DefaultPartitionAccessor.DEFAULT_PARTITION_ID, clients);
assertNotNull(client);
Integer count = clientCount.get(client);
if (count == null) {
clientCount.put(client, 1);
} else {
clientCount.put(client, count + 1);
}
}
int i = 0;
int avg_count = (loopNumber * 5) / (numberOfClients * 10);
for (Integer count : clientCount.values()) {
assertTrue(count >= avg_count);
i++;
}
assertTrue(i == numberOfClients);
}
use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testOneTrackerClientForPartition.
@Test(groups = { "small", "back-end" })
public void testOneTrackerClientForPartition() throws URISyntaxException {
DegraderLoadBalancerStrategyV3 strategy = getStrategy();
List<TrackerClient> clients = new ArrayList<TrackerClient>();
URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
Map<Integer, PartitionData> weightMap = new HashMap<Integer, PartitionData>();
weightMap.put(0, new PartitionData(1d));
TrackerClient client = new TrackerClient(uri1, weightMap, new TestLoadBalancerClient(uri1), new TestClock(), null);
clients.add(client);
// should always get the only client in the list
for (int i = 0; i < 1000; ++i) {
assertEquals(strategy.getTrackerClient(null, new RequestContext(), 0, 0, clients), client);
}
}
use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.
the class DegraderLoadBalancerTest method clusterRecovery1TC.
/**
* helper method to test DegraderLoadBalancerStrategy recovery with 1 TrackerClient.
*
* We want to test DegraderV2 and V3 with 2 different strategies : LoadBalacing and Call Dropping.
* So this method needs to able to handle all 4 permutations.
*
* @param myMap
* @param clock
* @param stepsToFullRecovery
* @param timeInterval
* @param strategy
*/
public void clusterRecovery1TC(Map<String, Object> myMap, TestClock clock, int stepsToFullRecovery, Long timeInterval, DegraderLoadBalancerStrategyAdapter strategy, DegraderLoadBalancerStrategyV2_1.DegraderLoadBalancerState.Strategy strategyV2, DegraderLoadBalancerStrategyV3.PartitionDegraderLoadBalancerState.Strategy strategyV3) {
final int NUM_CHECKS = 5;
final Long TIME_INTERVAL = timeInterval;
int localStepsToFullRecovery = stepsToFullRecovery;
DegraderLoadBalancerStrategyConfig config = DegraderLoadBalancerStrategyConfig.createHttpConfigFromMap(myMap);
List<TrackerClient> clients = new ArrayList<TrackerClient>();
URI uri1 = URI.create("http://test.linkedin.com:3242/fdsaf");
URIRequest request = new URIRequest(uri1);
TrackerClient client1 = new TrackerClient(uri1, getDefaultPartitionData(1d), new TestLoadBalancerClient(uri1), clock, null);
clients.add(client1);
// force client1 to be disabled
DegraderControl dcClient1Default = client1.getDegraderControl(DEFAULT_PARTITION_ID);
dcClient1Default.setOverrideMinCallCount(5);
dcClient1Default.setMinCallCount(5);
dcClient1Default.setMaxDropRate(1d);
dcClient1Default.setUpStep(1.0d);
List<CallCompletion> ccList = new ArrayList<CallCompletion>();
CallCompletion cc;
for (int j = 0; j < NUM_CHECKS; j++) {
cc = client1.getCallTracker().startCall();
ccList.add(cc);
}
// add high latency and errors to shut off traffic to this tracker client.
// note: the default values for highError and lowError in the degrader are 1.1,
// which means we don't use errorRates when deciding when to lb/degrade.
// In addition, because we changed to use the
clock.addMs(3500);
//for (int j = 0; j < NUM_CHECKS; j++)
for (Iterator<CallCompletion> iter = ccList.listIterator(); iter.hasNext(); ) {
cc = iter.next();
cc.endCallWithError();
iter.remove();
}
// go to next time interval.
clock.addMs(TIME_INTERVAL);
Assert.assertEquals(dcClient1Default.getCurrentComputedDropRate(), 1.0);
// trigger a state update
TrackerClient resultTC = getTrackerClient(strategy, request, new RequestContext(), 1, clients);
if (config.getInitialRecoveryLevel() < 0.01) {
//the returned TrackerClient should be null
assertNull(resultTC, "expected null trackerclient");
// tracker client, so it's time to try it out. We need to enter this code at least once.
do {
// go to next time interval.
clock.addMs(TIME_INTERVAL);
// try adjusting the hash ring on this updateState
if (strategyV3 != null) {
strategy.setStrategyV3(DEFAULT_PARTITION_ID, strategyV3);
} else if (strategyV2 != null) {
strategy.setStrategyV2(strategyV2);
} else {
fail("should set strategy (either LoadBalance or Degrader");
}
resultTC = getTrackerClient(strategy, request, new RequestContext(), 1, clients);
localStepsToFullRecovery--;
} while (localStepsToFullRecovery > 0);
}
assertNotNull(resultTC, "expected non-null trackerclient");
// make calls to the tracker client to verify that it's on the road to healthy status.
for (int j = 0; j < NUM_CHECKS; j++) {
cc = resultTC.getCallTracker().startCall();
ccList.add(cc);
}
clock.addMs(10);
for (Iterator<CallCompletion> iter = ccList.listIterator(); iter.hasNext(); ) {
cc = iter.next();
cc.endCall();
iter.remove();
}
// go to next time interval.
clock.addMs(TIME_INTERVAL);
Assert.assertTrue(dcClient1Default.getCurrentComputedDropRate() < 1d);
resultTC = getTrackerClient(strategy, request, new RequestContext(), 1, clients);
assertNotNull(resultTC, "expected non-null trackerclient");
}
use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testBadTrackerClients.
@Test(groups = { "small", "back-end" })
public void testBadTrackerClients() throws URISyntaxException {
DegraderLoadBalancerStrategyV3 strategy = getStrategy();
// test null twice (first time will have no state)
for (int i = 0; i < 2; ++i) {
assertNull(getTrackerClient(strategy, null, new RequestContext(), 0, null));
}
strategy = getStrategy();
// test empty twice (first time will have no state)
for (int i = 0; i < 2; ++i) {
assertNull(getTrackerClient(strategy, null, new RequestContext(), 0, new ArrayList<TrackerClient>()));
}
// test same cluster generation id but different client lists
strategy = getStrategy();
List<TrackerClient> clients1 = new ArrayList<TrackerClient>();
SettableClock clock1 = new SettableClock();
SettableClock clock2 = new SettableClock();
List<TrackerClient> clients2 = new ArrayList<TrackerClient>();
SettableClock clock3 = new SettableClock();
SettableClock clock4 = new SettableClock();
clients1.add(getClient(URI.create("http://test.linkedin.com:3242/fdsaf"), clock1));
clients1.add(getClient(URI.create("http://test.linkedin.com:3243/fdsaf"), clock2));
clients2.add(getClient(URI.create("http://asdbasdf.com:3242/fdsaf"), clock3));
clients2.add(getClient(URI.create("ftp://example.com:21/what"), clock4));
// same cluster generation id but different tracker clients
assertNotNull(getTrackerClient(strategy, null, new RequestContext(), 0, clients2));
assertNull(getTrackerClient(strategy, null, new RequestContext(), 0, clients1));
// now trigger an update by cluster generation id
assertNotNull(getTrackerClient(strategy, null, new RequestContext(), 1, clients1));
assertNull(getTrackerClient(strategy, null, new RequestContext(), 1, clients2));
}
use of com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3 in project rest.li by linkedin.
the class DegraderLoadBalancerTest method testTargetHostHeaderBindingInvalidHost.
@Test
public void testTargetHostHeaderBindingInvalidHost() {
final int NUM_SERVERS = 10;
DegraderLoadBalancerStrategyV3 strategy = getStrategy();
List<TrackerClient> clients = new ArrayList<TrackerClient>(NUM_SERVERS);
for (int ii = 0; ii < NUM_SERVERS; ++ii) {
clients.add(getClient(URI.create("http://server" + ii + ".testing:9876/foobar")));
}
RestRequestBuilder builder = new RestRequestBuilder(URI.create("d2://fooservice"));
RestRequest request = builder.build();
RequestContext context = new RequestContext();
KeyMapper.TargetHostHints.setRequestContextTargetHost(context, URI.create("http://notinclientlist.testing:9876/foobar"));
TrackerClient client = getTrackerClient(strategy, request, context, 0, clients);
Assert.assertNull(client);
}
Aggregations