Save ephemeral status in service metadata.

This commit is contained in:
KomachiSion 2020-12-09 14:01:10 +08:00
parent 3026120c2b
commit 8d4397d54b
5 changed files with 85 additions and 18 deletions

View File

@ -94,7 +94,7 @@ public class ServiceController {
private ServiceOperatorV2Impl serviceOperatorV2;
/**
* Create a new service.
* Create a new service. This API will create a persistence service.
*
* @param namespaceId namespace id
* @param serviceName service name
@ -114,6 +114,7 @@ public class ServiceController {
serviceMetadata.setProtectThreshold(protectThreshold);
serviceMetadata.setSelector(parseSelector(selector));
serviceMetadata.setExtendData(UtilsAndCommons.parseMetadata(metadata));
serviceMetadata.setEphemeral(false);
serviceOperatorV2.create(namespaceId, serviceName, serviceMetadata);
return "ok";
}

View File

@ -47,7 +47,7 @@ public class ServiceOperatorV2Impl implements ServiceOperator {
@Override
public void create(String namespaceId, String serviceName, ServiceMetadata metadata) throws NacosException {
Service service = getServiceFromGroupedServiceName(namespaceId, serviceName);
Service service = getServiceFromGroupedServiceName(namespaceId, serviceName, metadata.isEphemeral());
if (ServiceManager.getInstance().containSingleton(service)) {
throw new NacosException(NacosException.INVALID_PARAM,
String.format("specified service %s already exists!", service.getGroupedServiceName()));
@ -66,7 +66,7 @@ public class ServiceOperatorV2Impl implements ServiceOperator {
@Override
public void delete(String namespaceId, String serviceName) throws NacosException {
metadataOperateService.deleteServiceMetadata(getServiceFromGroupedServiceName(namespaceId, serviceName));
metadataOperateService.deleteServiceMetadata(getServiceFromGroupedServiceName(namespaceId, serviceName, true));
}
@Override
@ -92,9 +92,9 @@ public class ServiceOperatorV2Impl implements ServiceOperator {
return result;
}
private Service getServiceFromGroupedServiceName(String namespaceId, String groupedServiceName) {
private Service getServiceFromGroupedServiceName(String namespaceId, String groupedServiceName, boolean ephemeral) {
String groupName = NamingUtils.getGroupName(groupedServiceName);
String serviceName = NamingUtils.getServiceName(groupedServiceName);
return Service.newService(namespaceId, groupName, serviceName);
return Service.newService(namespaceId, groupName, serviceName, ephemeral);
}
}

View File

@ -20,6 +20,7 @@ import com.alibaba.nacos.common.notify.Event;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.notify.listener.SmartSubscriber;
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
import com.alibaba.nacos.naming.core.v2.ServiceManager;
import com.alibaba.nacos.naming.core.v2.event.client.ClientEvent;
import com.alibaba.nacos.naming.core.v2.event.metadata.MetadataEvent;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
@ -41,12 +42,12 @@ import java.util.concurrent.ConcurrentMap;
@Component
public class NamingMetadataManager extends SmartSubscriber {
private final ConcurrentMap<Service, ServiceMetadata> serviceMetadataMap;
private final ConcurrentMap<Service, ConcurrentMap<String, InstanceMetadata>> instanceMetadataMap;
private final Set<ExpiredMetadataInfo> expiredMetadataInfos;
private ConcurrentMap<Service, ServiceMetadata> serviceMetadataMap;
private ConcurrentMap<Service, ConcurrentMap<String, InstanceMetadata>> instanceMetadataMap;
public NamingMetadataManager() {
serviceMetadataMap = new ConcurrentHashMap<>(1 << 10);
instanceMetadataMap = new ConcurrentHashMap<>(1 << 10);
@ -75,7 +76,9 @@ public class NamingMetadataManager extends SmartSubscriber {
}
/**
* Get service metadata for {@link Service}.
* Get service metadata for {@link Service}, which is the original metadata object.
*
* <p>This method should use only query, can't modified metadata.
*
* @param service service
* @return service metadata
@ -85,7 +88,9 @@ public class NamingMetadataManager extends SmartSubscriber {
}
/**
* Get instance metadata for instance of {@link Service}.
* Get instance metadata for instance of {@link Service}, which is the original metadata object.
*
* <p>This method should use only query, can't modified metadata.
*
* @param service service
* @param instanceId instance id
@ -106,6 +111,7 @@ public class NamingMetadataManager extends SmartSubscriber {
* @param serviceMetadata new service metadata
*/
public void updateServiceMetadata(Service service, ServiceMetadata serviceMetadata) {
service.incrementRevision();
serviceMetadataMap.put(service, serviceMetadata);
}
@ -171,12 +177,31 @@ public class NamingMetadataManager extends SmartSubscriber {
return result;
}
public void loadServiceMetadataSnapshot(Map<Service, ServiceMetadata> snapshot) {
serviceMetadataMap.putAll(snapshot);
/**
* Load service metadata snapshot.
*
* <p>Service metadata need load back the service.
*
* @param snapshot snapshot
*/
public void loadServiceMetadataSnapshot(ConcurrentMap<Service, ServiceMetadata> snapshot) {
for (Service each : snapshot.keySet()) {
ServiceManager.getInstance().getSingleton(each);
}
ConcurrentMap<Service, ServiceMetadata> oldSnapshot = serviceMetadataMap;
serviceMetadataMap = snapshot;
oldSnapshot.clear();
}
public void loadInstanceMetadataSnapshot(Map<Service, ConcurrentMap<String, InstanceMetadata>> snapshot) {
instanceMetadataMap.putAll(snapshot);
/**
* Load instance metadata snapshot.
*
* @param snapshot snapshot
*/
public void loadInstanceMetadataSnapshot(ConcurrentMap<Service, ConcurrentMap<String, InstanceMetadata>> snapshot) {
ConcurrentMap<Service, ConcurrentMap<String, InstanceMetadata>> oldSnapshot = instanceMetadataMap;
instanceMetadataMap = snapshot;
oldSnapshot.clear();
}
public Set<ExpiredMetadataInfo> getExpiredMetadataInfos() {

View File

@ -33,6 +33,11 @@ public class ServiceMetadata implements Serializable {
private static final long serialVersionUID = -6605609934135069566L;
/**
* Service is ephemeral or persistence.
*/
private boolean ephemeral = true;
/**
* protect threshold.
*/
@ -47,6 +52,14 @@ public class ServiceMetadata implements Serializable {
private Map<String, ClusterMetadata> clusters = new ConcurrentHashMap<>(1);
public boolean isEphemeral() {
return ephemeral;
}
public void setEphemeral(boolean ephemeral) {
this.ephemeral = ephemeral;
}
public float getProtectThreshold() {
return protectThreshold;
}

View File

@ -34,6 +34,7 @@ import org.springframework.stereotype.Component;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
@ -100,9 +101,36 @@ public class ServiceMetadataProcessor extends RequestProcessor4CP {
}
private void updateServiceMetadata(MetadataOperation<ServiceMetadata> op) {
Service service = ServiceManager.getInstance()
.getSingleton(Service.newService(op.getNamespace(), op.getGroup(), op.getServiceName()));
namingMetadataManager.updateServiceMetadata(service, op.getMetadata());
Service service = Service
.newService(op.getNamespace(), op.getGroup(), op.getServiceName(), op.getMetadata().isEphemeral());
Optional<ServiceMetadata> currentMetadata = namingMetadataManager.getServiceMetadata(service);
if (currentMetadata.isPresent()) {
ServiceMetadata newMetadata = mergeMetadata(currentMetadata.get(), op.getMetadata());
Service singleton = ServiceManager.getInstance().getSingleton(service);
namingMetadataManager.updateServiceMetadata(singleton, newMetadata);
} else {
Service singleton = ServiceManager.getInstance().getSingleton(service);
namingMetadataManager.updateServiceMetadata(singleton, op.getMetadata());
}
}
/**
* Do not modified old metadata directly to avoid read half status.
*
* <p>Ephemeral variable should only use the value the metadata create.
*
* @param oldMetadata old metadata
* @param newMetadata new metadata
* @return merged metadata
*/
private ServiceMetadata mergeMetadata(ServiceMetadata oldMetadata, ServiceMetadata newMetadata) {
ServiceMetadata result = new ServiceMetadata();
result.setEphemeral(oldMetadata.isEphemeral());
result.setClusters(oldMetadata.getClusters());
result.setProtectThreshold(newMetadata.getProtectThreshold());
result.setSelector(newMetadata.getSelector());
result.setExtendData(newMetadata.getExtendData());
return result;
}
private void deleteServiceMetadata(MetadataOperation<ServiceMetadata> op) {