Make writing a habit together! This is the 14th day of my participation in the “Gold Digging Day New Plan · April More Text Challenge”. Click here for more details

Explains the Ribbon service selection principle

Don’t complain when you encounter difficulties. Since you can’t change the past, try to change the future

How do YOU get the Ribbon registry? How do you get the Ribbon

Where to start

If you want to think about when a service selection is made, specify that a specific service selection is made when an access request is made, so let’s look at this implementation code and see if there is any specific code in there

public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
        throws IOException {
    ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
    Server server = getServer(loadBalancer, hint);
    if (server == null) {
        throw new IllegalStateException("No instances available for " + serviceId);
    }
    RibbonServer ribbonServer = new RibbonServer(serviceId, server,
            isSecure(server, serviceId),
            serverIntrospector(serviceId).getMetadata(server));

    return execute(serviceId, ribbonServer, request);
}
Copy the code

GetServer (loadBalancer, hint) : getServer(loadBalancer, hint)

Select the service schematic

Source code analysis

1. DynamicServerListLoadBalancer access service

In fact he is to obtain the load balancer service list getServer (loadBalancer, hint), the load balancer is DynamicServerListLoadBalancer, Before he is defined in RibbonClientConfiguration, actually we look at the chart, it has access to the two service node [192.168.0.107:9100, 192.168.0.107:9200]

2. Select a loadBalancer service

LoadBalancer. ChooseServer actually walking is the way this selection service BaseLoadBalancer chooseServer method in a class

protected Server getServer(ILoadBalancer loadBalancer, Object hint) {
    if (loadBalancer == null) {
        return null;
    }
    returnloadBalancer.chooseServer(hint ! =null ? hint : "default");
}
Copy the code

In fact, the service is selected by certain service selection rules, the rule. Choose (key) code is the core selection rule

public Server chooseServer(Object key) {
    if (counter == null) {
        counter = createCounter();
    }
    counter.increment();
    if (rule == null) {
        return null;
    } else {
        try {
            // Instance selection algorithm
            return rule.choose(key);
        } catch (Exception e) {
            logger.warn("LoadBalancer [{}]: Error choosing server for key {}", 
                        name, key, e);
            return null; }}}Copy the code

3. Select services based on polling rules

The default service selection rule is polling algorithm, is one of the visit, chooseRoundRobinAfterFiltering this method is the most important, he is in the load balancer service list into the inside through the loop algorithm to select a come out, after we enter this method inside and see

@Override
public Server choose(Object key) {
    ILoadBalancer lb = getLoadBalancer();
    Optional<Server> server = getPredicate()
        .chooseRoundRobinAfterFiltering(lb.getAllServers(), key);
    if (server.isPresent()) {
        return server.get();
    } else {
        return null; }}Copy the code

4. Select filter chooseRoundRobinAfterFiltering polling algorithm

The getEligibleServers method is used to select the appropriate List of services and return a set of lists. The new service selection is then selected using the incrementAndGetModulo(net.size ()) algorithm

    public Optional<Server> chooseRoundRobinAfterFiltering(List
       
         servers, Object loadBalancerKey)
        {
        List<Server> eligible = getEligibleServers(servers, loadBalancerKey);
        if (eligible.size() == 0) {
            return Optional.absent();
        }
        return Optional.of(eligible.get(incrementAndGetModulo(eligible.size())));
    }
Copy the code

5. IncrementAndGetModulo algorithm

In an infinite loop, the current value is recorded by an atomic class nextIndex, and then the remainder is set to current and returned by the current value +1. In fact, it calculates an index value, which must be less than the size of the service list. Because it needs to get a value from the List collection

private int incrementAndGetModulo(int modulo) {
    for (;;) {
        int current = nextIndex.get();
        int next = (current + 1) % modulo;
        if (nextIndex.compareAndSet(current, next) && current < modulo)
            returncurrent; }}Copy the code

Eligible. Get (current) obtains a service node and returns it to the request for subsequent access

summary

  1. From DynamicServerListLoadBalancer load balancer for service access list
  2. Select the service list through the polling algorithm
  3. The polling algorithm is calculated by a modular algorithm