[Source code analysis] How does the Nacos server update and save registry information?

Article directory


We know that after the service is registered with Nacos, Nacos needs to save the service instance information, so how does Nacos save it?
First, let's analyze the structure of the Nacos registry.
We know that Nacos has three levels of namespace, group, and cluster, and they are all used for isolation.
Among them, the Cluster is divided into persistent instances and temporary instances. They are both Set types.
The persistent instance will not be deleted from the registry even if the service is disconnected, while the temporary instance will be, but the temporary instance will be registered in the registry again every time the service is restarted.
Therefore, for the Nacos registry, the approximate structure can be guessed as a three-layer Map structure. The approximate structure is as follows:
Map<namespace, Map<group, Map<clusterName, Cluster>(serviceName)>>
can be analyzed, and the Nacos registry The structure is that a namespace will have multiple groups, and each group has multiple specific services. These services appear in the form of clusters, so in the cluster cluster, the last specific instance will be included.
insert image description here
insert image description here
insert image description here
So now that we have a general understanding, let's see how this three-layer Map structure is created.
When we send an HTTP request to Nacos to request to register an instance, the Nacos server will call the following method:
insert image description here
and this method will finally call the following method, which is used to create a Servic instance.
insert image description here

The first is the innermost Map<ClusterName, Cluster>. It can be found that the inside of the Cluster is the two Set collections that store temporary and persistent instances we just mentioned.
insert image description here

And the structure of this Service is
insert image description here

And we can see that at the beginning, we will first call the following method to determine whether the Service has been created, and if it has been created, it can be reused directly.
insert image description here
insert image description here

It can be found that the returned result here is Service, that is, the current String is actually our group.
In the serviceMap structure below, the first String is actually our namespace.
The second String is actually our group. There can be multiple Services in a group, and there can be multiple service clusters in a Service.
insert image description here

Then we start to see how to put specific methods into the Service
insert image description here

The putService method here is to put our service into the Map structure.
It can be found that in order to ensure concurrency safety in multi-threaded situations, Nacos even uses double retrieval
insert image description here

Then the last line gets the corresponding group from the previous Map<group,Service> structure, and then puts the service name into this group: service instance.
Then let's look at the init method. This init method is actually to initialize the heartbeat of all instances of the cluster in all services.
This will create a timed task, which will get all the instances and judge whether the heartbeat is sent back within 15s. If not, it will set the healthy state of the instance to false, and if it exceeds 30s, then the current Instances will be culled.
insert image description here
insert image description here

After understanding the above process and creating the Service, we can inject the corresponding instance into the Service after we get the Service.
insert image description here

Adding instances here is a full addition, first get all the existing instances, and then add the current new instance.
insert image description here
insert image description here

Here is a Datum, the key is the instance name, and the value is the specific information of the instance.
insert image description here

And this allIps can get all the instances in the Cluster
insert image description here

And here begins to distinguish whether to use CP or AP.
insert image description here

At this point, all instances have been obtained from the Cluster, so we just need to perform some processing and conversion on it, and then we have obtained the information of all instances in the memory.
Pay special attention to the idea of ​​a CopyOnWrite.
We know that the instance information is stored in memory. At this time, he first gets all the instances, and then creates a new collection to store the instances, instead of directly modifying and adding to the Set in memory.
insert image description here

After this method is executed, we have obtained both the newly added instance and the existing instance in memory.
After that, we will put all these instances into the cluster, but we still have to choose two modes of instances.
insert image description here

And here is obviously a delegate method, using the DelegateConsistencyServiceImpl class. To call Distro or Raft, you need to judge the instance type.
insert image description here

At this time, according to the type of the key, it will be judged whether to put it into the temporary or persistent service.

insert image description here
insert image description here
insert image description here

Here, if you choose a temporary instance, then use Distro to create it, that is, use the AP protocol, and if it is a persistent instance, use Raft.
Because we know that both Raft and Paxos are consensus protocols, and they both choose CP.

//AP:EphemeralConsistencyService --->Distro
//CP:PersistentConsistencyService --->Raft

Therefore, our differences have already arisen here. The specific use of AP or CP depends on the protocol you use.
insert image description here

At this point, we first analyze the situation of using the AP protocol, that is, the situation of using Distro.
Since availability is guaranteed rather than consistency, we can actually use scheduled tasks or queues to load these instances asynchronously.
And Nacos does exactly that.
insert image description here
insert image description here

Here you can see that Datum is used again, where the value is all the corresponding instances, and the key is the service.
insert image description here

There are so many operations here, in fact, these instances are only operated in another memory, and these new instances have not been put into our memory, which is the set structure of Nacos, the set that stores specific instance information middle. That is, the registration of the instance has not yet been completed at this time.
The notifier seen above is the real place to start executing the registration event.
insert image description here

In the run method of the notifier, when the CHANGE event is triggered, the following method will be called, because the blocking queue has received the task at this time, and the logic will be executed immediately, and if the blocking queue has not received the task, it will always Blocks but does not consume performance.
insert image description here
insert image description here
insert image description here

The following picture is a specific example of updating the memory, and will also publish a service change event.
insert image description here

After entering this step, you can judge whether it should be put into the temporary or persistent Set collection according to whether it is a temporary node.
When the service discovers the temporary strength, it will get it from the ephemeralInstances of the cluster.

insert image description here

Guess you like

Origin blog.csdn.net/Zhangsama1/article/details/132141120