Jon Morgan
Jon Morgan

Reputation: 31

Netflix Ribbon and Polling for Server List

I'm currently trying out the Netflix Ribbon library and I'm trying to dynamically update a list of available endpoints to load balance.

I've successfully created a httpResourceGroup that uses a configuration based server list, e.g.:

httpResourceGroup = Ribbon.createHttpResourceGroup("searchServiceClient",
                    ClientOptions.create()
                            .withMaxAutoRetriesNextServer(3)
                            .withLoadBalancerEnabled(true)
                            .withConfigurationBasedServerList(serverList))

However, I'd like to be able to use a DynamicServerList in the httpResourceGroup. I've managed to build a load balancer as follows:

LoadBalancerBuilder.<Server>newBuilder()
                   .withDynamicServerList(servicesList)
                   .buildDynamicServerListLoadBalancer();

but I can't find a way to swap out the load balancer configured by the httpResourceGroup ClientOptions.

Anyone know how I can do this?

Upvotes: 1

Views: 2442

Answers (1)

hayduke
hayduke

Reputation: 121

The solution is to not specify withConfigurationBasedServerList() when constructing an HttpResourceGroup since this I believe this is meant for a fixed list though I am not sure. There are many ways to initialize a dynamic load balancer (typically you would never swap it out, but reuse the same load balancer and swap out new Servers as they become available or go away. The most straightforward way to do this might be via Archaius-based configuration.

Option 1

Create a config.properties file on the classpath containing the following

ribbon.NIWSServerListClassName=com.example.MyServerList
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule

Option 2

    System.setProperty("ribbon.NIWSServerListClassName", "com.example.MyServerList");
    System.setProperty("ribbon.NFLoadBalancerRuleClassName", "com.netflix.loadbalancer.RoundRobinRule");

Create a ServerList implementation

import java.util.Arrays;
import java.util.List;

import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;


public class MyServerList implements ServerList<Server> {

    @Override
    public final List<Server> getUpdatedListOfServers() {
        // TODO do some fancy stuff here
        return Arrays.asList(new Server("1.2.3.4", 8888), new Server("5.6.7.8", 9999));
    }

    @Override
    public final List<Server> getInitialListOfServers() {
        return Arrays.asList(new Server("1.2.3.4", 8888), new Server("5.6.7.8", 9999));
    }    
}

Run the code

HttpResourceGroup httpResourceGroup = Ribbon.createHttpResourceGroup("searchServiceClient",
                        ClientOptions.create()
                                .withMaxAutoRetriesNextServer(3);
    HttpRequestTemplate<ByteBuf> recommendationsByUserIdTemplate = httpResourceGroup.newTemplateBuilder("recommendationsByUserId", ByteBuf.class)
                .withMethod("GET")
                .withUriTemplate("/users/{userId}/recommendations")
                .withFallbackProvider(new RecommendationServiceFallbackHandler())
                .withResponseValidator(new RecommendationServiceResponseValidator())
                .build();
    Observable<ByteBuf> result = recommendationsByUserIdTemplate.requestBuilder()
                            .withRequestProperty("userId", “user1")
                            .build()
                            .observe();

It sounds like you already have a ServerList implementation which is where you would do any event driven updates to your server list, but keep the load balancer the same.

Upvotes: 3

Related Questions