Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.


In the previous two articles, we introduced Eureka’s service registration and renewal and service removal and offline. In this article, we take a look at the last two modules, service discovery and cluster information synchronization.

Service discovery

Eureka-client

Before learning the source code for service discovery, write a test case:

@Autowired
private DiscoveryClient discoveryClient;

@GetMapping("/find")
public void test(String id){
    List<ServiceInstance> instances = discoveryClient.getInstances(id);
    System.out.println(instances);
}
Copy the code

Call the getInstances method of DiscoveryClient to obtain a list of service instances based on the service ID:

So there is a problem here, we haven’t called the microservice yet, so when is the service list pulled or cached into the local service list? The answer is that the getInstances() method of the CompositeDiscoveryClient is called here:

Intermediate call process omitted:

EurekaDiscoveryClient # getInstances() ->
DiscoveryClient # getInstancesByVipAddress() ->
                # getInstancesByVipAddress() ->  // Not the same method as above
Applications # getInstancesByVirtualHostName()
Copy the code

Check the Applications of getInstancesByVirtualHostName method:

A Map set named virtualHostNameAppMap contains the list of all services registered with Eureka.

private final Map<String, VipIndexSupport> virtualHostNameAppMap;
Copy the code

In other words, there is a value in the collection when we do not call the service manually, indicating that the service will be automatically pulled and cached after the Eureka-server project starts.

So go back to the source and find out when the discovery of the service was made. Go back to DiscoveryClient and define the task scheduling thread pool cacheRefreshExecutor in its constructor. Once defined, call initScheduledTask:

In this thread, the refreshRegistry() method is called:

In the fetchRegistry method, the real service list pull is performed:

In the fetchRegistry method, decide whether to do an incremental pull or a full pull:

1. Full pull

When the cache is null, or the data in it is empty, or is forced, a full pull is performed and getAndStoreFullRegistry is executed:

2. Incremental pull

To pull only the changes, call getAndUpdateDelta:

①② : First send an HTTP request to obtain the collection modified or added in eureka-server

③ : Judge, if the pull set is null, then full pull

The update operation, in the updateDelta method, changes according to the type

⑤ : Obtain the consistent hashcode value to verify whether the eureka-server collection is the same as the local one

If the hash value of the remote set is equal to the hash value in the cache, no need to pull, otherwise pull again.

Finally, the following variables defined in Applications are prepared in Eureka-Server and can be pulled directly.

private final AbstractQueue<Application> applications;
private final Map<String, Application> appNameApplicationMap;
private final Map<String, VipIndexSupport> virtualHostNameAppMap;
private final Map<String, VipIndexSupport> secureVirtualHostNameAppMap;
Copy the code

A key summary of the service discovery process:

  • The list of services is pulled not when the service is called, but when the project is started, there is a scheduled task to pull, which is inDiscoveryClientCan be reflected in the construction method of;
  • The instance of the service is not the data in the real-time Eureka-Server, but a locally cached data;
  • Cache updates are divided into full pull and incremental pull based on actual requirements.

Synchronizing Cluster Information

Eureka-server

Cluster synchronization occurs between Eureka – server information, mentioned in PeerAwareInstanceRegistryImpl class, the execution of the register method registering service instance, after the completion of execution replicateToPeers cluster information synchronization methods, Analyze the method in detail:

Firstly, the cluster nodes are traversed to synchronize information for each cluster information node.

Then, call replicateInstanceActionsToPeers method, according to the specific type of operation in this method the Action, choose the branch, the final call PeerEurekaNode register method:

If the final HTTP request is sent, but different from the normal registration operation, set the cluster synchronization identifier to true, indicating that the registration information is from the cluster synchronization.

When the addInstance method is run during registration, the value of isReplication is false for standalone registration and true for cluster synchronization. Using this value, you can avoid the problem of cyclic synchronization between clusters.

The last

So that concludes the six important parts of the Eureka declaration cycle. Because space is limited, can only talk about the general process, if you also want to further understand some, might as well look at the source code, after all, the source code is the best teacher.

If you think it is helpful, you can like it and forward it. Thank you very much.

Public number agriculture ginseng, add a friend, do a thumbs-up friend ah