1. Traitement des demandes des clients
Trouver un contrôleur d'instance
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/instance")
Cette adresse est l'adresse de notre service d'inscription au service client. Le processus d'inscription du service client peut être vu dans cet article de blog [Spring Cloud] Code source du processus d'inscription au service Nacos_Autumn Sunset Blog-CSDN Blog
voir la méthode du contrôleur
Montez et obtenez d'abord le namespaceId et le serviceName
Espace de noms par défaut : public
Groupe : DEFAULT_GROUP@@ + le nom du service enregistré par le client
L'objet d'instance d'analyse encapsule les paramètres du fournisseur de services
Enregistrez ensuite le service et appelez la méthode registerInstance
serviceManager.registerInstance(namespaceId, serviceName, instance);
suivi
com.alibaba.nacos.naming.core.ServiceManager. registerInstance
2. Enregistrez l'instance
com.alibaba.nacos.naming.core.ServiceManager. registerInstance
Appelez d'abord createEmptyService pour créer une structure de service vide dans le registre
Suivi de la méthode createServiceIfAbsent
La première fois que vous entrez dans Service service = getService(namespaceId, serviceName) doit être nul
Entrez la logique if
Création d'un nouvel objet de service pour définir le nom du service, l'espace de noms, le nom du groupe pour enregistrer l'heure de modification
Venez à putServiceAndInit(service)
suivi
`serviceMap carte double couche
Regardez les données de serviceMap après avoir exécuté putService
La clé de la carte externe est la valeur de l'espace de noms et également une carte, la clé de la carte interne est le groupName et la valeur du nom du groupe est l'objet de service
3. Vérification du rythme cardiaque de l'instance de service
Retour à la méthode putServiceAndInit
Exécutez ensuite la méthode service.init()
Accédez à la méthode com.alibaba.nacos.naming.core.Service.init
Exécuter une tâche planifiée après les 5 premières secondes, puis l'exécuter toutes les 5 secondes pour voir quelle est la tâche de suivi lorsque la tâche de thread est exécutée
tâche de thread
com.alibaba.nacos.naming.healthcheck.ClientBeatCheckTask.run()
La valeur de `instance.getInstanceHeartBeatTimeOut() est de 15 secondes
Si l'heure actuelle moins la dernière pulsation de l'instance est supérieure à 15 secondes, entrez le jugement if et définissez l'état de santé sur false
C'est-à-dire que HealthCheckReactor.scheduleCheck(clientBeatCheckTask) active une pulsation pour détecter l'état de santé de toutes les instances. Une fois que le temps écoulé depuis la dernière détection de pulsation dépasse 15 s, l'état de santé est défini sur faux.
4. Envoyer un message à la file d'attente
Retour à la méthode registerInstance
Continuez à regarder addInstance(namespaceId, serviceName, instance.isEphemeral(), instance)
Suivi de com.alibaba.nacos.naming.core.ServiceManager.addInstance
Générez d'abord une valeur de clé d'instance com.alibaba.nacos.naming.iplist.ephemeral.public##DEFAULT_GROUP@@nacos-test
String key = KeyBuilder.buildInstanceListKey(namespaceId, serviceName, ephemeral);
Générer une collection d'instances
List<Instance> instanceList = addIpAddresses(service, ephemeral, ips)
de nouvelles instances encapsulent les données de collecte
Instances instances = new Instances();
instances.setInstanceList(instanceList);
Accédez à la méthode consistanceService.put(key, instances)
来到 com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.put
`La valeur d'enregistrement est l'incarnation des instances qui encapsule les instances Les instances Les instances héritent du polymorphisme d'enregistrement
Suivi de la méthode Put
Accédez à la méthode com.alibaba.nacos.naming.consistency.ephemeral.distro.DistroConsistencyServiceImpl.onPut
Un autre nouvel objet Datum, la valeur Datum est Instances key est la clé d'instance générée précédemment
Puis jetez le Datum dans la carte du DataStore
Enfin, appelez la méthode notifier.addTask pour suivre avec la méthode addTask
Mettre la clé dans les services est la valeur datumKey est une chaîne vide
private ConcurrentHashMap<String, String> services = new ConcurrentHashMap<>(10 * 1024)
Enfin, l'appel task.offer
jette la clé et l'action exécutée dans la file d'attente mémoire et renvoie null.La méthode est terminée.
La difficulté est-elle là ?
5. Écoutez la file d'attente et sortez la nouvelle instance de service
Regardons la classe à laquelle appartient cette tâche
`Notifier est également une classe de tâche de thread, alors jetons un coup d'œil à ses tâches de thread
Obtenez le datumKey de la file d'attente et appelez la méthode handle
Atteignez un point d'arrêt, examinez le flux d'exécution et réenregistrez le service
venir à listener.onChange
L'un des deux paramètres de la méthode onChange est datumKey et l'autre est Instances
On peut voir que la collection d'instances de service est extraite du dataStore via datumKey.
Suivi de la méthode com.alibaba.nacos.naming.core.Service.onChange
Parcourir toutes les instances d'instance pour définir des pondérations raisonnables
Appelez ensuite la méthode updateIPs pour suivre
Je suis venu avec un nouvel ipMap et beaucoup de cartes
itérer sur toutes les instances
Ajouter aux adresses IP du cluster
Aller au suivant pour la traversée
Appelez clusterMap.get(entry.getKey()).updateIps(entryIPs, ephemeral) pour obtenir le cluster et appelez la méthode updateIps
Venez à com.alibaba.nacos.naming.core.Cluster.updateIps
6. Copie sur écriture, enregistrez une nouvelle instance de service dans le registre
ephemeral Si le paramètre passé dans la méthode précédente est vrai, alors affectez la valeur de ephemeralInstances à Set toUpdateInstances
Set<Instance> toUpdateInstances = ephemeral ? ephemeralInstances : persistentInstances;
Alors, qu'est-ce que c'est que ces instances éphémères ?
Il s'agit de l'ancien ensemble d'instances de service de stockage en cluster
private Set<Instance> ephemeralInstances = new HashSet<>();
Attribuez l'ancien ensemble d'instances à toUpdateInstances L'étape suivante consiste à exploiter l'instance de service nouvellement enregistrée, et enfin à attribuer toutes les dernières instances à toUpdateInstances,
Attribuez ensuite la valeur de toUpdateInstances à ephemeralInstances. À ce stade, une nouvelle instance de service est enregistrée.
Il s'agit d'une idée de copie sur écriture, copiez une instance de service enregistrée, exploitez les données copiées, puis remplacez les anciennes données d'origine par les données copiées une fois l'opération terminée.
Le but est de résoudre le conflit de concurrence. Pendant le processus d'écriture, d'autres threads lisent les anciennes données, puis mettent à jour les données une fois l'écriture réelle terminée. Les données modifiées ne seront pas lues. Assurez-vous que toutes les instances de service lues sont disponibles.