D-Haven LoadBalance is a small library to assist with common load balancing tasks. It is intended to be used with other projects I’m working on, which entail a small set of the same type of resource so that work can be spread among the instances. For example, choosing between an instance of a microservice.
You can either use the raw load balancers for your application (see below), or use the built in URI handlers for local load balancing for your own services.
We have dependency injection support for the HttpClientFactory to resolve a named resource by name. Manual configuraiton looks like this:
services.AddLoadBalancing(registrar => { registrar.RegisterRoundRobin("service-name", new Uri("https://something"), new Uri("https://something:444"), new Uri("https://something:445")); });
When you actually need to access your service you claim the IHttpClientFactory as a dependency, and have it create your HttpClient locally:
using (var client = factory.CreateClient()) { var response = await client.GetAsync("http://service-name/one/two/three"); }
The load balancing algorithms are pretty common. The ILoadBalancer implementation take an IList of resources to allow you to provide your own implementation. If you don’t supply the IList, the LoadBalancer will create a default implementation for you.
Using the code is fairly simple.
// Set up: var balancer = new RoundRobinBalancer<MyResource>(resources);
// You can add and remove resources like this: balancer.Resources.Add(new MyResource(23432)); balancer.Resources.Remove(23);
// And you retrieve the instance to use like this: var myResource = balancer.GetResource();
Also included is an adaptive load balancer if you have a way of testing if the resource is overtaxed. It returns the lowest scored resource, and you provide the function to do the scoring. I recommend care with the Adaptive load balancers because it has to scan the whole list to find the best fit. Your scoring function can have a big impact on how useful it is.