in datasource/etcd/ms.go [358:422]
func (ds *MetadataManager) registerInstance(ctx context.Context, request *pb.RegisterInstanceRequest) (string, error) {
remoteIP := util.GetIPFromContext(ctx)
instance := request.Instance
//允许自定义id
if len(instance.InstanceId) > 0 {
needRegister, err := ds.sendHeartbeatInstead(ctx, instance)
if err != nil {
return "", err
}
if !needRegister {
return instance.InstanceId, nil
}
} else {
instance.InstanceId = uuid.Generator().GetInstanceID(ctx)
}
ttl := ds.calcInstanceTTL(instance)
instanceFlag := fmt.Sprintf("ttl %ds, endpoints %v, host '%s', serviceID %s",
ttl, instance.Endpoints, instance.HostName, instance.ServiceId)
//先以domain/project的方式组装
domainProject := util.ParseDomainProject(ctx)
instanceID := instance.InstanceId
data, err := json.Marshal(instance)
if err != nil {
log.Error(fmt.Sprintf("register instance failed, %s, instanceID %s, operator %s",
instanceFlag, instanceID, remoteIP), err)
return "", pb.NewError(pb.ErrInternal, err.Error())
}
leaseID, err := etcdadpt.Instance().LeaseGrant(ctx, ttl)
if err != nil {
log.Error(fmt.Sprintf("grant lease failed, %s, operator: %s", instanceFlag, remoteIP), err)
return "", pb.NewError(pb.ErrUnavailableBackend, err.Error())
}
// build the request options
key := path.GenerateInstanceKey(domainProject, instance.ServiceId, instanceID)
hbKey := path.GenerateInstanceLeaseKey(domainProject, instance.ServiceId, instanceID)
leaseOp := etcdadpt.WithLease(leaseID)
resp, err := etcdadpt.TxnWithCmp(ctx,
etcdadpt.Ops(
etcdadpt.OpPut(etcdadpt.WithStrKey(key), etcdadpt.WithValue(data), leaseOp),
etcdadpt.OpPut(etcdadpt.WithStrKey(hbKey), etcdadpt.WithStrValue(fmt.Sprintf("%d", leaseID)), leaseOp),
),
etcdadpt.If(etcdadpt.NotEqualVer(path.GenerateServiceKey(domainProject, instance.ServiceId), 0)),
nil)
if err != nil {
log.Error(fmt.Sprintf("register instance failed, %s, instanceID %s, operator %s",
instanceFlag, instanceID, remoteIP), err)
return "", pb.NewError(pb.ErrUnavailableBackend, err.Error())
}
if !resp.Succeeded {
log.Error(fmt.Sprintf("register instance failed, %s, instanceID %s, operator %s: service does not exist",
instanceFlag, instanceID, remoteIP), nil)
return "", pb.NewError(pb.ErrServiceNotExists, "Service does not exist.")
}
sendEvent(ctx, sync.CreateAction, datasource.ResourceInstance, request)
log.Info(fmt.Sprintf("register instance %s, instanceID %s, operator %s",
instanceFlag, instanceID, remoteIP))
return instanceID, nil
}