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;
}
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;
}
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"));
}
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"));
}
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);
}
Aggregations