diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/CommonParams.java b/api/src/main/java/com/alibaba/nacos/api/naming/CommonParams.java index f2b7b7100..49fe807af 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/CommonParams.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/CommonParams.java @@ -29,4 +29,6 @@ public class CommonParams { public static final String NAMESPACE_ID = "namespaceId"; + public static final String GROUP_NAME = "groupName"; + } diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java b/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java index d018eca02..78c34d31d 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java @@ -23,7 +23,7 @@ import com.alibaba.nacos.api.exception.NacosException; /** * Naming Factory * - * @author dungu.zpf + * @author nkorange */ public class NamingFactory { diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java b/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java index 48f6ae5f8..5fd4610fa 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java @@ -27,7 +27,7 @@ import java.util.List; /** * Naming Service * - * @author dungu.zpf + * @author nkorange */ public interface NamingService { diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/listener/Event.java b/api/src/main/java/com/alibaba/nacos/api/naming/listener/Event.java index feede4e8f..cb04b9dd4 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/listener/Event.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/listener/Event.java @@ -18,7 +18,7 @@ package com.alibaba.nacos.api.naming.listener; /** * Event Interface * - * @author dungu.zpf + * @author nkorange */ public interface Event { } diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/listener/NamingEvent.java b/api/src/main/java/com/alibaba/nacos/api/naming/listener/NamingEvent.java index c43f95048..6bb45c095 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/listener/NamingEvent.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/listener/NamingEvent.java @@ -22,7 +22,7 @@ import com.alibaba.nacos.api.naming.pojo.Instance; /** * Naming Event * - * @author dungu.zpf + * @author nkorange */ public class NamingEvent implements Event { diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java index f209f476e..a571e0edb 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java @@ -21,7 +21,7 @@ import java.util.Map; /** * Cluster * - * @author dungu.zpf + * @author nkorange */ public class Cluster { diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java index 24cc563af..7df2672d3 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ListView.java @@ -22,7 +22,7 @@ import java.util.List; /** * ListView * - * @author dungu.zpf + * @author nkorange */ public class ListView { diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java index c52cf8845..c7e03142d 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java @@ -19,9 +19,14 @@ import java.util.HashMap; import java.util.Map; /** - * Service + * Service of Nacos + *

+ * We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters, + * which contains a list of instances. + *

+ * Typically we put some unique properties between instances to service level. * - * @author dungu.zpf + * @author nkorange */ public class Service { @@ -43,7 +48,7 @@ public class Service { private String app; /** - * Service group which is meant to classify services into different sets. + * Service group to classify services into different sets. */ private String group; diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java index 78bac2f9f..8e359d9b7 100644 --- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java +++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java @@ -26,7 +26,7 @@ import java.util.List; /** * ServiceInfo * - * @author dungu.zpf + * @author nkorange */ public class ServiceInfo { diff --git a/naming/src/main/java/com/alibaba/nacos/naming/boot/SpringContext.java b/naming/src/main/java/com/alibaba/nacos/naming/boot/SpringContext.java index 7a6ab37ae..d9292cce3 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/boot/SpringContext.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/boot/SpringContext.java @@ -16,7 +16,6 @@ package com.alibaba.nacos.naming.boot; import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerMode.java b/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerMode.java new file mode 100644 index 000000000..400b4d1a4 --- /dev/null +++ b/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerMode.java @@ -0,0 +1,48 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.nacos.naming.cluster; + +/** + * Server running mode + *

+ * We use CAP theory to set the server mode, users can select their preferred mode in running time. + *

+ * CP mode provides strong consistency, data persistence but network partition tolerance. + *

+ * AP mode provides eventual consistency and network partition tolerance but data persistence. + *

+ * Mixed mode provides CP for some data and AP for some other data. + *

+ * Service level information and cluster level information are always operated via CP protocol, so + * in AP mode they cannot be edited. + * + * @author nkorange + * @since 1.0.0 + */ +public enum ServerMode { + /** + * AP mode + */ + AP, + /** + * CP mode + */ + CP, + /** + * Mixed mode + */ + MIXED +} diff --git a/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerStatusManager.java b/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerStatusManager.java index 6ec67a019..1cfed7e82 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerStatusManager.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/cluster/ServerStatusManager.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; +import javax.annotation.Resource; /** * Detect and control the working status of local server @@ -33,7 +34,7 @@ import javax.annotation.PostConstruct; @Service public class ServerStatusManager { - @Autowired + @Resource(name = "consistencyDelegate") private ConsistencyService consistencyService; @Autowired @@ -41,8 +42,6 @@ public class ServerStatusManager { private ServerStatus serverStatus = ServerStatus.STARTING; - private boolean serverStatusLocked = false; - @PostConstruct public void init() { GlobalExecutor.registerServerStatusUpdater(new ServerStatusUpdater()); diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/partition/DataStore.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/partition/DataStore.java index c129d67c4..83cdd6931 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/partition/DataStore.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/partition/DataStore.java @@ -18,7 +18,10 @@ package com.alibaba.nacos.naming.consistency.ephemeral.partition; import com.alibaba.nacos.naming.consistency.Datum; import org.springframework.stereotype.Component; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftStore.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftStore.java index 60aec39c1..75fb8271b 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftStore.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftStore.java @@ -49,14 +49,9 @@ public class RaftStore { private Properties meta = new Properties(); - private String metaFileName; + private String metaFileName = UtilsAndCommons.DATA_BASE_DIR + File.separator + "meta.properties"; - private String cacheDir; - - public RaftStore() { - metaFileName = UtilsAndCommons.DATA_BASE_DIR + File.separator + "meta.properties"; - cacheDir = UtilsAndCommons.DATA_BASE_DIR + File.separator + "data"; - } + private String cacheDir = UtilsAndCommons.DATA_BASE_DIR + File.separator + "data"; public synchronized ConcurrentHashMap> loadDatums(RaftCore.Notifier notifier) throws Exception { @@ -116,7 +111,7 @@ public class RaftStore { return null; } - public synchronized static Datum readDatum(File file, String namespaceId) throws IOException { + public synchronized Datum readDatum(File file, String namespaceId) throws IOException { ByteBuffer buffer; FileChannel fc = null; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/controllers/CatalogController.java b/naming/src/main/java/com/alibaba/nacos/naming/controllers/CatalogController.java index 02732f334..fe15a52b8 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/controllers/CatalogController.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/controllers/CatalogController.java @@ -26,11 +26,7 @@ import com.alibaba.nacos.naming.core.ServiceManager; import com.alibaba.nacos.naming.exception.NacosException; import com.alibaba.nacos.naming.healthcheck.HealthCheckTask; import com.alibaba.nacos.naming.misc.UtilsAndCommons; -import com.alibaba.nacos.naming.pojo.ClusterInfo; -import com.alibaba.nacos.naming.pojo.IpAddressInfo; -import com.alibaba.nacos.naming.pojo.ServiceDetailInfo; -import com.alibaba.nacos.naming.pojo.ServiceDetailView; -import com.alibaba.nacos.naming.pojo.ServiceView; +import com.alibaba.nacos.naming.pojo.*; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.map.HashedMap; import org.apache.commons.lang3.StringUtils; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/controllers/ClusterController.java b/naming/src/main/java/com/alibaba/nacos/naming/controllers/ClusterController.java index b257c67b2..1da62e69f 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/controllers/ClusterController.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/controllers/ClusterController.java @@ -21,8 +21,8 @@ import com.alibaba.nacos.api.naming.CommonParams; import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker; import com.alibaba.nacos.core.utils.WebUtils; import com.alibaba.nacos.naming.core.Cluster; -import com.alibaba.nacos.naming.core.ServiceManager; import com.alibaba.nacos.naming.core.Service; +import com.alibaba.nacos.naming.core.ServiceManager; import com.alibaba.nacos.naming.exception.NacosException; import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.UtilsAndCommons; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/controllers/InstanceController.java b/naming/src/main/java/com/alibaba/nacos/naming/controllers/InstanceController.java index d43e874a4..5b4a24c41 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/controllers/InstanceController.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/controllers/InstanceController.java @@ -21,6 +21,7 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.nacos.api.naming.CommonParams; import com.alibaba.nacos.core.utils.WebUtils; import com.alibaba.nacos.naming.boot.RunningConfig; +import com.alibaba.nacos.naming.cluster.ServerMode; import com.alibaba.nacos.naming.core.DistroMapper; import com.alibaba.nacos.naming.core.Instance; import com.alibaba.nacos.naming.core.Service; @@ -90,7 +91,7 @@ public class InstanceController { @RequestMapping(value = "/instance", method = RequestMethod.POST) public String register(HttpServletRequest request) throws Exception { - return regService(request); + return registerInstance(request); } @RequestMapping(value = "/instance", method = RequestMethod.DELETE) @@ -112,7 +113,7 @@ public class InstanceController { @RequestMapping(value = {"/instance/update", "instance"}, method = RequestMethod.PUT) public String update(HttpServletRequest request) throws Exception { - return regService(request); + return registerInstance(request); } @RequestMapping(value = {"/instances", "/instance/list"}, method = RequestMethod.GET) @@ -184,6 +185,16 @@ public class InstanceController { @RequestMapping(value = "/instance/beat", method = RequestMethod.PUT) public JSONObject beat(HttpServletRequest request) throws Exception { + + JSONObject result = new JSONObject(); + + result.put("clientBeatInterval", switchDomain.getClientBeatInterval()); + + // ignore client beat in CP mode: + if (ServerMode.CP.name().equals(switchDomain.getServerMode())) { + return result; + } + String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, UtilsAndCommons.DEFAULT_NAMESPACE_ID); String beat = WebUtils.required(request, "beat"); @@ -218,7 +229,13 @@ public class InstanceController { instance.setClusterName(clusterName); instance.setServiceName(serviceName); instance.setInstanceId(instance.generateInstanceId()); - serviceManager.registerInstance(namespaceId, serviceName, clusterName, instance); + instance.setEphemeral(clientBeat.isEphemeral()); + + if (ServerMode.AP.name().equals(switchDomain.getServerMode())) { + serviceManager.registerInstance(namespaceId, serviceName, clusterName, instance); + } else { + serviceManager.addInstance(namespaceId, serviceName, clusterName, true, instance); + } } Service service = serviceManager.getService(namespaceId, serviceName); @@ -252,10 +269,6 @@ public class InstanceController { service.processClientBeat(clientBeat); } - JSONObject result = new JSONObject(); - - result.put("clientBeatInterval", switchDomain.getClientBeatInterval()); - return result; } @@ -295,7 +308,7 @@ public class InstanceController { return result; } - private String regService(HttpServletRequest request) throws Exception { + private String registerInstance(HttpServletRequest request) throws Exception { String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); String clusterName = WebUtils.optional(request, CommonParams.CLUSTER_NAME, UtilsAndCommons.DEFAULT_CLUSTER_NAME); @@ -325,7 +338,9 @@ public class InstanceController { String weight = WebUtils.optional(request, "weight", "1"); String cluster = WebUtils.optional(request, CommonParams.CLUSTER_NAME, UtilsAndCommons.DEFAULT_CLUSTER_NAME); boolean enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true")); - boolean ephemeral = BooleanUtils.toBoolean(WebUtils.optional(request, "ephemeral", "true")); + // If server running in CP mode, we set this flag to false: + boolean ephemeral = BooleanUtils.toBoolean(WebUtils.optional(request, "ephemeral", + String.valueOf(!ServerMode.CP.name().equals(switchDomain.getServerMode())))); Instance instance = new Instance(); instance.setPort(Integer.parseInt(port)); diff --git a/naming/src/main/java/com/alibaba/nacos/naming/controllers/PartitionController.java b/naming/src/main/java/com/alibaba/nacos/naming/controllers/PartitionController.java index 0866706f3..7e36800a3 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/controllers/PartitionController.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/controllers/PartitionController.java @@ -16,14 +16,11 @@ package com.alibaba.nacos.naming.controllers; import com.alibaba.fastjson.TypeReference; -import com.alibaba.nacos.api.common.Constants; -import com.alibaba.nacos.api.naming.pojo.Instance; -import com.alibaba.nacos.common.util.IoUtils; import com.alibaba.nacos.core.utils.WebUtils; +import com.alibaba.nacos.naming.cluster.transport.Serializer; import com.alibaba.nacos.naming.consistency.Datum; import com.alibaba.nacos.naming.consistency.KeyBuilder; import com.alibaba.nacos.naming.consistency.ephemeral.partition.PartitionConsistencyServiceImpl; -import com.alibaba.nacos.naming.cluster.transport.Serializer; import com.alibaba.nacos.naming.core.Instances; import com.alibaba.nacos.naming.exception.NacosException; import com.alibaba.nacos.naming.misc.Loggers; @@ -37,7 +34,6 @@ import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; -import java.util.List; import java.util.Map; /** diff --git a/naming/src/main/java/com/alibaba/nacos/naming/controllers/RaftController.java b/naming/src/main/java/com/alibaba/nacos/naming/controllers/RaftController.java index c51c7fa93..f2c63a65f 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/controllers/RaftController.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/controllers/RaftController.java @@ -24,7 +24,9 @@ import com.alibaba.nacos.core.utils.WebUtils; import com.alibaba.nacos.naming.consistency.DataListener; import com.alibaba.nacos.naming.consistency.Datum; import com.alibaba.nacos.naming.consistency.KeyBuilder; -import com.alibaba.nacos.naming.consistency.persistent.raft.*; +import com.alibaba.nacos.naming.consistency.persistent.raft.RaftConsistencyServiceImpl; +import com.alibaba.nacos.naming.consistency.persistent.raft.RaftCore; +import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer; import com.alibaba.nacos.naming.core.Instances; import com.alibaba.nacos.naming.core.Service; import com.alibaba.nacos.naming.core.ServiceManager; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/controllers/ServiceController.java b/naming/src/main/java/com/alibaba/nacos/naming/controllers/ServiceController.java index c95eb7e6a..aacb94024 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/controllers/ServiceController.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/controllers/ServiceController.java @@ -25,7 +25,6 @@ import com.alibaba.nacos.naming.cluster.ServerListManager; import com.alibaba.nacos.naming.core.*; import com.alibaba.nacos.naming.exception.NacosException; import com.alibaba.nacos.naming.misc.Loggers; -import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.misc.UtilsAndCommons; import com.alibaba.nacos.naming.selector.LabelSelector; import com.alibaba.nacos.naming.selector.NoneSelector; @@ -53,9 +52,6 @@ public class ServiceController { @Autowired protected ServiceManager serviceManager; - @Autowired - private SwitchDomain switchDomain; - @Autowired private DistroMapper distroMapper; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/core/Cluster.java b/naming/src/main/java/com/alibaba/nacos/naming/core/Cluster.java index 5d7e99fae..018ed7885 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/core/Cluster.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/core/Cluster.java @@ -16,7 +16,6 @@ package com.alibaba.nacos.naming.core; import com.alibaba.fastjson.annotation.JSONField; -import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker; import com.alibaba.nacos.naming.healthcheck.HealthCheckReactor; import com.alibaba.nacos.naming.healthcheck.HealthCheckStatus; import com.alibaba.nacos.naming.healthcheck.HealthCheckTask; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/core/Service.java b/naming/src/main/java/com/alibaba/nacos/naming/core/Service.java index e9ca87579..63d972b0a 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/core/Service.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/core/Service.java @@ -40,12 +40,12 @@ import java.security.MessageDigest; import java.util.*; /** - * Service of Nacos + * Service of Nacos server side *

* We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters, * which contains a list of instances. *

- * Typically we put some common properties between instances to service level. + * This class inherits from Service in API module and stores some fields that do not expose to client. * * @author nkorange */ diff --git a/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java b/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java index 943672dd2..046e1b674 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java @@ -21,7 +21,6 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.naming.cluster.ServerListManager; import com.alibaba.nacos.naming.cluster.servers.Server; -import com.alibaba.nacos.naming.cluster.transport.Serializer; import com.alibaba.nacos.naming.consistency.ConsistencyService; import com.alibaba.nacos.naming.consistency.DataListener; import com.alibaba.nacos.naming.consistency.Datum; @@ -37,12 +36,15 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.Condition; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** + * Core manager storing all services in Nacos + * * @author nkorange */ @Component @@ -54,21 +56,12 @@ public class ServiceManager implements DataListener { */ private Map> serviceMap = new ConcurrentHashMap<>(); - private LinkedBlockingDeque toBeUpdatedDomsQueue = new LinkedBlockingDeque<>(1024 * 1024); + private LinkedBlockingDeque toBeUpdatedServicesQueue = new LinkedBlockingDeque<>(1024 * 1024); private Synchronizer synchronizer = new DomainStatusSynchronizer(); - /** - * thread pool core size - */ - private final static int DOMAIN_UPDATE_EXECUTOR_NUM = 2; - private final Lock lock = new ReentrantLock(); - private Map service2ConditionMap = new ConcurrentHashMap<>(); - - private Map service2LockMap = new ConcurrentHashMap<>(); - @Resource(name = "consistencyDelegate") private ConsistencyService consistencyService; @@ -84,29 +77,12 @@ public class ServiceManager implements DataListener { @Autowired private PushService pushService; - @Autowired - private Serializer serializer; - - /** - * thread pool that processes getting service detail from other server asynchronously - */ - private ExecutorService serviceUpdateExecutor - = Executors.newFixedThreadPool(DOMAIN_UPDATE_EXECUTOR_NUM, new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setName("com.alibaba.nacos.naming.service.update.http.handler"); - t.setDaemon(true); - return t; - } - }); - @PostConstruct public void init() { UtilsAndCommons.DOMAIN_SYNCHRONIZATION_EXECUTOR.schedule(new ServiceReporter(), 60000, TimeUnit.MILLISECONDS); - UtilsAndCommons.DOMAIN_UPDATE_EXECUTOR.submit(new UpdatedDomainProcessor()); + UtilsAndCommons.DOMAIN_UPDATE_EXECUTOR.submit(new UpdatedServiceProcessor()); try { Loggers.SRV_LOG.info("listen for service meta change"); @@ -123,10 +99,10 @@ public class ServiceManager implements DataListener { public void addUpdatedService2Queue(String namespaceId, String serviceName, String serverIP, String checksum) { lock.lock(); try { - toBeUpdatedDomsQueue.offer(new ServiceKey(namespaceId, serviceName, serverIP, checksum), 5, TimeUnit.MILLISECONDS); + toBeUpdatedServicesQueue.offer(new ServiceKey(namespaceId, serviceName, serverIP, checksum), 5, TimeUnit.MILLISECONDS); } catch (Exception e) { - toBeUpdatedDomsQueue.poll(); - toBeUpdatedDomsQueue.add(new ServiceKey(namespaceId, serviceName, serverIP, checksum)); + toBeUpdatedServicesQueue.poll(); + toBeUpdatedServicesQueue.add(new ServiceKey(namespaceId, serviceName, serverIP, checksum)); Loggers.SRV_LOG.error("[DOMAIN-STATUS] Failed to add service to be updatd to queue.", e); } finally { lock.unlock(); @@ -162,16 +138,12 @@ public class ServiceManager implements DataListener { if (oldDom != null) { oldDom.update(service); } else { - - addLockIfAbsent(UtilsAndCommons.assembleFullServiceName(service.getNamespaceId(), service.getName())); putService(service); service.init(); consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), true), service); consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), false), service); Loggers.SRV_LOG.info("[NEW-SERVICE] {}", service.toJSON()); } - wakeUp(UtilsAndCommons.assembleFullServiceName(service.getNamespaceId(), service.getName())); - } catch (Throwable e) { Loggers.SRV_LOG.error("[NACOS-SERVICE] error while processing service update", e); } @@ -189,23 +161,20 @@ public class ServiceManager implements DataListener { consistencyService.remove(KeyBuilder.buildInstanceListKey(namespace, name, true)); consistencyService.remove(KeyBuilder.buildInstanceListKey(namespace, name, false)); consistencyService.unlisten(KeyBuilder.buildServiceMetaKey(namespace, name), service); - Loggers.SRV_LOG.info("[DEAD-DOM] {}", service.toJSON()); + Loggers.SRV_LOG.info("[DEAD-SERVICE] {}", service.toJSON()); } } - private class UpdatedDomainProcessor implements Runnable { + private class UpdatedServiceProcessor implements Runnable { //get changed service from other server asynchronously @Override public void run() { - String serviceName = null; - String serverIP = null; + ServiceKey serviceKey = null; try { while (true) { - ServiceKey serviceKey = null; - try { - serviceKey = toBeUpdatedDomsQueue.take(); + serviceKey = toBeUpdatedServicesQueue.take(); } catch (Exception e) { Loggers.EVT_LOG.error("[UPDATE-DOMAIN] Exception while taking item from LinkedBlockingDeque."); } @@ -213,14 +182,10 @@ public class ServiceManager implements DataListener { if (serviceKey == null) { continue; } - - serviceName = serviceKey.getServiceName(); - serverIP = serviceKey.getServerIP(); - - serviceUpdateExecutor.execute(new ServiceUpdater(serviceKey.getNamespaceId(), serviceName, serverIP)); + GlobalExecutor.sumbitServiceUpdate(new ServiceUpdater(serviceKey)); } } catch (Exception e) { - Loggers.EVT_LOG.error("[UPDATE-DOMAIN] Exception while update service: {} from {}, error: {}", serviceName, serverIP, e); + Loggers.EVT_LOG.error("[UPDATE-DOMAIN] Exception while update service: {}", serviceKey, e); } } } @@ -231,10 +196,10 @@ public class ServiceManager implements DataListener { String serviceName; String serverIP; - public ServiceUpdater(String namespaceId, String serviceName, String serverIP) { - this.namespaceId = namespaceId; - this.serviceName = serviceName; - this.serverIP = serverIP; + public ServiceUpdater(ServiceKey serviceKey) { + this.namespaceId = serviceKey.getNamespaceId(); + this.serviceName = serviceKey.getServiceName(); + this.serverIP = serviceKey.getServerIP(); } @Override @@ -357,7 +322,7 @@ public class ServiceManager implements DataListener { } /** - * Register an instance to a service. + * Register an instance to a service in AP mode. *

* This method creates service or cluster silently if they don't exist. * @@ -400,28 +365,9 @@ public class ServiceManager implements DataListener { serviceUpdated = true; } + // only local memory is updated: if (serviceUpdated) { - Lock lock = addLockIfAbsent(UtilsAndCommons.assembleFullServiceName(namespaceId, serviceName)); - Condition condition = addCondtion(UtilsAndCommons.assembleFullServiceName(namespaceId, serviceName)); - - final Service finalService = service; - GlobalExecutor.submit(new Runnable() { - @Override - public void run() { - try { - addOrReplaceService(finalService); - } catch (Exception e) { - Loggers.SRV_LOG.error("register or update service failed, service: {}", finalService, e); - } - } - }); - - try { - lock.lock(); - condition.await(5000, TimeUnit.MILLISECONDS); - } finally { - lock.unlock(); - } + putService(service); } if (service.allIPs().contains(instance)) { @@ -437,6 +383,11 @@ public class ServiceManager implements DataListener { Service service = getService(namespaceId, serviceName); + if (service == null) { + throw new NacosException(NacosException.INVALID_PARAM, + "service not found, namespace: " + namespaceId + ", service: " + serviceName); + } + Map instanceMap = addIpAddresses(service, ephemeral, ips); Instances instances = new Instances(); @@ -564,7 +515,6 @@ public class ServiceManager implements DataListener { serviceMap.get(service.getNamespaceId()).put(service.getName(), service); } - public List searchServices(String namespaceId, String regex) { List result = new ArrayList<>(); for (Map.Entry entry : chooseServiceMap(namespaceId).entrySet()) { @@ -716,40 +666,11 @@ public class ServiceManager implements DataListener { } } - public void wakeUp(String key) { - - Lock lock = service2LockMap.get(key); - Condition condition = service2ConditionMap.get(key); - - try { - lock.lock(); - condition.signalAll(); - } catch (Exception ignore) { - } finally { - lock.unlock(); - } - } - - public Lock addLockIfAbsent(String key) { - - if (service2LockMap.containsKey(key)) { - return service2LockMap.get(key); - } - Lock lock = new ReentrantLock(); - service2LockMap.put(key, lock); - return lock; - } - - public Condition addCondtion(String key) { - Condition condition = service2LockMap.get(key).newCondition(); - service2ConditionMap.put(key, condition); - return condition; - } - private static class ServiceKey { private String namespaceId; private String serviceName; private String serverIP; + private String checksum; public String getChecksum() { return checksum; @@ -767,13 +688,16 @@ public class ServiceManager implements DataListener { return namespaceId; } - private String checksum; - public ServiceKey(String namespaceId, String serviceName, String serverIP, String checksum) { this.namespaceId = namespaceId; this.serviceName = serviceName; this.serverIP = serverIP; this.checksum = checksum; } + + @Override + public String toString() { + return JSON.toJSONString(this); + } } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/ClientBeatProcessor.java b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/ClientBeatProcessor.java index b13020246..1c6028b39 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/ClientBeatProcessor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/ClientBeatProcessor.java @@ -18,7 +18,9 @@ package com.alibaba.nacos.naming.healthcheck; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.nacos.naming.boot.SpringContext; -import com.alibaba.nacos.naming.core.*; +import com.alibaba.nacos.naming.core.Cluster; +import com.alibaba.nacos.naming.core.Instance; +import com.alibaba.nacos.naming.core.Service; import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.UtilsAndCommons; import com.alibaba.nacos.naming.push.PushService; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HttpHealthCheckProcessor.java b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HttpHealthCheckProcessor.java index 90ef29159..35a742601 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HttpHealthCheckProcessor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/HttpHealthCheckProcessor.java @@ -18,7 +18,6 @@ package com.alibaba.nacos.naming.healthcheck; import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker; import com.alibaba.nacos.naming.core.Cluster; import com.alibaba.nacos.naming.core.Instance; -import com.alibaba.nacos.naming.core.Service; import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.monitor.MetricsMonitor; import com.ning.http.client.AsyncCompletionHandler; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/MysqlHealthCheckProcessor.java b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/MysqlHealthCheckProcessor.java index 824f12604..8670151bd 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/MysqlHealthCheckProcessor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/MysqlHealthCheckProcessor.java @@ -18,7 +18,6 @@ package com.alibaba.nacos.naming.healthcheck; import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker; import com.alibaba.nacos.naming.core.Cluster; import com.alibaba.nacos.naming.core.Instance; -import com.alibaba.nacos.naming.core.Service; import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.monitor.MetricsMonitor; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/RsInfo.java b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/RsInfo.java index 529248acc..d64a0fbd7 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/RsInfo.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/RsInfo.java @@ -36,6 +36,7 @@ public class RsInfo { private String ak; private String cluster; private double weight; + private boolean ephemeral = true; private Map metadata; public String getServiceName() { @@ -126,6 +127,14 @@ public class RsInfo { this.weight = weight; } + public boolean isEphemeral() { + return ephemeral; + } + + public void setEphemeral(boolean ephemeral) { + this.ephemeral = ephemeral; + } + public Map getMetadata() { return metadata; } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/TcpSuperSenseProcessor.java b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/TcpSuperSenseProcessor.java index e477c2d0f..ea56f43e2 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/TcpSuperSenseProcessor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/healthcheck/TcpSuperSenseProcessor.java @@ -19,8 +19,8 @@ import com.alibaba.nacos.naming.core.Cluster; import com.alibaba.nacos.naming.core.Instance; import com.alibaba.nacos.naming.core.Service; import com.alibaba.nacos.naming.misc.Loggers; -import com.alibaba.nacos.naming.monitor.MetricsMonitor; import com.alibaba.nacos.naming.misc.SwitchDomain; +import com.alibaba.nacos.naming.monitor.MetricsMonitor; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/misc/GlobalExecutor.java b/naming/src/main/java/com/alibaba/nacos/naming/misc/GlobalExecutor.java index 92919ef1e..9e99ae86f 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/misc/GlobalExecutor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/misc/GlobalExecutor.java @@ -15,10 +15,7 @@ */ package com.alibaba.nacos.naming.misc; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; /** * @author nacos @@ -103,6 +100,20 @@ public class GlobalExecutor { } }); + /** + * thread pool that processes getting service detail from other server asynchronously + */ + private static ExecutorService serviceUpdateExecutor + = Executors.newFixedThreadPool(2, new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setName("com.alibaba.nacos.naming.service.update.http.handler"); + t.setDaemon(true); + return t; + } + }); + public static void submitDataSync(Runnable runnable) { dataSyncExecutor.submit(runnable); } @@ -147,4 +158,8 @@ public class GlobalExecutor { public static void submit(Runnable runnable) { executorService.submit(runnable); } + + public static void sumbitServiceUpdate(Runnable runnable) { + serviceUpdateExecutor.execute(runnable); + } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/misc/HttpClient.java b/naming/src/main/java/com/alibaba/nacos/naming/misc/HttpClient.java index 0ab3f834a..792440e28 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/misc/HttpClient.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/misc/HttpClient.java @@ -28,7 +28,6 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchDomain.java b/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchDomain.java index 400f8c4ce..5418f9288 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchDomain.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchDomain.java @@ -93,7 +93,9 @@ public class SwitchDomain implements DataListener { public boolean enableAuthentication = false; - public String overriddenServerStatus = null; + private String overriddenServerStatus = null; + + private String serverMode = "MIXED"; public boolean isEnableAuthentication() { return enableAuthentication; @@ -361,6 +363,14 @@ public class SwitchDomain implements DataListener { this.overriddenServerStatus = overriddenServerStatus; } + public String getServerMode() { + return serverMode; + } + + public void setServerMode(String serverMode) { + this.serverMode = serverMode; + } + public void replace(SwitchDomain newSwitchDomain) { // TODO } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchEntry.java b/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchEntry.java index a8601360b..09072d6cf 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchEntry.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchEntry.java @@ -66,4 +66,5 @@ public class SwitchEntry { public static final String READ_ENABLED = "readEnabled"; public static final String OVERRIDDEN_SERVER_STATUS = "overriddenServerStatus"; + public static final String SERVER_MODE = "serverMode"; } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchManager.java b/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchManager.java index 8047c549b..f2fa01f66 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchManager.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/misc/SwitchManager.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.naming.misc; import com.alibaba.fastjson.JSON; import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.naming.cluster.ServerMode; import com.alibaba.nacos.naming.consistency.ConsistencyService; import com.alibaba.nacos.naming.consistency.Datum; import org.apache.commons.lang3.StringUtils; @@ -356,6 +357,17 @@ public class SwitchManager { return; } + if (entry.equals(SwitchEntry.SERVER_MODE)) { + String mode = value; + switchDomain.setServerMode(ServerMode.valueOf(mode).name()); + + if (!debug) { + consistencyService.put(UtilsAndCommons.getSwitchDomainKey(), JSON.toJSONString(switchDomain)); + } + + return; + } + throw new IllegalArgumentException("update entry not found: " + entry); } finally { lock.unlock(); diff --git a/naming/src/main/java/com/alibaba/nacos/naming/misc/UtilsAndCommons.java b/naming/src/main/java/com/alibaba/nacos/naming/misc/UtilsAndCommons.java index 72be67592..cecb46de6 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/misc/UtilsAndCommons.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/misc/UtilsAndCommons.java @@ -34,7 +34,6 @@ import java.util.Map; import java.util.concurrent.*; import static com.alibaba.nacos.common.util.SystemUtils.NACOS_HOME; -import static com.alibaba.nacos.common.util.SystemUtils.NACOS_HOME_KEY; /** * @author nacos @@ -119,6 +118,8 @@ public class UtilsAndCommons { public static final String DEFAULT_NAMESPACE_ID = "public"; + public static final String DEFAULT_GROUP_NAME = "DEFAULT_GROUP"; + public static final String DATA_BASE_DIR = NACOS_HOME + File.separator + "data" + File.separator + "naming"; public static final ScheduledExecutorService DOMAIN_SYNCHRONIZATION_EXECUTOR; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/monitor/PerformanceLoggerThread.java b/naming/src/main/java/com/alibaba/nacos/naming/monitor/PerformanceLoggerThread.java index 3e4743c16..b99d7000b 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/monitor/PerformanceLoggerThread.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/monitor/PerformanceLoggerThread.java @@ -22,8 +22,8 @@ import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.push.PushService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.Map; diff --git a/naming/src/main/java/com/alibaba/nacos/naming/web/AuthFilter.java b/naming/src/main/java/com/alibaba/nacos/naming/web/AuthFilter.java index 6e5b2e467..beb5a7785 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/web/AuthFilter.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/web/AuthFilter.java @@ -100,35 +100,35 @@ public class AuthFilter implements Filter { private Class mapClass(String path) throws NacosException { - if (path.contains(UtilsAndCommons.NACOS_NAMING_INSTANCE_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_INSTANCE_CONTEXT)) { return InstanceController.class; } - if (path.contains(UtilsAndCommons.NACOS_NAMING_SERVICE_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_SERVICE_CONTEXT)) { return ServiceController.class; } - if (path.contains(UtilsAndCommons.NACOS_NAMING_CLUSTER_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_CLUSTER_CONTEXT)) { return ClusterController.class; } - if (path.contains(UtilsAndCommons.NACOS_NAMING_OPERATOR_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_OPERATOR_CONTEXT)) { return OperatorController.class; } - if (path.contains(UtilsAndCommons.NACOS_NAMING_CATALOG_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_CATALOG_CONTEXT)) { return CatalogController.class; } - if (path.contains(UtilsAndCommons.NACOS_NAMING_HEALTH_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_HEALTH_CONTEXT)) { return HealthController.class; } - if (path.contains(UtilsAndCommons.NACOS_NAMING_RAFT_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_RAFT_CONTEXT)) { return RaftController.class; } - if (path.contains(UtilsAndCommons.NACOS_NAMING_PARTITION_CONTEXT)) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_PARTITION_CONTEXT)) { return PartitionController.class; } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/web/NamingConfig.java b/naming/src/main/java/com/alibaba/nacos/naming/web/NamingConfig.java index c5825fc35..25a7f8a7a 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/web/NamingConfig.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/web/NamingConfig.java @@ -19,8 +19,6 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.servlet.Filter; - /** * @author nkorange */ diff --git a/naming/src/main/java/com/alibaba/nacos/naming/web/TrafficReviseFilter.java b/naming/src/main/java/com/alibaba/nacos/naming/web/TrafficReviseFilter.java index acd586253..fd548ad99 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/web/TrafficReviseFilter.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/web/TrafficReviseFilter.java @@ -16,8 +16,10 @@ package com.alibaba.nacos.naming.web; import com.alibaba.nacos.common.util.HttpMethod; +import com.alibaba.nacos.naming.cluster.ServerMode; import com.alibaba.nacos.naming.cluster.ServerStatus; import com.alibaba.nacos.naming.cluster.ServerStatusManager; +import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.misc.UtilsAndCommons; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +28,8 @@ import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; /** * Filter incoming traffic to refuse or revise unexpected requests @@ -38,12 +42,33 @@ public class TrafficReviseFilter implements Filter { @Autowired private ServerStatusManager serverStatusManager; + @Autowired + private SwitchDomain switchDomain; + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; + // in AP mode, service and cluster cannot be edited: + try { + String path = new URI(req.getRequestURI()).getPath(); + if (ServerMode.AP.name().equals(switchDomain.getServerMode()) && !HttpMethod.GET.equals(req.getMethod())) { + if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_SERVICE_CONTEXT) + || path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_CLUSTER_CONTEXT)) { + resp.getWriter().write("server in AP mode, request: " + req.getMethod() + " " + path + " not permitted"); + resp.setStatus(HttpServletResponse.SC_FORBIDDEN); + return; + } + } + + } catch (URISyntaxException e) { + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Server parse url failed," + UtilsAndCommons.getAllExceptionMsg(e)); + return; + } + // if server is UP: if (serverStatusManager.getServerStatus() == ServerStatus.UP) { filterChain.doFilter(req, resp); diff --git a/naming/src/test/java/com/alibaba/nacos/naming/BaseTest.java b/naming/src/test/java/com/alibaba/nacos/naming/BaseTest.java index b191d2301..f2393450a 100644 --- a/naming/src/test/java/com/alibaba/nacos/naming/BaseTest.java +++ b/naming/src/test/java/com/alibaba/nacos/naming/BaseTest.java @@ -15,9 +15,9 @@ */ package com.alibaba.nacos.naming; -import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeerSet; import com.alibaba.nacos.naming.consistency.persistent.raft.RaftCore; import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeer; +import com.alibaba.nacos.naming.consistency.persistent.raft.RaftPeerSet; import com.alibaba.nacos.naming.core.ServiceManager; import com.alibaba.nacos.naming.misc.NetUtils; import org.junit.Before; diff --git a/naming/src/test/java/com/alibaba/nacos/naming/controllers/InstanceControllerTest.java b/naming/src/test/java/com/alibaba/nacos/naming/controllers/InstanceControllerTest.java index 1d4da2838..c88cf64f5 100644 --- a/naming/src/test/java/com/alibaba/nacos/naming/controllers/InstanceControllerTest.java +++ b/naming/src/test/java/com/alibaba/nacos/naming/controllers/InstanceControllerTest.java @@ -43,7 +43,6 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.locks.ReentrantLock; /** * @author nkorange @@ -87,10 +86,6 @@ public class InstanceControllerTest extends BaseTest { Mockito.when(domainsManager.getService(UtilsAndCommons.DEFAULT_NAMESPACE_ID, "nacos.test.1")).thenReturn(domain); - Mockito.when(domainsManager.addLockIfAbsent( - UtilsAndCommons.assembleFullServiceName(UtilsAndCommons.DEFAULT_NAMESPACE_ID, "nacos.test.1"))) - .thenReturn(new ReentrantLock()); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.put("/naming/instance") .param("serviceName", "nacos.test.1")