Nacos源码ServiceManager
ServiceManager就是Nacos中管理服務(wù)、實(shí)例信息的核心API,其中就包含Nacos的服務(wù)注冊(cè)表:
?
而其中的registerInstance方法就是注冊(cè)服務(wù)實(shí)例的方法:
/*** Register an instance to a service in AP mode.** <p>This method creates service or cluster silently if they don't exist.** @param namespaceId id of namespace* @param serviceName service name* @param instance instance to register* @throws Exception any error occurred in the process*/ public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {// 創(chuàng)建一個(gè)空的service(如果是第一次來(lái)注冊(cè)實(shí)例,要先創(chuàng)建一個(gè)空service出來(lái),放入注冊(cè)表)// 此時(shí)不包含實(shí)例信息createEmptyService(namespaceId, serviceName, instance.isEphemeral());// 拿到創(chuàng)建好的serviceService service = getService(namespaceId, serviceName);// 拿不到則拋異常if (service == null) {throw new NacosException(NacosException.INVALID_PARAM,"service not found, namespace: " + namespaceId + ", service: " + serviceName);}// 添加要注冊(cè)的實(shí)例到service中addInstance(namespaceId, serviceName, instance.isEphemeral(), instance); }創(chuàng)建好了服務(wù),接下來(lái)就要添加實(shí)例到服務(wù)中:
/*** Add instance to service.** @param namespaceId namespace* @param serviceName service name* @param ephemeral whether instance is ephemeral* @param ips instances* @throws NacosException nacos exception*/ public void addInstance(String namespaceId, String serviceName, boolean ephemeral, Instance... ips)throws NacosException {// 監(jiān)聽(tīng)服務(wù)列表用到的key,服務(wù)唯一標(biāo)識(shí),例如:com.alibaba.nacos.naming.iplist.ephemeral.public##DEFAULT_GROUP@@order-serviceString key = KeyBuilder.buildInstanceListKey(namespaceId, serviceName, ephemeral);// 獲取服務(wù)Service service = getService(namespaceId, serviceName);// 同步鎖,避免并發(fā)修改的安全問(wèn)題synchronized (service) {// 1)獲取要更新的實(shí)例列表List<Instance> instanceList = addIpAddresses(service, ephemeral, ips);// 2)封裝實(shí)例列表到Instances對(duì)象Instances instances = new Instances();instances.setInstanceList(instanceList);// 3)完成 注冊(cè)表更新 以及 Nacos集群的數(shù)據(jù)同步consistencyService.put(key, instances);} }該方法中對(duì)修改服務(wù)列表的動(dòng)作加鎖處理,確保線程安全。而在同步代碼塊中,包含下面幾步:
-
1)先獲取要更新的實(shí)例列表,addIpAddresses(service, ephemeral, ips);
-
2)然后將更新后的數(shù)據(jù)封裝到Instances對(duì)象中,后面更新注冊(cè)表時(shí)使用
-
3)最后,調(diào)用consistencyService.put()方法完成Nacos集群的數(shù)據(jù)同步,保證集群一致性。
注意:在第1步的addIPAddress中,會(huì)拷貝舊的實(shí)例列表,添加新實(shí)例到列表中。在第3步中,完成對(duì)實(shí)例狀態(tài)更新后,則會(huì)用新列表直接覆蓋舊實(shí)例列表。而在更新過(guò)程中,舊實(shí)例列表不受影響,用戶依然可以讀取。
這樣在更新列表狀態(tài)過(guò)程中,無(wú)需阻塞用戶的讀操作,也不會(huì)導(dǎo)致用戶讀取到臟數(shù)據(jù),性能比較好。這種方案稱為CopyOnWrite方案。
總結(jié)
以上是生活随笔為你收集整理的Nacos源码ServiceManager的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Nacos如何支撑阿里内部数十万服务注册
- 下一篇: Nacos源码更服务列表