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
- From DynamicServerListLoadBalancer load balancer for service access list
- Select the service list through the polling algorithm
- The polling algorithm is calculated by a modular algorithm