客户端注册实例流程
注册实例
官网的描述:
客户端注册
主要是在这个地方。
服务端处理
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);
}
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。