Spring Cloud 2.2.2 源碼之五十三nacos服務端處理註冊實例請求一
客戶端註冊實例流程
註冊實例
官網的描述:
客戶端註冊
主要是在這個地方。
服務端處理
InstanceController
的register
方法:
parseInstance解析成實例
就是把傳過來的參數封裝成服務實例Instance
。
private Instance parseInstance(HttpServletRequest request) throws Exception {
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
String app = WebUtils.optional(request, "app", "DEFAULT");
String metadata = WebUtils.optional(request, "metadata", StringUtils.EMPTY);
Instance instance = getIPAddress(request);
instance.setApp(app);
instance.setServiceName(serviceName);
// Generate simple instance id first. This value would be updated according to
// INSTANCE_ID_GENERATOR.
instance.setInstanceId(instance.generateInstanceId());
instance.setLastBeat(System.currentTimeMillis());
if (StringUtils.isNotEmpty(metadata)) {
instance.setMetadata(UtilsAndCommons.parseMetadata(metadata));
}
instance.validate();
return instance;
}
服務端處理
默認是AP
模式,保證高可用,數據最終一致性。
public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {
//創建服務
createEmptyService(namespaceId, serviceName, instance.isEphemeral());
//獲取服務
Service service = getService(namespaceId, serviceName);
if (service == null) {
throw new NacosException(NacosException.INVALID_PARAM,
"service not found, namespace: " + namespaceId + ", service: " + serviceName);
}
//添加實例
addInstance(namespaceId, serviceName, instance.isEphemeral(), instance);
}
createEmptyService
最終到createServiceIfAbsent
,創建服務實例,然後設置參數,初始化。
public void createServiceIfAbsent(String namespaceId, String serviceName, boolean local, Cluster cluster) throws NacosException {
//獲取對應命名空間內服務名的實例
Service service = getService(namespaceId, serviceName);
if (service == null) {
//創建一個服務
Loggers.SRV_LOG.info("creating empty service {}:{}", namespaceId, serviceName);
service = new Service();
service.setName(serviceName);
service.setNamespaceId(namespaceId);
service.setGroupName(NamingUtils.getGroupName(serviceName));
// now validate the service. if failed, exception will be thrown
service.setLastModifiedMillis(System.currentTimeMillis());
service.recalculateChecksum();//校驗和
if (cluster != null) {//有集羣要添加
cluster.setService(service);
service.getClusterMap().put(cluster.getName(), cluster);
}
service.validate();//服務驗證,服務和集羣名驗證
//服務初始化
putServiceAndInit(service);
if (!local) {//永久服務還要添加到一致性服務裏
addOrReplaceService(service);
}
}
}
ServiceManager的getService
獲取對應命名空間內服務名的實例。
/** 命名空間 組@@服務名 服務實例
* Map<namespace, Map<group::serviceName, Service>>
*/
private Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();
public Service getService(String namespaceId, String serviceName) {
if (serviceMap.get(namespaceId) == null) {
return null;
}
return chooseServiceMap(namespaceId).get(serviceName);
}
獲取命名空間的服務實例映射:
public Map<String, Service> chooseServiceMap(String namespaceId) {
return serviceMap.get(namespaceId);
}
好了,今天就到這裏了,希望對學習理解有幫助,大神看見勿噴,僅爲自己的學習理解,能力有限,請多包涵。