Search in sources :

Example 16 with DegraderTrackerClient

use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testHealthCheckRequestContextNotShared.

@Test
public void testHealthCheckRequestContextNotShared() {
    final DegraderLoadBalancerStrategyConfig config = new DegraderLoadBalancerStrategyConfig(1000);
    final TestClock clock = new TestClock();
    final DegraderImpl.Config degraderConfig = DegraderConfigFactory.toDegraderConfig(Collections.emptyMap());
    final DegraderTrackerClient trackerClient = createTrackerClient(1, clock, degraderConfig).get(0);
    final TestLoadBalancerClient testLoadBalancerClient = (TestLoadBalancerClient) trackerClient.getTransportClient();
    final DegraderTrackerClientUpdater degraderTrackerClientUpdater = new DegraderTrackerClientUpdater(trackerClient, DEFAULT_PARTITION_ID);
    final LoadBalancerQuarantine quarantine = new LoadBalancerQuarantine(degraderTrackerClientUpdater.getTrackerClient(), config, "abc0");
    final TransportHealthCheck healthCheck = (TransportHealthCheck) quarantine.getHealthCheckClient();
    healthCheck.checkHealth(Callbacks.empty());
    final RequestContext requestContext1 = testLoadBalancerClient._requestContext;
    final Map<String, String> wireAttrs1 = testLoadBalancerClient._wireAttrs;
    healthCheck.checkHealth(Callbacks.empty());
    final RequestContext requestContext2 = testLoadBalancerClient._requestContext;
    final Map<String, String> wireAttrs2 = testLoadBalancerClient._wireAttrs;
    Assert.assertEquals(requestContext1, requestContext2);
    Assert.assertNotSame(requestContext1, requestContext2, "RequestContext should not be shared between requests.");
    Assert.assertEquals(wireAttrs1, wireAttrs2);
    Assert.assertNotSame(wireAttrs1, wireAttrs2, "Wire attributes should not be shared between requests.");
}
Also used : LoadBalancerQuarantine(com.linkedin.d2.balancer.strategies.LoadBalancerQuarantine) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) DegraderImpl(com.linkedin.util.degrader.DegraderImpl) TransportHealthCheck(com.linkedin.d2.balancer.util.healthcheck.TransportHealthCheck) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 17 with DegraderTrackerClient

use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testStateIsNotNullAndCallCountIsZero.

@Test(groups = { "small", "back-end" })
public void testStateIsNotNullAndCallCountIsZero() throws URISyntaxException {
    DegraderLoadBalancerStrategyV3 strategy = new DegraderLoadBalancerStrategyV3(new DegraderLoadBalancerStrategyConfig(5000), "DegraderLoadBalancerTest", null, DEGRADER_STATE_LISTENER_FACTORIES);
    List<DegraderTrackerClient> clients = new ArrayList<>();
    SettableClock clock1 = new SettableClock();
    SettableClock clock2 = new SettableClock();
    clients.add(getClient(URI.create("http://test.linkedin.com:3242/fdsaf"), clock1));
    clients.add(getClient(URI.create("http://test.linkedin.com:3243/fdsaf"), clock2));
    clock1.addDuration(5000);
    // this should trigger setting _state (generation id is different) with an override
    // of 0d
    getTrackerClient(strategy, null, new RequestContext(), 0, clients);
    // should not have overridden anything, and default is 0
    for (DegraderTrackerClient client : clients) {
        assertEquals(client.getDegraderControl(DEFAULT_PARTITION_ID).getOverrideDropRate(), 0d);
    }
    // this should trigger setting _state (state is null and count > 0) with an override
    // of 0d
    assertNotNull(getTrackerClient(strategy, null, new RequestContext(), -1, clients));
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) ArrayList(java.util.ArrayList) SettableClock(com.linkedin.util.clock.SettableClock) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 18 with DegraderTrackerClient

use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.

the class DegraderLoadBalancerTest method simulateAndTestOneInterval.

/**
 * simulates calling all the clients with the given QPS according to the given interval.
 * Then verify that the DegraderLoadBalancerState behaves as expected.
 * @param expectedPointsPerClient we'll verify if the points are smaller than the number given here
 * @param isCalledWithError
 * @param isCalledWithErrorForLoadBalancing
 */
private TrackerClient simulateAndTestOneInterval(long timeInterval, TestClock clock, double qps, List<DegraderTrackerClient> clients, DegraderLoadBalancerStrategyAdapter adapter, long clusterGenerationId, Integer expectedPointsPerClient, boolean isExpectingDropCallStrategyForNewState, double expectedClusterOverrideDropRate, long latency, boolean isCalledWithError, boolean isCalledWithErrorForLoadBalancing) {
    callClients(latency, qps, clients, clock, timeInterval, isCalledWithError, isCalledWithErrorForLoadBalancing);
    // create any random URIRequest because we just need a URI to be hashed to get the point in hash ring anyway
    if (clients != null && !clients.isEmpty()) {
        URIRequest request = new URIRequest(clients.get(0).getUri());
        TrackerClient client = getTrackerClient(adapter, request, new RequestContext(), clusterGenerationId, clients);
        Map<URI, Integer> pointsMap = adapter.getPointsMap();
        for (TrackerClient trackerClient : clients) {
            Integer pointsInTheRing = pointsMap.get(trackerClient.getUri());
            assertEquals(pointsInTheRing, expectedPointsPerClient);
        }
        if (isExpectingDropCallStrategyForNewState) {
            assertTrue(adapter.isStrategyCallDrop());
        } else {
            assertFalse(adapter.isStrategyCallDrop());
        }
        assertEquals(adapter.getCurrentOverrideDropRate(), expectedClusterOverrideDropRate);
        return client;
    }
    return null;
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) URIRequest(com.linkedin.d2.balancer.util.URIRequest) RequestContext(com.linkedin.r2.message.RequestContext) URI(java.net.URI)

Example 19 with DegraderTrackerClient

use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testWeightedAndLatencyDegradationBalancingRingWithPartitions.

@Test(groups = { "small", "back-end" }, dataProvider = "consistentHashAlgorithms")
public void testWeightedAndLatencyDegradationBalancingRingWithPartitions(String consistentHashAlgorithm) throws URISyntaxException {
    DegraderLoadBalancerStrategyV3 strategy = getStrategy(consistentHashAlgorithm);
    Map<URI, TrackerClient> clientsForPartition0 = new HashMap<>();
    Map<URI, TrackerClient> clientsForPartition1 = new HashMap<>();
    URI uri1 = URI.create("http://someTestService/someTestUrl");
    URI uri2 = URI.create("http://abcxfweuoeueoueoueoukeueoueoueoueoueouo/2354");
    URI uri3 = URI.create("http://slashdot/blah");
    URI uri4 = URI.create("http://idle/server");
    TestClock clock1 = new TestClock();
    TestClock clock2 = new TestClock();
    TestClock clock3 = new TestClock();
    @SuppressWarnings("serial") DegraderTrackerClient client1 = new DegraderTrackerClientImpl(uri1, new HashMap<Integer, PartitionData>() {

        {
            put(0, new PartitionData(1d));
        }
    }, new TestLoadBalancerClient(uri1), clock1, null);
    @SuppressWarnings("serial") DegraderTrackerClient client2 = new DegraderTrackerClientImpl(uri2, new HashMap<Integer, PartitionData>() {

        {
            put(0, new PartitionData(0.5d));
            put(1, new PartitionData(0.5d));
        }
    }, new TestLoadBalancerClient(uri2), clock2, null);
    @SuppressWarnings("serial") DegraderTrackerClient client3 = new DegraderTrackerClientImpl(uri3, new HashMap<Integer, PartitionData>() {

        {
            put(1, new PartitionData(1d));
        }
    }, new TestLoadBalancerClient(uri3), clock3, null);
    final int partitionId0 = 0;
    clientsForPartition0.put(client1.getUri(), client1);
    clientsForPartition0.put(client2.getUri(), client2);
    final int partitionId1 = 1;
    clientsForPartition1.put(client2.getUri(), client2);
    clientsForPartition1.put(client3.getUri(), client3);
    // force client2 to be disabled
    DegraderControl dcClient2Partition0 = client2.getDegraderControl(0);
    DegraderControl dcClient2Partition1 = client2.getDegraderControl(1);
    dcClient2Partition0.setOverrideMinCallCount(1);
    dcClient2Partition0.setMinCallCount(1);
    dcClient2Partition0.setMaxDropRate(1d);
    dcClient2Partition0.setUpStep(0.4d);
    dcClient2Partition0.setHighErrorRate(0);
    dcClient2Partition1.setOverrideMinCallCount(1);
    dcClient2Partition1.setMinCallCount(1);
    dcClient2Partition1.setMaxDropRate(1d);
    dcClient2Partition1.setUpStep(0.4d);
    dcClient2Partition1.setHighErrorRate(0);
    CallCompletion cc = client2.getCallTracker().startCall();
    clock2.addMs(1);
    cc.endCallWithError();
    // force client3 to be disabled
    DegraderControl dcClient3Partition1 = client3.getDegraderControl(1);
    dcClient3Partition1.setOverrideMinCallCount(1);
    dcClient3Partition1.setMinCallCount(1);
    dcClient3Partition1.setMaxDropRate(1d);
    dcClient3Partition1.setHighErrorRate(0);
    dcClient3Partition1.setUpStep(0.2d);
    CallCompletion cc3 = client3.getCallTracker().startCall();
    clock3.addMs(1);
    cc3.endCallWithError();
    clock1.addMs(15000);
    clock2.addMs(5000);
    clock3.addMs(5000);
    // trigger a state update
    assertNotNull(strategy.getTrackerClient(null, new RequestContext(), 1, partitionId0, clientsForPartition0));
    assertNotNull(strategy.getTrackerClient(null, new RequestContext(), 1, partitionId1, clientsForPartition1));
    assertNotNull(strategy.getRing(1, partitionId0, clientsForPartition0));
    assertNotNull(strategy.getRing(1, partitionId1, clientsForPartition1));
    // now do a basic verification to verify getTrackerClient is properly weighting things
    int calls = 10000;
    int client1Count = 0;
    int client2Count = 0;
    double tolerance = 0.05d;
    for (int i = 0; i < calls; ++i) {
        TrackerClient client = strategy.getTrackerClient(null, new RequestContext(), 1, partitionId0, clientsForPartition0);
        assertNotNull(client);
        if (client.getUri().equals(uri1)) {
            ++client1Count;
        } else {
            ++client2Count;
        }
    }
    assertTrue(Math.abs((client1Count / (double) calls) - (100 / 130d)) < tolerance);
    assertTrue(Math.abs((client2Count / (double) calls) - (30 / 130d)) < tolerance);
    client2Count = 0;
    int client3Count = 0;
    int client4Count = 0;
    for (int i = 0; i < calls; ++i) {
        TrackerClient client = strategy.getTrackerClient(null, new RequestContext(), 1, partitionId1, clientsForPartition1);
        assertNotNull(client);
        if (client.getUri().equals(uri3)) {
            ++client3Count;
        } else if (client.getUri().equals(uri2)) {
            ++client2Count;
        } else {
            ++client4Count;
        }
    }
    assertTrue(Math.abs((client3Count / (double) calls) - (80 / 110d)) < tolerance);
    assertTrue(Math.abs((client2Count / (double) calls) - (30 / 110d)) < tolerance);
    assertTrue(client4Count == 0);
}
Also used : HashMap(java.util.HashMap) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) DegraderControl(com.linkedin.util.degrader.DegraderControl) URI(java.net.URI) DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) CallCompletion(com.linkedin.util.degrader.CallCompletion) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) DegraderTrackerClientImpl(com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Example 20 with DegraderTrackerClient

use of com.linkedin.d2.balancer.clients.DegraderTrackerClient in project rest.li by linkedin.

the class DegraderLoadBalancerTest method testHighTrafficHighLatency100Clients.

@Test(groups = { "small", "back-end" })
public void testHighTrafficHighLatency100Clients() {
    Map<String, Object> myMap = lbDefaultConfig();
    Long timeInterval = 5000L;
    TestClock clock = new TestClock();
    myMap.put(PropertyKeys.CLOCK, clock);
    myMap.put(PropertyKeys.HTTP_LB_STRATEGY_PROPERTIES_UPDATE_INTERVAL_MS, timeInterval);
    Map<String, String> degraderProperties = degraderDefaultConfig();
    degraderProperties.put(PropertyKeys.DEGRADER_HIGH_ERROR_RATE, "0.5");
    degraderProperties.put(PropertyKeys.DEGRADER_LOW_ERROR_RATE, "0.2");
    DegraderImpl.Config degraderConfig = DegraderConfigFactory.toDegraderConfig(degraderProperties);
    double qps = 88;
    // test Strategy V3
    List<DegraderTrackerClient> clients = createTrackerClient(100, clock, degraderConfig);
    DegraderLoadBalancerStrategyConfig config = DegraderLoadBalancerStrategyConfig.createHttpConfigFromMap(myMap);
    DegraderLoadBalancerStrategyV3 strategyV3 = new DegraderLoadBalancerStrategyV3(config, "DegraderLoadBalancerTest", null, DEGRADER_STATE_LISTENER_FACTORIES);
    DegraderLoadBalancerStrategyAdapter strategy = new DegraderLoadBalancerStrategyAdapter(strategyV3);
    testDegraderLoadBalancerSimulator(strategy, clock, timeInterval, clients, qps, degraderConfig);
}
Also used : DegraderTrackerClient(com.linkedin.d2.balancer.clients.DegraderTrackerClient) DegraderImpl(com.linkedin.util.degrader.DegraderImpl) AtomicLong(java.util.concurrent.atomic.AtomicLong) Test(org.testng.annotations.Test) DegraderTrackerClientTest(com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)

Aggregations

DegraderTrackerClient (com.linkedin.d2.balancer.clients.DegraderTrackerClient)58 Test (org.testng.annotations.Test)46 DegraderTrackerClientTest (com.linkedin.d2.balancer.clients.DegraderTrackerClientTest)42 ArrayList (java.util.ArrayList)34 URI (java.net.URI)31 RequestContext (com.linkedin.r2.message.RequestContext)30 TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)20 DegraderImpl (com.linkedin.util.degrader.DegraderImpl)19 AtomicLong (java.util.concurrent.atomic.AtomicLong)17 DegraderControl (com.linkedin.util.degrader.DegraderControl)16 HashMap (java.util.HashMap)16 DegraderTrackerClientImpl (com.linkedin.d2.balancer.clients.DegraderTrackerClientImpl)14 CallCompletion (com.linkedin.util.degrader.CallCompletion)11 URIRequest (com.linkedin.d2.balancer.util.URIRequest)9 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)7 SettableClock (com.linkedin.util.clock.SettableClock)6 LoadBalancerQuarantine (com.linkedin.d2.balancer.strategies.LoadBalancerQuarantine)4 RestRequest (com.linkedin.r2.message.rest.RestRequest)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4