Search in sources :

Example 1 with SimpleLoadBalancer

use of com.linkedin.d2.balancer.simple.SimpleLoadBalancer in project rest.li by linkedin.

the class ZKFSTogglingLoadBalancerFactoryImpl method createLoadBalancer.

@Override
public TogglingLoadBalancer createLoadBalancer(ZKConnection zkConnection, ScheduledExecutorService executorService) {
    _log.info("Using d2ServicePath: " + _d2ServicePath);
    ZooKeeperPermanentStore<ClusterProperties> zkClusterRegistry = createPermanentStore(zkConnection, ZKFSUtil.clusterPath(_baseZKPath), new ClusterPropertiesJsonSerializer());
    ZooKeeperPermanentStore<ServiceProperties> zkServiceRegistry = createPermanentStore(zkConnection, ZKFSUtil.servicePath(_baseZKPath, _d2ServicePath), new ServicePropertiesJsonSerializer());
    ZooKeeperEphemeralStore<UriProperties> zkUriRegistry = createEphemeralStore(zkConnection, ZKFSUtil.uriPath(_baseZKPath), new UriPropertiesJsonSerializer(), new UriPropertiesMerger(), _useNewEphemeralStoreWatcher);
    FileStore<ClusterProperties> fsClusterStore = createFileStore("clusters", new ClusterPropertiesJsonSerializer());
    FileStore<ServiceProperties> fsServiceStore = createFileStore(_d2ServicePath, new ServicePropertiesJsonSerializer());
    FileStore<UriProperties> fsUriStore = createFileStore("uris", new UriPropertiesJsonSerializer());
    PropertyEventBus<ClusterProperties> clusterBus = new PropertyEventBusImpl<ClusterProperties>(executorService);
    PropertyEventBus<ServiceProperties> serviceBus = new PropertyEventBusImpl<ServiceProperties>(executorService);
    PropertyEventBus<UriProperties> uriBus = new PropertyEventBusImpl<UriProperties>(executorService);
    // This ensures the filesystem store receives the events from the event bus so that
    // it can keep a local backup.
    clusterBus.register(fsClusterStore);
    serviceBus.register(fsServiceStore);
    uriBus.register(fsUriStore);
    TogglingPublisher<ClusterProperties> clusterToggle = _factory.createClusterToggle(zkClusterRegistry, fsClusterStore, clusterBus);
    TogglingPublisher<ServiceProperties> serviceToggle = _factory.createServiceToggle(zkServiceRegistry, fsServiceStore, serviceBus);
    TogglingPublisher<UriProperties> uriToggle = _factory.createUriToggle(zkUriRegistry, fsUriStore, uriBus);
    SimpleLoadBalancerState state = new SimpleLoadBalancerState(executorService, uriBus, clusterBus, serviceBus, _clientFactories, _loadBalancerStrategyFactories, _sslContext, _sslParameters, _isSSLEnabled, _clientServicesConfig);
    SimpleLoadBalancer balancer = new SimpleLoadBalancer(state, _lbTimeout, _lbTimeoutUnit);
    TogglingLoadBalancer togLB = _factory.createBalancer(balancer, state, clusterToggle, serviceToggle, uriToggle);
    togLB.start(new Callback<None>() {

        @Override
        public void onError(Throwable e) {
            _log.warn("Failed to run start on the TogglingLoadBalancer, may not have registered " + "SimpleLoadBalancer and State with JMX.");
        }

        @Override
        public void onSuccess(None result) {
            _log.info("Registered SimpleLoadBalancer and State with JMX.");
        }
    });
    return togLB;
}
Also used : ServicePropertiesJsonSerializer(com.linkedin.d2.balancer.properties.ServicePropertiesJsonSerializer) UriPropertiesMerger(com.linkedin.d2.balancer.properties.UriPropertiesMerger) TogglingLoadBalancer(com.linkedin.d2.balancer.util.TogglingLoadBalancer) UriPropertiesJsonSerializer(com.linkedin.d2.balancer.properties.UriPropertiesJsonSerializer) ClusterPropertiesJsonSerializer(com.linkedin.d2.balancer.properties.ClusterPropertiesJsonSerializer) UriProperties(com.linkedin.d2.balancer.properties.UriProperties) SimpleLoadBalancerState(com.linkedin.d2.balancer.simple.SimpleLoadBalancerState) SimpleLoadBalancer(com.linkedin.d2.balancer.simple.SimpleLoadBalancer) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) PropertyEventBusImpl(com.linkedin.d2.discovery.event.PropertyEventBusImpl) ClusterProperties(com.linkedin.d2.balancer.properties.ClusterProperties) None(com.linkedin.common.util.None)

Example 2 with SimpleLoadBalancer

use of com.linkedin.d2.balancer.simple.SimpleLoadBalancer in project rest.li by linkedin.

the class RetryClientTest method prepareLoadBalancer.

public SimpleLoadBalancer prepareLoadBalancer(List<String> uris) throws URISyntaxException {
    String serviceName = "retryService";
    String clusterName = "cluster";
    String path = "";
    String strategyName = "degrader";
    // setup partition
    Map<URI, Map<Integer, PartitionData>> partitionDescriptions = new HashMap<URI, Map<Integer, PartitionData>>();
    for (String uri : uris) {
        final URI foo = URI.create(uri);
        Map<Integer, PartitionData> foo1Data = new HashMap<Integer, PartitionData>();
        foo1Data.put(0, new PartitionData(1.0));
        partitionDescriptions.put(foo, foo1Data);
    }
    DegraderLoadBalancerStrategyV3 strategy = new DegraderLoadBalancerStrategyV3(new DegraderLoadBalancerStrategyConfig(5000), serviceName, null);
    List<LoadBalancerState.SchemeStrategyPair> orderedStrategies = new ArrayList<LoadBalancerState.SchemeStrategyPair>();
    orderedStrategies.add(new LoadBalancerState.SchemeStrategyPair("http", strategy));
    PartitionAccessor accessor = new TestRetryPartitionAccessor();
    SimpleLoadBalancer balancer = new SimpleLoadBalancer(new PartitionedLoadBalancerTestState(clusterName, serviceName, path, strategyName, partitionDescriptions, orderedStrategies, accessor));
    return balancer;
}
Also used : SimpleLoadBalancer(com.linkedin.d2.balancer.simple.SimpleLoadBalancer) HashMap(java.util.HashMap) DegraderLoadBalancerStrategyConfig(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyConfig) ArrayList(java.util.ArrayList) PartitionedLoadBalancerTestState(com.linkedin.d2.balancer.PartitionedLoadBalancerTestState) URI(java.net.URI) LoadBalancerState(com.linkedin.d2.balancer.LoadBalancerState) DegraderLoadBalancerStrategyV3(com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyV3) PartitionAccessor(com.linkedin.d2.balancer.util.partitions.PartitionAccessor) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with SimpleLoadBalancer

use of com.linkedin.d2.balancer.simple.SimpleLoadBalancer in project rest.li by linkedin.

the class RetryClientTest method testRetryNoAvailableHosts.

@Test
public void testRetryNoAvailableHosts() throws Exception {
    SimpleLoadBalancer balancer = prepareLoadBalancer(Arrays.asList("http://test.linkedin.com/retry1", "http://test.linkedin.com/retry2"));
    DynamicClient dynamicClient = new DynamicClient(balancer, null);
    RetryClient client = new RetryClient(dynamicClient, 3);
    URI uri = URI.create("d2://retryService?arg1=empty&arg2=empty");
    RestRequest restRequest = new RestRequestBuilder(uri).build();
    TrackerClientTest.TestCallback<RestResponse> restCallback = new TrackerClientTest.TestCallback<RestResponse>();
    client.restRequest(restRequest, restCallback);
    assertNull(restCallback.t);
    assertNotNull(restCallback.e);
    assertTrue(restCallback.e.toString().contains("retryService is in a bad state"));
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) SimpleLoadBalancer(com.linkedin.d2.balancer.simple.SimpleLoadBalancer) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) URI(java.net.URI) Test(org.testng.annotations.Test)

Example 4 with SimpleLoadBalancer

use of com.linkedin.d2.balancer.simple.SimpleLoadBalancer in project rest.li by linkedin.

the class RetryClientTest method testRetryOverLimit.

@Test
public void testRetryOverLimit() throws Exception {
    SimpleLoadBalancer balancer = prepareLoadBalancer(Arrays.asList("http://test.linkedin.com/retry1", "http://test.linkedin.com/retry2"));
    DynamicClient dynamicClient = new DynamicClient(balancer, null);
    RetryClient client = new RetryClient(dynamicClient, 1);
    URI uri = URI.create("d2://retryService?arg1=empty&arg2=empty");
    RestRequest restRequest = new RestRequestBuilder(uri).build();
    TrackerClientTest.TestCallback<RestResponse> restCallback = new TrackerClientTest.TestCallback<RestResponse>();
    client.restRequest(restRequest, restCallback);
    assertNull(restCallback.t);
    assertNotNull(restCallback.e);
    assertTrue(restCallback.e.getMessage().contains("Data not available"));
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) SimpleLoadBalancer(com.linkedin.d2.balancer.simple.SimpleLoadBalancer) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) URI(java.net.URI) Test(org.testng.annotations.Test)

Example 5 with SimpleLoadBalancer

use of com.linkedin.d2.balancer.simple.SimpleLoadBalancer in project rest.li by linkedin.

the class SimpleLoadBalancerTest method testGetPartitionInfoOrdering.

/**
   * This tests the getPartitionInfo() when given a collection of keys (actually a test for KeyMapper.mapKeysV3()).
   */
@Test
public void testGetPartitionInfoOrdering() throws Exception {
    String serviceName = "articles";
    String clusterName = "cluster";
    String path = "path";
    String strategyName = "degrader";
    // setup 3 partitions. Partition 1 and Partition 2 both have server1 - server3. Partition 3 only has server1.
    Map<URI, Map<Integer, PartitionData>> partitionDescriptions = new HashMap<URI, Map<Integer, PartitionData>>();
    final URI server1 = new URI("http://foo1.com");
    Map<Integer, PartitionData> server1Data = new HashMap<Integer, PartitionData>();
    server1Data.put(1, new PartitionData(1.0));
    server1Data.put(2, new PartitionData(1.0));
    server1Data.put(3, new PartitionData(1.0));
    partitionDescriptions.put(server1, server1Data);
    final URI server2 = new URI("http://foo2.com");
    Map<Integer, PartitionData> server2Data = new HashMap<Integer, PartitionData>();
    server2Data.put(1, new PartitionData(1.0));
    server2Data.put(2, new PartitionData(1.0));
    partitionDescriptions.put(server2, server2Data);
    final URI server3 = new URI("http://foo3.com");
    Map<Integer, PartitionData> server3Data = new HashMap<Integer, PartitionData>();
    server3Data.put(1, new PartitionData(1.0));
    server3Data.put(2, new PartitionData(1.0));
    partitionDescriptions.put(server3, server3Data);
    //setup strategy which involves tweaking the hash ring to get partitionId -> URI host
    List<LoadBalancerState.SchemeStrategyPair> orderedStrategies = new ArrayList<LoadBalancerState.SchemeStrategyPair>();
    LoadBalancerStrategy strategy = new TestLoadBalancerStrategy(partitionDescriptions);
    orderedStrategies.add(new LoadBalancerState.SchemeStrategyPair("http", strategy));
    //setup the partition accessor which can only map keys from 1 - 3.
    PartitionAccessor accessor = new TestPartitionAccessor();
    URI serviceURI = new URI("d2://" + serviceName);
    SimpleLoadBalancer balancer = new SimpleLoadBalancer(new PartitionedLoadBalancerTestState(clusterName, serviceName, path, strategyName, partitionDescriptions, orderedStrategies, accessor));
    List<Integer> keys = new ArrayList<Integer>();
    keys.add(1);
    keys.add(2);
    keys.add(3);
    keys.add(123);
    HostToKeyMapper<Integer> result = balancer.getPartitionInformation(serviceURI, keys, 3, 123);
    Assert.assertEquals(result.getLimitHostPerPartition(), 3);
    Assert.assertEquals(1, result.getUnmappedKeys().size());
    Assert.assertEquals(123, (int) result.getUnmappedKeys().iterator().next().getKey());
    //partition 0 should be null
    Assert.assertNull(result.getPartitionInfoMap().get(0));
    // results for partition 1 should contain server1, server2 and server3
    KeysAndHosts<Integer> keysAndHosts1 = result.getPartitionInfoMap().get(1);
    Assert.assertTrue(keysAndHosts1.getKeys().size() == 1);
    Assert.assertTrue(keysAndHosts1.getKeys().iterator().next() == 1);
    List<URI> ordering1 = keysAndHosts1.getHosts();
    // results for partition 2 should be the same as partition1.
    KeysAndHosts<Integer> keysAndHosts2 = result.getPartitionInfoMap().get(2);
    Assert.assertTrue(keysAndHosts2.getKeys().size() == 1);
    Assert.assertTrue(keysAndHosts2.getKeys().iterator().next() == 2);
    List<URI> ordering2 = keysAndHosts2.getHosts();
    //for partition 3
    KeysAndHosts<Integer> keysAndHosts3 = result.getPartitionInfoMap().get(3);
    Assert.assertTrue(keysAndHosts3.getKeys().size() == 1);
    Assert.assertTrue(keysAndHosts3.getKeys().iterator().next() == 3);
    List<URI> ordering3 = keysAndHosts3.getHosts();
    // Just compare the size and contents of the list, not the ordering.
    Assert.assertTrue(ordering1.size() == 3);
    List<URI> allServers = new ArrayList<>();
    allServers.add(server1);
    allServers.add(server2);
    allServers.add(server3);
    Assert.assertTrue(ordering1.containsAll(allServers));
    Assert.assertTrue(ordering2.containsAll(allServers));
    Assert.assertEquals(ordering1, ordering2);
    Assert.assertEquals(ordering3.get(0), server1);
    Assert.assertTrue(result.getPartitionsWithoutEnoughHosts().containsKey(3));
    Assert.assertEquals((int) result.getPartitionsWithoutEnoughHosts().get(3), 2);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) LoadBalancerStrategy(com.linkedin.d2.balancer.strategies.LoadBalancerStrategy) PartitionedLoadBalancerTestState(com.linkedin.d2.balancer.PartitionedLoadBalancerTestState) URI(java.net.URI) LoadBalancerState(com.linkedin.d2.balancer.LoadBalancerState) DefaultPartitionAccessor(com.linkedin.d2.balancer.util.partitions.DefaultPartitionAccessor) PartitionAccessor(com.linkedin.d2.balancer.util.partitions.PartitionAccessor) PartitionData(com.linkedin.d2.balancer.properties.PartitionData) Map(java.util.Map) HashMap(java.util.HashMap) Test(org.testng.annotations.Test)

Aggregations

SimpleLoadBalancer (com.linkedin.d2.balancer.simple.SimpleLoadBalancer)17 URI (java.net.URI)14 HashMap (java.util.HashMap)14 Test (org.testng.annotations.Test)14 LoadBalancerStrategy (com.linkedin.d2.balancer.strategies.LoadBalancerStrategy)12 ArrayList (java.util.ArrayList)11 ClusterProperties (com.linkedin.d2.balancer.properties.ClusterProperties)10 ServiceProperties (com.linkedin.d2.balancer.properties.ServiceProperties)10 UriProperties (com.linkedin.d2.balancer.properties.UriProperties)10 Map (java.util.Map)10 TransportClientFactory (com.linkedin.r2.transport.common.TransportClientFactory)9 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)8 LoadBalancerStrategyFactory (com.linkedin.d2.balancer.strategies.LoadBalancerStrategyFactory)8 LoadBalancerState (com.linkedin.d2.balancer.LoadBalancerState)7 DegraderLoadBalancerStrategyFactoryV3 (com.linkedin.d2.balancer.strategies.degrader.DegraderLoadBalancerStrategyFactoryV3)7 RequestContext (com.linkedin.r2.message.RequestContext)7 None (com.linkedin.common.util.None)6 PartitionedLoadBalancerTestState (com.linkedin.d2.balancer.PartitionedLoadBalancerTestState)6 URIRequest (com.linkedin.d2.balancer.util.URIRequest)6 PartitionAccessor (com.linkedin.d2.balancer.util.partitions.PartitionAccessor)6