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

How does the Ribbon get an example of a registry

Action is the ladder of success, the more action, the higher the

Imagine where to start

In fact, we have already said that the load balancer selects a service from the registry that can be used. If I use the Eureka registry, it should also be obtained from the client of the registry. So let’s see if there are any clues in the initialization of the load balancer

Obtaining the Configuration Flowchart

The Ribbon client configuration class

RibbonClientConfiguration client configuration class, have a look at what it is initialized, see the main logical part, which created the routing rules, rules of ping, updater service list, list, create, filter, and context load balancer, etc

public class RibbonClientConfiguration {
    // Connection timeout time
	public static final int DEFAULT_CONNECT_TIMEOUT = 1000;
	// Read timeout time
	public static final int DEFAULT_READ_TIMEOUT = 1000;
	@RibbonClientName
	private String name = "client";
    // Ribbon client configuration
	@Bean
	@ConditionalOnMissingBean
	public IClientConfig ribbonClientConfig(a) {... }// Ribbon routing rules
	@Bean
	@ConditionalOnMissingBean
	public IRule ribbonRule(IClientConfig config) {... }// Ping the route
	@Bean
	@ConditionalOnMissingBean
	public IPing ribbonPing(IClientConfig config) {... }// Ribbon Service list
	@Bean
	@ConditionalOnMissingBean
	@SuppressWarnings("unchecked")
	public ServerList<Server> ribbonServerList(IClientConfig config) {... }// Ribbon Service list updater
	@Bean
	@ConditionalOnMissingBean
	public ServerListUpdater ribbonServerListUpdater(IClientConfig config) {... }// Load balancer
	@Bean
	@ConditionalOnMissingBean
	public ILoadBalancer ribbonLoadBalancer(IClientConfig config, ServerList
       
         serverList, ServerListFilter
        
          serverListFilter, IRule rule, IPing ping, ServerListUpdater serverListUpdater)
        
        {
		if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {
			return this.propertiesFactory.get(ILoadBalancer.class, config, name);
		}
		return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
				serverListFilter, serverListUpdater);
	}
    // Service list filter
	@Bean
	@ConditionalOnMissingBean
	@SuppressWarnings("unchecked")
	public ServerListFilter<Server> ribbonServerListFilter(IClientConfig config) {... }// ribbon load balancing context
	@Bean
	@ConditionalOnMissingBean
	public RibbonLoadBalancerContext ribbonLoadBalancerContext(ILoadBalancer loadBalancer, IClientConfig config, RetryHandler retryHandler) {... }// Retry the processor
	@Bean
	@ConditionalOnMissingBean
	public RetryHandler retryHandler(IClientConfig config) {... }}Copy the code

Create a load balancer. RibbonLoadBalancer

RibbonLoadBalancer is configured according to the ribbonLoadBalancer parameters initialized by other methods. The ribbonLoadBalancer includes rules, Ping mechanism, and address of the service you want to access. The default load balancer is ZoneAwareLoadBalancer

@Bean
@ConditionalOnMissingBean
public ILoadBalancer ribbonLoadBalancer(IClientConfig config, ServerList
       
         serverList, ServerListFilter
        
          serverListFilter, IRule rule, IPing ping, ServerListUpdater serverListUpdater)
        
        {
    if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {
        return this.propertiesFactory.get(ILoadBalancer.class, config, name);
    }
    return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
            serverListFilter, serverListUpdater);
}
Copy the code

Default load balancer ZoneAwareLoadBalancer

The load balancer inherited DynamicServerListLoadBalancer dynamic service list load balancer, a look is what we need to load balancer

public ZoneAwareLoadBalancer(IClientConfig clientConfig, IRule rule, IPing ping, ServerList
       
         serverList, ServerListFilter
        
          filter, ServerListUpdater serverListUpdater)
        
        {
    super(clientConfig, rule, ping, serverList, filter, serverListUpdater);
}
Copy the code

Here the super method which is DynamicServerListLoadBalancer * * * * here

The dynamic load balancer DynamicServerListLoadBalancer service list

public DynamicServerListLoadBalancer(IClientConfig clientConfig, IRule rule, IPing ping, ServerList
       
         serverList, ServerListFilter
        
          filter, ServerListUpdater serverListUpdater)
        
        {
    super(clientConfig, rule, ping);
    this.serverListImpl = serverList;
    this.filter = filter;
    this.serverListUpdater = serverListUpdater;
    if (filter instanceof AbstractServerListFilter) {
        ((AbstractServerListFilter) filter).
            setLoadBalancerStats(getLoadBalancerStats());
    }
    // Core methods, other methods are not carefully looked at first
    restOfInit(clientConfig);
}
Copy the code

RestOfInit method

Inside this method is the real operation to get the service instance list, and enable subsequent operations such as registry push new instance change information or pull instance change

void restOfInit(IClientConfig clientConfig) {
    boolean primeConnection = this.isEnablePrimingConnections();
    // Enables and initializes the loading of new service instances, such as registry push or pull operations, described below
    enableAndInitLearnNewServersFeature();
    // Get the service list operationupdateListOfServers(); . }Copy the code

UpdateListOfServers ()

@VisibleForTesting
public void updateListOfServers(a) {
    List<T> servers = new ArrayList<T>();
    if(serverListImpl ! =null) {
        // Get the service list information
        servers = serverListImpl.getUpdatedListOfServers();
        LOGGER.debug("List of Servers for {} obtained from Discovery client: {}",
                getIdentifier(), servers);
    }
    // Update the list of all services in LoadBalancer
    updateAllServerList(servers);
}
Copy the code

GetUpdatedListOfServers ()

Is take the DiscoveryEnabledNIWSServerList this class the following getUpdatedListOfServers () operation, is take the list of service registry

@Override
public List<DiscoveryEnabledServer> getUpdatedListOfServers(a){
    // Get the service method
    return obtainServersViaDiscovery();
}
Copy the code

Access to the service discovery obtainServersViaDiscovery list

private List<DiscoveryEnabledServer> obtainServersViaDiscovery(a) {
    List<DiscoveryEnabledServer> serverList = new ArrayList<DiscoveryEnabledServer>();
    Return an empty list if the client is empty for the provider
    if (eurekaClientProvider == null || eurekaClientProvider.get() == null) {
        logger.warn("EurekaClient has not been initialized yet, returning an empty list");
        return new ArrayList<DiscoveryEnabledServer>();
    }
    // Get the Eureka client operation
    EurekaClient eurekaClient = eurekaClientProvider.get();
    // The service address is not empty
    if(vipAddresses! =null) {for (String vipAddress : vipAddresses.split(",")) {
            // Get the service instance through the Eureka client
        List<InstanceInfo> listOfInstanceInfo = 
            eurekaClient.getInstancesByVipAddress(vipAddress, isSecure, targetRegion);
        for (InstanceInfo ii : listOfInstanceInfo) {
                // The service instance must be started or normal
            if (ii.getStatus().equals(InstanceStatus.UP)) {
                // Create a service and add it to the service listDiscoveryEnabledServer des = createServer(ii, isSecure, shouldUseIpAddr); serverList.add(des); }}}}// Return to the list of services
    return serverList;
}
Copy the code

UpdateAllServerList (Servers)

protected void updateAllServerList(List<T> ls) {
    if (serverListUpdateInProgress.compareAndSet(false.true)) {
        try {
            for (T s : ls) {
                s.setAlive(true); 
            }
            setServersList(ls);
            // Ping service description
            super.forceQuickPing();
        } finally {
            serverListUpdateInProgress.set(false); }}}Copy the code

Set the service list setServersList

The service client gets the service list instance into the BaseLoadBalancer allServerList, and the client gets the service list instance into the serversInZones haspMap

@Override
public void setServersList(List lsrv) {
    // Place the instance of the service list obtained by the service client into the allServerList of BaseLoadBalancer
    super.setServersList(lsrv);
    // Put the client's service list instance into the serversInZones haspMap
    List<T> serverList = (List<T>) lsrv;
    Map<String, List<Server>> serversInZones = new HashMap<String, List<Server>>();
    for (Server server : serverList) {
        getLoadBalancerStats().getSingleServerStat(server);
        String zone = server.getZone();
        if(zone ! =null) {
            zone = zone.toLowerCase();
            List<Server> servers = serversInZones.get(zone);
            if (servers == null) {
                servers = new ArrayList<Server>();
                serversInZones.put(zone, servers);
            }
            servers.add(server);
        }
    }
    setServerListForZones(serversInZones);
}
Copy the code

summary

  1. Create some necessary prerequisite components, such as ZoneAwareLoadBalancer, PollingServerListUpdater, and so on
  2. Obtain the service list from eureka Client
  3. Update the internal service list of the load balancer based on the obtained service list information