Merge pull request #997 from alibaba/feature_naming_group

Feature naming group
This commit is contained in:
Fury Zhu 2019-04-02 20:57:04 +08:00 committed by GitHub
commit e0547c82ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 471 additions and 276 deletions

View File

@ -16,7 +16,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -138,6 +138,16 @@ public interface NamingService {
*/ */
void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException; void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException;
/**
* deregister instance with full instance information
*
* @param serviceName name of service
* @param groupName group of service
* @param instance instance information
* @throws NacosException
*/
void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException;
/** /**
* get all instances of a service * get all instances of a service
* *

View File

@ -0,0 +1,30 @@
/*
* 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.api.naming;
/**
* Some keys of metadata that are recognized by Nacos
*
* @author nkorange
* @since 1.0.0
*/
public class PreservedMetadataKeys {
/**
* The key to indicate the registry source of service instance, such as Dubbo, SpringCloud, etc.
*/
public static final String REGISTER_SOURCE = "preserved.register.source";
}

View File

@ -16,7 +16,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -104,14 +104,11 @@ public class NacosNamingService implements NamingService {
private int initClientBeatThreadCount(Properties properties) { private int initClientBeatThreadCount(Properties properties) {
if (properties == null) { if (properties == null) {
return UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT; return UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT;
} }
int clientBeatThreadCount = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT), return NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT),
UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT); UtilAndComs.DEFAULT_CLIENT_BEAT_THREAD_COUNT);
return clientBeatThreadCount;
} }
private int initPollingThreadCount(Properties properties) { private int initPollingThreadCount(Properties properties) {
@ -120,10 +117,8 @@ public class NacosNamingService implements NamingService {
return UtilAndComs.DEFAULT_POLLING_THREAD_COUNT; return UtilAndComs.DEFAULT_POLLING_THREAD_COUNT;
} }
int pollingThreadCount = NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_POLLING_THREAD_COUNT), return NumberUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_POLLING_THREAD_COUNT),
UtilAndComs.DEFAULT_POLLING_THREAD_COUNT); UtilAndComs.DEFAULT_POLLING_THREAD_COUNT);
return pollingThreadCount;
} }
private boolean isLoadCacheAtStart(Properties properties) { private boolean isLoadCacheAtStart(Properties properties) {
@ -283,6 +278,7 @@ public class NacosNamingService implements NamingService {
@Override @Override
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException { public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
if (instance.isEphemeral()) {
BeatInfo beatInfo = new BeatInfo(); BeatInfo beatInfo = new BeatInfo();
beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName)); beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
beatInfo.setIp(instance.getIp()); beatInfo.setIp(instance.getIp());
@ -293,6 +289,7 @@ public class NacosNamingService implements NamingService {
beatInfo.setScheduled(false); beatInfo.setScheduled(false);
beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo); beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
}
serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance); serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
} }
@ -314,8 +311,18 @@ public class NacosNamingService implements NamingService {
@Override @Override
public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException { public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), ip, port); Instance instance = new Instance();
serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), ip, port, clusterName); instance.setIp(ip);
instance.setPort(port);
instance.setClusterName(clusterName);
deregisterInstance(serviceName, groupName, instance);
}
@Override
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(), instance.getPort());
serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), instance);
} }
@Override @Override

View File

@ -187,17 +187,18 @@ public class NamingProxy {
} }
public void deregisterService(String serviceName, String ip, int port, String clusterName) throws NacosException { public void deregisterService(String serviceName, Instance instance) throws NacosException {
NAMING_LOGGER.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}:{}@{}", NAMING_LOGGER.info("[DEREGISTER-SERVICE] {} deregistering service {} with instance: {}",
namespaceId, serviceName, ip, port, clusterName); namespaceId, serviceName, instance);
final Map<String, String> params = new HashMap<String, String>(8); final Map<String, String> params = new HashMap<String, String>(8);
params.put(CommonParams.NAMESPACE_ID, namespaceId); params.put(CommonParams.NAMESPACE_ID, namespaceId);
params.put("ip", ip);
params.put("port", String.valueOf(port));
params.put(CommonParams.SERVICE_NAME, serviceName); params.put(CommonParams.SERVICE_NAME, serviceName);
params.put(CommonParams.CLUSTER_NAME, clusterName); params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
params.put("ip", instance.getIp());
params.put("port", String.valueOf(instance.getPort()));
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.DELETE); reqAPI(UtilAndComs.NACOS_URL_INSTANCE, params, HttpMethod.DELETE);
} }

View File

@ -18,7 +18,7 @@
<parent> <parent>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -17,7 +17,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>nacos-console</artifactId> <artifactId>nacos-console</artifactId>
<!--<packaging>war</packaging>--> <!--<packaging>war</packaging>-->

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -22,10 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File; import java.io.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -59,7 +56,6 @@ public class SystemUtils {
public static final String FUNCTION_MODE_NAMING = "naming"; public static final String FUNCTION_MODE_NAMING = "naming";
private static OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory private static OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory
.getOperatingSystemMXBean(); .getOperatingSystemMXBean();
@ -128,8 +124,11 @@ public class SystemUtils {
public static List<String> readClusterConf() throws IOException { public static List<String> readClusterConf() throws IOException {
List<String> instanceList = new ArrayList<String>(); List<String> instanceList = new ArrayList<String>();
List<String> lines = IoUtils.readLines( Reader reader = null;
new InputStreamReader(new FileInputStream(new File(CLUSTER_CONF_FILE_PATH)), UTF_8));
try {
reader = new InputStreamReader(new FileInputStream(new File(CLUSTER_CONF_FILE_PATH)), UTF_8);
List<String> lines = IoUtils.readLines(reader);
String comment = "#"; String comment = "#";
for (String line : lines) { for (String line : lines) {
String instance = line.trim(); String instance = line.trim();
@ -145,6 +144,11 @@ public class SystemUtils {
instanceList.add(instance); instanceList.add(instance);
} }
return instanceList; return instanceList;
} finally {
if (reader != null) {
reader.close();
}
}
} }
public static void writeClusterConf(String content) throws IOException { public static void writeClusterConf(String content) throws IOException {

View File

@ -26,7 +26,7 @@ management.metrics.export.influx.enabled=false
#management.metrics.export.influx.compressed=true #management.metrics.export.influx.compressed=true
server.tomcat.accesslog.enabled=true server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i
# default current work dir # default current work dir
server.tomcat.basedir= server.tomcat.basedir=

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -100,7 +100,9 @@ public class DistroConsistencyServiceImpl implements EphemeralConsistencyService
public volatile Notifier notifier = new Notifier(); public volatile Notifier notifier = new Notifier();
private volatile Map<String, CopyOnWriteArrayList<RecordListener>> listeners = new ConcurrentHashMap<>(); private Map<String, CopyOnWriteArrayList<RecordListener>> listeners = new ConcurrentHashMap<>();
private Map<String, String> syncChecksumTasks = new ConcurrentHashMap<>(16);
@PostConstruct @PostConstruct
public void init() throws Exception { public void init() throws Exception {
@ -190,6 +192,16 @@ public class DistroConsistencyServiceImpl implements EphemeralConsistencyService
public void onReceiveChecksums(Map<String, String> checksumMap, String server) { public void onReceiveChecksums(Map<String, String> checksumMap, String server) {
if (syncChecksumTasks.containsKey(server)) {
// Already in process of this server:
Loggers.EPHEMERAL.warn("sync checksum task already in process with {}", server);
return;
}
syncChecksumTasks.put(server, "1");
try {
List<String> toUpdateKeys = new ArrayList<>(); List<String> toUpdateKeys = new ArrayList<>();
List<String> toRemoveKeys = new ArrayList<>(); List<String> toRemoveKeys = new ArrayList<>();
for (Map.Entry<String, String> entry : checksumMap.entrySet()) { for (Map.Entry<String, String> entry : checksumMap.entrySet()) {
@ -233,6 +245,10 @@ public class DistroConsistencyServiceImpl implements EphemeralConsistencyService
} catch (Exception e) { } catch (Exception e) {
Loggers.EPHEMERAL.error("get data from " + server + " failed!", e); Loggers.EPHEMERAL.error("get data from " + server + " failed!", e);
} }
} finally {
// Remove this 'in process' flag:
syncChecksumTasks.remove(server);
}
} }
@ -259,8 +275,9 @@ public class DistroConsistencyServiceImpl implements EphemeralConsistencyService
if (!listeners.containsKey(entry.getKey())) { if (!listeners.containsKey(entry.getKey())) {
// pretty sure the service not exist: // pretty sure the service not exist:
if (ServerMode.AP.name().equals(switchDomain.getServerMode())) { if (switchDomain.isDefaultInstanceEphemeral()) {
// create empty service // create empty service
Loggers.EPHEMERAL.info("creating service {}", entry.getKey());
Service service = new Service(); Service service = new Service();
String serviceName = KeyBuilder.getServiceName(entry.getKey()); String serviceName = KeyBuilder.getServiceName(entry.getKey());
String namespaceId = KeyBuilder.getNamespace(entry.getKey()); String namespaceId = KeyBuilder.getNamespace(entry.getKey());
@ -277,19 +294,24 @@ public class DistroConsistencyServiceImpl implements EphemeralConsistencyService
} }
for (Map.Entry<String, Datum<Instances>> entry : datumMap.entrySet()) { for (Map.Entry<String, Datum<Instances>> entry : datumMap.entrySet()) {
dataStore.put(entry.getKey(), entry.getValue());
if (!listeners.containsKey(entry.getKey())) { if (!listeners.containsKey(entry.getKey())) {
Loggers.EPHEMERAL.warn("listener not found: {}", entry.getKey()); // Should not happen:
Loggers.EPHEMERAL.warn("listener of {} not found.", entry.getKey());
continue; continue;
} }
for (RecordListener listener : listeners.get(entry.getKey())) {
try { try {
for (RecordListener listener : listeners.get(entry.getKey())) {
listener.onChange(entry.getKey(), entry.getValue().value); listener.onChange(entry.getKey(), entry.getValue().value);
}
} catch (Exception e) { } catch (Exception e) {
Loggers.EPHEMERAL.error("notify " + listener + ", key: " + entry.getKey() + " failed.", e); Loggers.EPHEMERAL.error("[NACOS-DISTRO] error while execute listener of key: {}", entry.getKey(), e);
} continue;
} }
// Update data store if listener executed successfully:
dataStore.put(entry.getKey(), entry.getValue());
} }
} }
} }
@ -384,12 +406,13 @@ public class DistroConsistencyServiceImpl implements EphemeralConsistencyService
continue; continue;
} }
} catch (Throwable e) { } catch (Throwable e) {
Loggers.EPHEMERAL.error("[NACOS-DISTRO] error while notifying listener of key: {} {}", datumKey, e); Loggers.EPHEMERAL.error("[NACOS-DISTRO] error while notifying listener of key: {}", datumKey, e);
} }
} }
if (Loggers.EPHEMERAL.isDebugEnabled()) { if (Loggers.EPHEMERAL.isDebugEnabled()) {
Loggers.EPHEMERAL.debug("[NACOS-DISTRO] datum change notified, key: {}, listener count: {}", datumKey, count); Loggers.EPHEMERAL.debug("[NACOS-DISTRO] datum change notified, key: {}, listener count: {}, action: {}",
datumKey, count, action.name());
} }
} catch (Throwable e) { } catch (Throwable e) {
Loggers.EPHEMERAL.error("[NACOS-DISTRO] Error while handling notifying task", e); Loggers.EPHEMERAL.error("[NACOS-DISTRO] Error while handling notifying task", e);

View File

@ -100,14 +100,16 @@ public class TaskDispatcher {
continue; continue;
} }
if (StringUtils.isBlank(key)) {
continue;
}
if (dataSize == 0) { if (dataSize == 0) {
keys = new ArrayList<>(); keys = new ArrayList<>();
} }
if (StringUtils.isNotBlank(key)) {
keys.add(key); keys.add(key);
dataSize++; dataSize++;
}
if (dataSize == partitionConfig.getBatchSyncKeyCount() || if (dataSize == partitionConfig.getBatchSyncKeyCount() ||
(System.currentTimeMillis() - lastDispatchTime) > partitionConfig.getTaskDispatchPeriod()) { (System.currentTimeMillis() - lastDispatchTime) > partitionConfig.getTaskDispatchPeriod()) {

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.naming.consistency.persistent.raft;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.naming.cluster.ServerStatus; import com.alibaba.nacos.naming.cluster.ServerStatus;
import com.alibaba.nacos.naming.consistency.Datum; import com.alibaba.nacos.naming.consistency.Datum;
import com.alibaba.nacos.naming.consistency.KeyBuilder;
import com.alibaba.nacos.naming.consistency.RecordListener; import com.alibaba.nacos.naming.consistency.RecordListener;
import com.alibaba.nacos.naming.consistency.persistent.PersistentConsistencyService; import com.alibaba.nacos.naming.consistency.persistent.PersistentConsistencyService;
import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.Loggers;
@ -38,6 +39,9 @@ public class RaftConsistencyServiceImpl implements PersistentConsistencyService
@Autowired @Autowired
private RaftCore raftCore; private RaftCore raftCore;
@Autowired
private RaftPeerSet peers;
@Autowired @Autowired
private SwitchDomain switchDomain; private SwitchDomain switchDomain;
@ -54,6 +58,12 @@ public class RaftConsistencyServiceImpl implements PersistentConsistencyService
@Override @Override
public void remove(String key) throws NacosException { public void remove(String key) throws NacosException {
try { try {
if (KeyBuilder.matchInstanceListKey(key) && !raftCore.isLeader()) {
Datum datum = new Datum();
datum.key = key;
raftCore.onDelete(datum.key, peers.getLeader());
return;
}
raftCore.signalDelete(key); raftCore.signalDelete(key);
} catch (Exception e) { } catch (Exception e) {
Loggers.RAFT.error("Raft remove failed.", e); Loggers.RAFT.error("Raft remove failed.", e);
@ -92,7 +102,7 @@ public class RaftConsistencyServiceImpl implements PersistentConsistencyService
public void onRemove(Datum datum, RaftPeer source) throws NacosException { public void onRemove(Datum datum, RaftPeer source) throws NacosException {
try { try {
raftCore.onDelete(datum, source); raftCore.onDelete(datum.key, source);
} catch (Exception e) { } catch (Exception e) {
Loggers.RAFT.error("Raft onRemove failed.", e); Loggers.RAFT.error("Raft onRemove failed.", e);
throw new NacosException(NacosException.SERVER_ERROR, "Raft onRemove failed, datum:" + datum + ", source: " + source); throw new NacosException(NacosException.SERVER_ERROR, "Raft onRemove failed, datum:" + datum + ", source: " + source);

View File

@ -213,7 +213,7 @@ public class RaftCore {
if (!latch.await(UtilsAndCommons.RAFT_PUBLISH_TIMEOUT, TimeUnit.MILLISECONDS)) { if (!latch.await(UtilsAndCommons.RAFT_PUBLISH_TIMEOUT, TimeUnit.MILLISECONDS)) {
// only majority servers return success can we consider this update success // only majority servers return success can we consider this update success
Loggers.RAFT.info("data publish failed, caused failed to notify majority, key={}", key); Loggers.RAFT.error("data publish failed, caused failed to notify majority, key={}", key);
throw new IllegalStateException("data publish failed, caused failed to notify majority, key=" + key); throw new IllegalStateException("data publish failed, caused failed to notify majority, key=" + key);
} }
@ -243,7 +243,7 @@ public class RaftCore {
json.put("datum", datum); json.put("datum", datum);
json.put("source", peers.local()); json.put("source", peers.local());
onDelete(datum, peers.local()); onDelete(datum.key, peers.local());
for (final String server : peers.allServersWithoutMySelf()) { for (final String server : peers.allServersWithoutMySelf()) {
String url = buildURL(server, API_ON_DEL); String url = buildURL(server, API_ON_DEL);
@ -317,7 +317,7 @@ public class RaftCore {
Loggers.RAFT.info("data added/updated, key={}, term={}", datum.key, local.term); Loggers.RAFT.info("data added/updated, key={}, term={}", datum.key, local.term);
} }
public void onDelete(Datum datum, RaftPeer source) throws Exception { public void onDelete(String datumKey, RaftPeer source) throws Exception {
RaftPeer local = peers.local(); RaftPeer local = peers.local();
@ -337,7 +337,7 @@ public class RaftCore {
local.resetLeaderDue(); local.resetLeaderDue();
// do apply // do apply
String key = datum.key; String key = datumKey;
deleteDatum(key); deleteDatum(key);
if (KeyBuilder.matchServiceMetaKey(key)) { if (KeyBuilder.matchServiceMetaKey(key)) {
@ -353,7 +353,7 @@ public class RaftCore {
raftStore.updateTerm(local.term.get()); raftStore.updateTerm(local.term.get());
} }
Loggers.RAFT.info("data removed, key={}, term={}", datum.key, local.term); Loggers.RAFT.info("data removed, key={}, term={}", datumKey, local.term);
} }
@ -667,41 +667,49 @@ public class RaftCore {
return 1; return 1;
} }
List<Datum> datumList = JSON.parseObject(response.getResponseBody(), new TypeReference<List<Datum>>() { List<JSONObject> datumList = JSON.parseObject(response.getResponseBody(), new TypeReference<List<JSONObject>>() {
}); });
for (Datum datum : datumList) { for (JSONObject datumJson : datumList) {
OPERATE_LOCK.lock(); OPERATE_LOCK.lock();
Datum newDatum = null;
try { try {
Datum oldDatum = getDatum(datum.key); Datum oldDatum = getDatum(datumJson.getString("key"));
if (oldDatum != null && datum.timestamp.get() <= oldDatum.timestamp.get()) { if (oldDatum != null && datumJson.getLongValue("timestamp") <= oldDatum.timestamp.get()) {
Loggers.RAFT.info("[NACOS-RAFT] timestamp is smaller than that of mine, key: {}, remote: {}, local: {}", Loggers.RAFT.info("[NACOS-RAFT] timestamp is smaller than that of mine, key: {}, remote: {}, local: {}",
datum.key, datum.timestamp, oldDatum.timestamp); datumJson.getString("key"), datumJson.getLongValue("timestamp"), oldDatum.timestamp);
continue; continue;
} }
raftStore.write(datum); if (KeyBuilder.matchServiceMetaKey(datumJson.getString("key"))) {
if (KeyBuilder.matchServiceMetaKey(datum.key)) {
Datum<Service> serviceDatum = new Datum<>(); Datum<Service> serviceDatum = new Datum<>();
serviceDatum.key = datum.key; serviceDatum.key = datumJson.getString("key");
serviceDatum.timestamp.set(datum.timestamp.get()); serviceDatum.timestamp.set(datumJson.getLongValue("timestamp"));
serviceDatum.value = JSON.parseObject(JSON.toJSONString(datum.value), Service.class); serviceDatum.value =
datum = serviceDatum; JSON.parseObject(JSON.toJSONString(datumJson.getJSONObject("value")), Service.class);
newDatum = serviceDatum;
} }
if (KeyBuilder.matchInstanceListKey(datum.key)) { if (KeyBuilder.matchInstanceListKey(datumJson.getString("key"))) {
Datum<Instances> instancesDatum = new Datum<>(); Datum<Instances> instancesDatum = new Datum<>();
instancesDatum.key = datum.key; instancesDatum.key = datumJson.getString("key");
instancesDatum.timestamp.set(datum.timestamp.get()); instancesDatum.timestamp.set(datumJson.getLongValue("timestamp"));
instancesDatum.value = JSON.parseObject(JSON.toJSONString(datum.value), Instances.class); instancesDatum.value =
datum = instancesDatum; JSON.parseObject(JSON.toJSONString(datumJson.getJSONObject("value")), Instances.class);
newDatum = instancesDatum;
} }
datums.put(datum.key, datum); if (newDatum == null || newDatum.value == null) {
notifier.addTask(datum.key, ApplyAction.CHANGE); Loggers.RAFT.error("receive null datum: {}", datumJson);
continue;
}
raftStore.write(newDatum);
datums.put(newDatum.key, newDatum);
notifier.addTask(newDatum.key, ApplyAction.CHANGE);
local.resetLeaderDue(); local.resetLeaderDue();
@ -715,10 +723,10 @@ public class RaftCore {
raftStore.updateTerm(local.term.get()); raftStore.updateTerm(local.term.get());
Loggers.RAFT.info("data updated, key: {}, timestamp: {}, from {}, local term: {}", Loggers.RAFT.info("data updated, key: {}, timestamp: {}, from {}, local term: {}",
datum.key, datum.timestamp, JSON.toJSONString(remote), local.term); newDatum.key, newDatum.timestamp, JSON.toJSONString(remote), local.term);
} catch (Throwable e) { } catch (Throwable e) {
Loggers.RAFT.error("[RAFT-BEAT] failed to sync datum from leader, key: {} {}", datum.key, e); Loggers.RAFT.error("[RAFT-BEAT] failed to sync datum from leader, datum: {}", newDatum, e);
} finally { } finally {
OPERATE_LOCK.unlock(); OPERATE_LOCK.unlock();
} }
@ -863,7 +871,6 @@ public class RaftCore {
} }
private void deleteDatum(String key) { private void deleteDatum(String key) {
Datum deleted; Datum deleted;
try { try {
deleted = datums.remove(URLDecoder.decode(key, "UTF-8")); deleted = datums.remove(URLDecoder.decode(key, "UTF-8"));
@ -881,6 +888,10 @@ public class RaftCore {
return initialized || !globalConfig.isDataWarmup(); return initialized || !globalConfig.isDataWarmup();
} }
public int getNotifyTaskCount() {
return notifier.getTaskSize();
}
public class Notifier implements Runnable { public class Notifier implements Runnable {
private ConcurrentHashMap<String, String> services = new ConcurrentHashMap<>(10 * 1024); private ConcurrentHashMap<String, String> services = new ConcurrentHashMap<>(10 * 1024);
@ -895,6 +906,9 @@ public class RaftCore {
if (action == ApplyAction.CHANGE) { if (action == ApplyAction.CHANGE) {
services.put(datumKey, StringUtils.EMPTY); services.put(datumKey, StringUtils.EMPTY);
} }
Loggers.RAFT.info("add task {}", datumKey);
tasks.add(Pair.with(datumKey, action)); tasks.add(Pair.with(datumKey, action));
} }
@ -920,6 +934,8 @@ public class RaftCore {
services.remove(datumKey); services.remove(datumKey);
Loggers.RAFT.info("remove task {}", datumKey);
int count = 0; int count = 0;
if (listeners.containsKey(KeyBuilder.SERVICE_META_KEY_PREFIX)) { if (listeners.containsKey(KeyBuilder.SERVICE_META_KEY_PREFIX)) {
@ -936,7 +952,7 @@ public class RaftCore {
listener.onDelete(datumKey); listener.onDelete(datumKey);
} }
} catch (Throwable e) { } catch (Throwable e) {
Loggers.RAFT.error("[NACOS-RAFT] error while notifying listener of key: {} {}", datumKey, e); Loggers.RAFT.error("[NACOS-RAFT] error while notifying listener of key: {}", datumKey, e);
} }
} }
} }
@ -961,7 +977,7 @@ public class RaftCore {
continue; continue;
} }
} catch (Throwable e) { } catch (Throwable e) {
Loggers.RAFT.error("[NACOS-RAFT] error while notifying listener of key: {} {}", datumKey, e); Loggers.RAFT.error("[NACOS-RAFT] error while notifying listener of key: {}", datumKey, e);
} }
} }

View File

@ -24,6 +24,7 @@ import com.alibaba.nacos.naming.core.DistroMapper;
import com.alibaba.nacos.naming.core.ServiceManager; import com.alibaba.nacos.naming.core.ServiceManager;
import com.alibaba.nacos.naming.misc.UtilsAndCommons; import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.push.ClientInfo; import com.alibaba.nacos.naming.push.ClientInfo;
import com.alibaba.nacos.naming.web.CanDistro;
import com.alibaba.nacos.naming.web.OverrideParameterRequestWrapper; import com.alibaba.nacos.naming.web.OverrideParameterRequestWrapper;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -138,6 +139,7 @@ public class ApiController extends InstanceController {
agent, clusters, clientIP, udpPort, env, isCheck, app, tenant, healthyOnly); agent, clusters, clientIP, udpPort, env, isCheck, app, tenant, healthyOnly);
} }
@CanDistro
@RequestMapping("/clientBeat") @RequestMapping("/clientBeat")
public JSONObject clientBeat(HttpServletRequest request) throws Exception { public JSONObject clientBeat(HttpServletRequest request) throws Exception {
OverrideParameterRequestWrapper requestWrapper = OverrideParameterRequestWrapper.buildRequest(request); OverrideParameterRequestWrapper requestWrapper = OverrideParameterRequestWrapper.buildRequest(request);

View File

@ -96,9 +96,8 @@ public class ClusterController {
cluster.setHealthChecker(abstractHealthChecker); cluster.setHealthChecker(abstractHealthChecker);
cluster.setMetadata(UtilsAndCommons.parseMetadata(metadata)); cluster.setMetadata(UtilsAndCommons.parseMetadata(metadata));
cluster.init();
service.getClusterMap().put(clusterName, cluster); service.getClusterMap().put(clusterName, cluster);
service.setLastModifiedMillis(System.currentTimeMillis()); service.setLastModifiedMillis(System.currentTimeMillis());
service.recalculateChecksum(); service.recalculateChecksum();
service.validate(); service.validate();

View File

@ -15,6 +15,7 @@
*/ */
package com.alibaba.nacos.naming.controllers; package com.alibaba.nacos.naming.controllers;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.core.utils.WebUtils; import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.cluster.ServerMode; import com.alibaba.nacos.naming.cluster.ServerMode;
@ -84,8 +85,8 @@ public class DistroController {
String namespaceId = KeyBuilder.getNamespace(entry.getKey()); String namespaceId = KeyBuilder.getNamespace(entry.getKey());
String serviceName = KeyBuilder.getServiceName(entry.getKey()); String serviceName = KeyBuilder.getServiceName(entry.getKey());
if (!serviceManager.containService(namespaceId, serviceName) if (!serviceManager.containService(namespaceId, serviceName)
&& ServerMode.AP.name().equals(switchDomain.getServerMode())) { && switchDomain.isDefaultInstanceEphemeral()) {
serviceManager.createEmptyService(namespaceId, serviceName); serviceManager.createEmptyService(namespaceId, serviceName, true);
} }
consistencyService.onPut(entry.getKey(), entry.getValue().value); consistencyService.onPut(entry.getKey(), entry.getValue().value);
} }
@ -106,7 +107,9 @@ public class DistroController {
@RequestMapping(value = "/datum", method = RequestMethod.GET) @RequestMapping(value = "/datum", method = RequestMethod.GET)
public void get(HttpServletRequest request, HttpServletResponse response) throws Exception { public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
String keys = WebUtils.required(request, "keys");
String entity = IOUtils.toString(request.getInputStream(), "UTF-8");
String keys = JSON.parseObject(entity).getString("keys");
String keySplitter = ","; String keySplitter = ",";
Map<String, Datum> datumMap = new HashMap<>(64); Map<String, Datum> datumMap = new HashMap<>(64);
for (String key : keys.split(keySplitter)) { for (String key : keys.split(keySplitter)) {

View File

@ -25,20 +25,18 @@ import com.alibaba.nacos.naming.core.Instance;
import com.alibaba.nacos.naming.core.Service; import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager; import com.alibaba.nacos.naming.core.ServiceManager;
import com.alibaba.nacos.naming.healthcheck.HealthCheckType; import com.alibaba.nacos.naming.healthcheck.HealthCheckType;
import com.alibaba.nacos.naming.misc.HttpClient;
import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.UtilsAndCommons; import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.push.PushService; import com.alibaba.nacos.naming.push.PushService;
import com.alibaba.nacos.naming.web.CanDistro;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
/** /**
* Health status related operation controller * Health status related operation controller
@ -68,40 +66,31 @@ public class HealthController {
return result; return result;
} }
@CanDistro
@RequestMapping(value = {"", "/instance"}, method = RequestMethod.PUT) @RequestMapping(value = {"", "/instance"}, method = RequestMethod.PUT)
public String update(HttpServletRequest request) throws Exception { public String update(HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID,
Constants.DEFAULT_NAMESPACE_ID); Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
String ip = WebUtils.required(request, "ip");
int port = Integer.parseInt(WebUtils.required(request, "port"));
boolean valid = Boolean.valueOf(WebUtils.required(request, "valid"));
String clusterName = WebUtils.optional(request, CommonParams.CLUSTER_NAME String clusterName = WebUtils.optional(request, CommonParams.CLUSTER_NAME
, UtilsAndCommons.DEFAULT_CLUSTER_NAME); , UtilsAndCommons.DEFAULT_CLUSTER_NAME);
if (!distroMapper.responsible(serviceName)) { String ip = WebUtils.required(request, "ip");
String server = distroMapper.mapSrv(serviceName); int port = Integer.parseInt(WebUtils.required(request, "port"));
Loggers.EVT_LOG.info("I'm not responsible for " + serviceName + ", proxy it to " + server);
Map<String, String> proxyParams = new HashMap<>(16); boolean valid = false;
for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
String key = entry.getKey(); String healthyString = WebUtils.optional(request, "healthy", StringUtils.EMPTY);
String value = entry.getValue()[0]; if (StringUtils.isBlank(healthyString)) {
proxyParams.put(key, value); healthyString = WebUtils.optional(request, "valid", StringUtils.EMPTY);
} }
if (!server.contains(UtilsAndCommons.IP_PORT_SPLITER)) { if (StringUtils.isBlank(healthyString)) {
server = server + UtilsAndCommons.IP_PORT_SPLITER + RunningConfig.getServerPort(); throw new IllegalArgumentException("Param 'healthy' is required.");
} }
String url = "http://" + server + RunningConfig.getContextPath()
+ UtilsAndCommons.NACOS_NAMING_CONTEXT + "/health";
HttpClient.HttpResult httpResult = HttpClient.httpPost(url, null, proxyParams);
if (httpResult.code != HttpURLConnection.HTTP_OK) {
throw new IllegalArgumentException("failed to proxy health update to " + server + ", service: " + serviceName);
}
} else {
Service service = serviceManager.getService(namespaceId, serviceName); Service service = serviceManager.getService(namespaceId, serviceName);
// Only health check "none" need update health status with api // Only health check "none" need update health status with api
if (HealthCheckType.NONE.name().equals(service.getClusterMap().get(clusterName).getHealthChecker().getType())) { if (HealthCheckType.NONE.name().equals(service.getClusterMap().get(clusterName).getHealthChecker().getType())) {
@ -116,9 +105,9 @@ public class HealthController {
} }
} }
} else { } else {
throw new IllegalArgumentException("health check mode 'client' and 'server' are not supported, service: " + serviceName); throw new IllegalArgumentException("health check is still working, service: " + serviceName);
}
} }
return "ok"; return "ok";
} }
} }

View File

@ -187,7 +187,8 @@ public class InstanceController {
List<Instance> ips = service.allIPs(clusters); List<Instance> ips = service.allIPs(clusters);
if (ips == null || ips.isEmpty()) { if (ips == null || ips.isEmpty()) {
throw new IllegalStateException("no ips found for cluster " + cluster + " in service " + serviceName); throw new NacosException(NacosException.NOT_FOUND,
"no ips found for cluster " + cluster + " in service " + serviceName);
} }
for (Instance instance : ips) { for (Instance instance : ips) {
@ -205,7 +206,7 @@ public class InstanceController {
} }
} }
throw new IllegalStateException("no matched ip found!"); throw new NacosException(NacosException.NOT_FOUND, "no matched ip found!");
} }
@CanDistro @CanDistro
@ -216,15 +217,15 @@ public class InstanceController {
result.put("clientBeatInterval", switchDomain.getClientBeatInterval()); 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, String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID,
Constants.DEFAULT_NAMESPACE_ID); Constants.DEFAULT_NAMESPACE_ID);
String beat = WebUtils.required(request, "beat"); String beat = WebUtils.required(request, "beat");
RsInfo clientBeat = JSON.parseObject(beat, RsInfo.class); RsInfo clientBeat = JSON.parseObject(beat, RsInfo.class);
if (!switchDomain.isDefaultInstanceEphemeral() && !clientBeat.isEphemeral()) {
return result;
}
if (StringUtils.isBlank(clientBeat.getCluster())) { if (StringUtils.isBlank(clientBeat.getCluster())) {
clientBeat.setCluster(UtilsAndCommons.DEFAULT_CLUSTER_NAME); clientBeat.setCluster(UtilsAndCommons.DEFAULT_CLUSTER_NAME);
} }
@ -323,16 +324,6 @@ public class InstanceController {
throw new NacosException(NacosException.INVALID_PARAM, "instance format invalid:" + instance); throw new NacosException(NacosException.INVALID_PARAM, "instance format invalid:" + instance);
} }
if ((ServerMode.AP.name().equals(switchDomain.getServerMode()) && !instance.isEphemeral())) {
throw new NacosException(NacosException.INVALID_PARAM, "wrong instance type: " + instance.isEphemeral()
+ " in " + switchDomain.getServerMode() + " mode.");
}
if ((ServerMode.CP.name().equals(switchDomain.getServerMode()) && instance.isEphemeral())) {
throw new NacosException(NacosException.INVALID_PARAM, "wrong instance type: " + instance.isEphemeral()
+ " in " + switchDomain.getServerMode() + " mode.");
}
return instance; return instance;
} }
@ -346,7 +337,7 @@ public class InstanceController {
boolean enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true")); boolean enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true"));
// If server running in CP mode, we set this flag to false: // If server running in CP mode, we set this flag to false:
boolean ephemeral = BooleanUtils.toBoolean(WebUtils.optional(request, "ephemeral", boolean ephemeral = BooleanUtils.toBoolean(WebUtils.optional(request, "ephemeral",
String.valueOf(!ServerMode.CP.name().equals(switchDomain.getServerMode())))); String.valueOf(switchDomain.isDefaultInstanceEphemeral())));
Instance instance = new Instance(); Instance instance = new Instance();
instance.setPort(Integer.parseInt(port)); instance.setPort(Integer.parseInt(port));

View File

@ -23,6 +23,7 @@ import com.alibaba.nacos.core.utils.SystemUtils;
import com.alibaba.nacos.core.utils.WebUtils; import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.cluster.ServerListManager; import com.alibaba.nacos.naming.cluster.ServerListManager;
import com.alibaba.nacos.naming.cluster.ServerStatusManager; import com.alibaba.nacos.naming.cluster.ServerStatusManager;
import com.alibaba.nacos.naming.consistency.persistent.raft.RaftCore;
import com.alibaba.nacos.naming.core.DistroMapper; import com.alibaba.nacos.naming.core.DistroMapper;
import com.alibaba.nacos.naming.core.Service; import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager; import com.alibaba.nacos.naming.core.ServiceManager;
@ -73,6 +74,9 @@ public class OperatorController {
@Autowired @Autowired
private DistroMapper distroMapper; private DistroMapper distroMapper;
@Autowired
private RaftCore raftCore;
@RequestMapping("/push/state") @RequestMapping("/push/state")
public JSONObject pushState(HttpServletRequest request) { public JSONObject pushState(HttpServletRequest request) {
@ -144,6 +148,7 @@ public class OperatorController {
result.put("status", serverStatusManager.getServerStatus().name()); result.put("status", serverStatusManager.getServerStatus().name());
result.put("serviceCount", serviceCount); result.put("serviceCount", serviceCount);
result.put("instanceCount", ipCount); result.put("instanceCount", ipCount);
result.put("raftNotifyTaskCount", raftCore.getNotifyTaskCount());
result.put("responsibleServiceCount", responsibleDomCount); result.put("responsibleServiceCount", responsibleDomCount);
result.put("responsibleInstanceCount", responsibleIPCount); result.put("responsibleInstanceCount", responsibleIPCount);
result.put("cpu", SystemUtils.getCPU()); result.put("cpu", SystemUtils.getCPU());

View File

@ -50,7 +50,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* HTTP interfaces for Raft consistency protocol. These interfaces should only be invoked by Nacos server itself. * Methods for Raft consistency protocol. These methods should only be invoked by Nacos server itself.
* *
* @author nkorange * @author nkorange
* @since 1.0.0 * @since 1.0.0
@ -83,7 +83,6 @@ public class RaftController {
public JSONObject beat(HttpServletRequest request, HttpServletResponse response) throws Exception { public JSONObject beat(HttpServletRequest request, HttpServletResponse response) throws Exception {
String entity = new String(IoUtils.tryDecompress(request.getInputStream()), "UTF-8"); String entity = new String(IoUtils.tryDecompress(request.getInputStream()), "UTF-8");
// String value = Arrays.asList(entity).toArray(new String[1])[0];
String value = URLDecoder.decode(entity, "UTF-8"); String value = URLDecoder.decode(entity, "UTF-8");
value = URLDecoder.decode(value, "UTF-8"); value = URLDecoder.decode(value, "UTF-8");
@ -240,7 +239,6 @@ public class RaftController {
response.setHeader("Content-Encode", "gzip"); response.setHeader("Content-Encode", "gzip");
String entity = IOUtils.toString(request.getInputStream(), "UTF-8"); String entity = IOUtils.toString(request.getInputStream(), "UTF-8");
// String value = Arrays.asList(entity).toArray(new String[1])[0];
String value = URLDecoder.decode(entity, "UTF-8"); String value = URLDecoder.decode(entity, "UTF-8");
value = URLDecoder.decode(value, "UTF-8"); value = URLDecoder.decode(value, "UTF-8");
JSONObject jsonObject = JSON.parseObject(value); JSONObject jsonObject = JSON.parseObject(value);

View File

@ -31,6 +31,7 @@ import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.selector.LabelSelector; import com.alibaba.nacos.naming.selector.LabelSelector;
import com.alibaba.nacos.naming.selector.NoneSelector; import com.alibaba.nacos.naming.selector.NoneSelector;
import com.alibaba.nacos.naming.selector.Selector; import com.alibaba.nacos.naming.selector.Selector;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -39,6 +40,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.*; import java.util.*;
@ -105,15 +107,6 @@ public class ServiceController {
Constants.DEFAULT_NAMESPACE_ID); Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
Service service = serviceManager.getService(namespaceId, serviceName);
if (service == null) {
throw new IllegalArgumentException("specified service not exist, serviceName : " + serviceName);
}
if (!service.allIPs().isEmpty()) {
throw new IllegalArgumentException("specified service has instances, serviceName : " + serviceName);
}
serviceManager.easyRemoveService(namespaceId, serviceName); serviceManager.easyRemoveService(namespaceId, serviceName);
return "ok"; return "ok";
@ -299,13 +292,19 @@ public class ServiceController {
} }
@RequestMapping(value = "/status", method = RequestMethod.POST) @RequestMapping(value = "/status", method = RequestMethod.POST)
public String serviceStatus(HttpServletRequest request) { public String serviceStatus(HttpServletRequest request) throws Exception {
String entity = IOUtils.toString(request.getInputStream(), "UTF-8");
String value = URLDecoder.decode(entity, "UTF-8");
JSONObject json = JSON.parseObject(value);
//format: service1@@checksum@@@service2@@checksum //format: service1@@checksum@@@service2@@checksum
String statuses = WebUtils.required(request, "statuses"); String statuses = json.getString("statuses");
String serverIP = WebUtils.optional(request, "clientIP", ""); String serverIP = json.getString("clientIP");
if (!serverListManager.contains(serverIP)) { if (!serverListManager.contains(serverIP)) {
throw new IllegalArgumentException("ip: " + serverIP + " is not in serverlist"); throw new NacosException(NacosException.INVALID_PARAM,
"ip: " + serverIP + " is not in serverlist");
} }
try { try {
@ -345,7 +344,7 @@ public class ServiceController {
} }
@RequestMapping(value = "/checksum", method = RequestMethod.PUT) @RequestMapping(value = "/checksum", method = RequestMethod.PUT)
public JSONObject checksum(HttpServletRequest request) { public JSONObject checksum(HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID,
Constants.DEFAULT_NAMESPACE_ID); Constants.DEFAULT_NAMESPACE_ID);
@ -353,7 +352,8 @@ public class ServiceController {
Service service = serviceManager.getService(namespaceId, serviceName); Service service = serviceManager.getService(namespaceId, serviceName);
if (service == null) { if (service == null) {
throw new IllegalArgumentException("serviceName not found: " + serviceName); throw new NacosException(NacosException.NOT_FOUND,
"serviceName not found: " + serviceName);
} }
service.recalculateChecksum(); service.recalculateChecksum();

View File

@ -54,6 +54,9 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
@JSONField(serialize = false) @JSONField(serialize = false)
private Service service; private Service service;
@JSONField(serialize = false)
private volatile boolean inited = false;
private Map<String, String> metadata = new ConcurrentHashMap<>(); private Map<String, String> metadata = new ConcurrentHashMap<>();
public Cluster() { public Cluster() {
@ -87,8 +90,12 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
} }
public void init() { public void init() {
if (inited) {
return;
}
checkTask = new HealthCheckTask(this); checkTask = new HealthCheckTask(this);
HealthCheckReactor.scheduleCheck(checkTask); HealthCheckReactor.scheduleCheck(checkTask);
inited = true;
} }
public void destroy() { public void destroy() {
@ -105,6 +112,7 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
public void setService(Service service) { public void setService(Service service) {
this.service = service; this.service = service;
this.setServiceName(service.getName());
} }
@Override @Override

View File

@ -181,7 +181,7 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
} }
if (ip == null) { if (ip == null) {
throw new IllegalArgumentException("malfomed ip config: " + json); throw new IllegalArgumentException("malformed ip config: " + json);
} }
if (ip.getWeight() > MAX_WEIGHT_VALUE) { if (ip.getWeight() > MAX_WEIGHT_VALUE) {
@ -195,7 +195,7 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
} }
if (!ip.validate()) { if (!ip.validate()) {
throw new IllegalArgumentException("malfomed ip config: " + json); throw new IllegalArgumentException("malformed ip config: " + json);
} }
return ip; return ip;

View File

@ -25,6 +25,7 @@ import java.math.BigInteger;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -40,7 +41,7 @@ public class Instances implements Record {
private long lastCalculateTime = 0L; private long lastCalculateTime = 0L;
private List<Instance> instanceList; private List<Instance> instanceList = new ArrayList<>();
public List<Instance> getInstanceList() { public List<Instance> getInstanceList() {
return instanceList; return instanceList;

View File

@ -18,8 +18,8 @@ package com.alibaba.nacos.naming.core;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.nacos.naming.boot.SpringContext; import com.alibaba.nacos.naming.boot.SpringContext;
import com.alibaba.nacos.naming.consistency.RecordListener;
import com.alibaba.nacos.naming.consistency.KeyBuilder; import com.alibaba.nacos.naming.consistency.KeyBuilder;
import com.alibaba.nacos.naming.consistency.RecordListener;
import com.alibaba.nacos.naming.healthcheck.ClientBeatCheckTask; import com.alibaba.nacos.naming.healthcheck.ClientBeatCheckTask;
import com.alibaba.nacos.naming.healthcheck.ClientBeatProcessor; import com.alibaba.nacos.naming.healthcheck.ClientBeatProcessor;
import com.alibaba.nacos.naming.healthcheck.HealthCheckReactor; import com.alibaba.nacos.naming.healthcheck.HealthCheckReactor;
@ -44,9 +44,9 @@ import java.util.*;
* Service of Nacos server side * Service of Nacos server side
* <p> * <p>
* We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters, * We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters,
* which contains a list of instances. * which contain a list of instances.
* <p> * <p>
* This class inherits from Service in API module and stores some fields that do not expose to client. * This class inherits from Service in API module and stores some fields that do not have to expose to client.
* *
* @author nkorange * @author nkorange
*/ */
@ -154,14 +154,19 @@ public class Service extends com.alibaba.nacos.api.naming.pojo.Service implement
Loggers.SRV_LOG.info("[NACOS-RAFT] datum is changed, key: {}, value: {}", key, value); Loggers.SRV_LOG.info("[NACOS-RAFT] datum is changed, key: {}, value: {}", key, value);
for (Instance ip : value.getInstanceList()) { for (Instance instance : value.getInstanceList()) {
if (ip.getWeight() > 10000.0D) { if (instance == null) {
ip.setWeight(10000.0D); // Reject this abnormal instance list:
throw new RuntimeException("got null instance " + key);
} }
if (ip.getWeight() < 0.01D && ip.getWeight() > 0.0D) { if (instance.getWeight() > 10000.0D) {
ip.setWeight(0.01D); instance.setWeight(10000.0D);
}
if (instance.getWeight() < 0.01D && instance.getWeight() > 0.0D) {
instance.setWeight(0.01D);
} }
} }

View File

@ -21,7 +21,6 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.naming.cluster.ServerListManager; import com.alibaba.nacos.naming.cluster.ServerListManager;
import com.alibaba.nacos.naming.cluster.ServerMode;
import com.alibaba.nacos.naming.cluster.servers.Server; import com.alibaba.nacos.naming.cluster.servers.Server;
import com.alibaba.nacos.naming.consistency.ConsistencyService; import com.alibaba.nacos.naming.consistency.ConsistencyService;
import com.alibaba.nacos.naming.consistency.Datum; import com.alibaba.nacos.naming.consistency.Datum;
@ -79,6 +78,8 @@ public class ServiceManager implements RecordListener<Service> {
@Autowired @Autowired
private PushService pushService; private PushService pushService;
private final Object putServiceLock = new Object();
@PostConstruct @PostConstruct
public void init() { public void init() {
@ -155,9 +156,15 @@ public class ServiceManager implements RecordListener<Service> {
public void onDelete(String key) throws Exception { public void onDelete(String key) throws Exception {
String namespace = KeyBuilder.getNamespace(key); String namespace = KeyBuilder.getNamespace(key);
String name = KeyBuilder.getServiceName(key); String name = KeyBuilder.getServiceName(key);
Service service = chooseServiceMap(namespace).remove(name); Service service = chooseServiceMap(namespace).get(name);
Loggers.RAFT.info("[RAFT-NOTIFIER] datum is deleted, key: {}", key); Loggers.RAFT.info("[RAFT-NOTIFIER] datum is deleted, key: {}", key);
// check again:
if (service != null && !service.allIPs().isEmpty()) {
Loggers.SRV_LOG.warn("service not empty, key: {}", key);
return;
}
if (service != null) { if (service != null) {
service.destroy(); service.destroy();
consistencyService.remove(KeyBuilder.buildInstanceListKey(namespace, name, true)); consistencyService.remove(KeyBuilder.buildInstanceListKey(namespace, name, true));
@ -165,6 +172,8 @@ public class ServiceManager implements RecordListener<Service> {
consistencyService.unlisten(KeyBuilder.buildServiceMetaKey(namespace, name), service); consistencyService.unlisten(KeyBuilder.buildServiceMetaKey(namespace, name), service);
Loggers.SRV_LOG.info("[DEAD-SERVICE] {}", service.toJSON()); Loggers.SRV_LOG.info("[DEAD-SERVICE] {}", service.toJSON());
} }
chooseServiceMap(namespace).remove(name);
} }
private class UpdatedServiceProcessor implements Runnable { private class UpdatedServiceProcessor implements Runnable {
@ -321,16 +330,28 @@ public class ServiceManager implements RecordListener<Service> {
} }
public void easyRemoveService(String namespaceId, String serviceName) throws Exception { public void easyRemoveService(String namespaceId, String serviceName) throws Exception {
Service service = getService(namespaceId, serviceName);
if (service == null) {
throw new IllegalArgumentException("specified service not exist, serviceName : " + serviceName);
}
if (!service.allIPs().isEmpty()) {
throw new IllegalArgumentException("specified service has instances, serviceName : " + serviceName);
}
consistencyService.remove(KeyBuilder.buildServiceMetaKey(namespaceId, serviceName)); consistencyService.remove(KeyBuilder.buildServiceMetaKey(namespaceId, serviceName));
} }
public void addOrReplaceService(Service service) throws Exception { public void addOrReplaceService(Service service) throws NacosException {
consistencyService.put(KeyBuilder.buildServiceMetaKey(service.getNamespaceId(), service.getName()), service); consistencyService.put(KeyBuilder.buildServiceMetaKey(service.getNamespaceId(), service.getName()), service);
} }
public void createEmptyService(String namespaceId, String serviceName) throws NacosException { public void createEmptyService(String namespaceId, String serviceName, boolean local) throws NacosException {
Service service = getService(namespaceId, serviceName); Service service = getService(namespaceId, serviceName);
if (service == null) { if (service == null) {
Loggers.SRV_LOG.info("creating empty service {}:{}", namespaceId, serviceName);
service = new Service(); service = new Service();
service.setName(serviceName); service.setName(serviceName);
service.setNamespaceId(namespaceId); service.setNamespaceId(namespaceId);
@ -339,10 +360,14 @@ public class ServiceManager implements RecordListener<Service> {
service.setLastModifiedMillis(System.currentTimeMillis()); service.setLastModifiedMillis(System.currentTimeMillis());
service.recalculateChecksum(); service.recalculateChecksum();
service.validate(); service.validate();
if (local) {
putService(service); putService(service);
service.init(); service.init();
consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), true), service); consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), true), service);
consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), false), service); consistencyService.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), false), service);
} else {
addOrReplaceService(service);
}
} }
} }
@ -358,9 +383,7 @@ public class ServiceManager implements RecordListener<Service> {
*/ */
public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException { public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {
if (ServerMode.AP.name().equals(switchDomain.getServerMode())) { createEmptyService(namespaceId, serviceName, instance.isEphemeral());
createEmptyService(namespaceId, serviceName);
}
Service service = getService(namespaceId, serviceName); Service service = getService(namespaceId, serviceName);
@ -466,6 +489,7 @@ public class ServiceManager implements RecordListener<Service> {
if (!service.getClusterMap().containsKey(instance.getClusterName())) { if (!service.getClusterMap().containsKey(instance.getClusterName())) {
Cluster cluster = new Cluster(instance.getClusterName()); Cluster cluster = new Cluster(instance.getClusterName());
cluster.setService(service); cluster.setService(service);
cluster.init();
service.getClusterMap().put(instance.getClusterName(), cluster); service.getClusterMap().put(instance.getClusterName(), cluster);
Loggers.SRV_LOG.warn("cluster: {} not found, ip: {}, will create new cluster with default configuration.", Loggers.SRV_LOG.warn("cluster: {} not found, ip: {}, will create new cluster with default configuration.",
instance.getClusterName(), instance.toJSON()); instance.getClusterName(), instance.toJSON());
@ -521,9 +545,13 @@ public class ServiceManager implements RecordListener<Service> {
} }
public void putService(Service service) { public void putService(Service service) {
if (!serviceMap.containsKey(service.getNamespaceId())) {
synchronized (putServiceLock) {
if (!serviceMap.containsKey(service.getNamespaceId())) { if (!serviceMap.containsKey(service.getNamespaceId())) {
serviceMap.put(service.getNamespaceId(), new ConcurrentHashMap<>(16)); serviceMap.put(service.getNamespaceId(), new ConcurrentHashMap<>(16));
} }
}
}
serviceMap.get(service.getNamespaceId()).put(service.getName(), service); serviceMap.get(service.getNamespaceId()).put(service.getName(), service);
} }

View File

@ -27,6 +27,8 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.http.*; import org.apache.http.*;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
@ -41,6 +43,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.*; import java.util.*;
@ -285,6 +288,29 @@ public class HttpClient {
} }
} }
public static void asyncHttpGetLarge(String url, Map<String, String> headers, byte[] content, AsyncCompletionHandler handler) throws Exception {
AsyncHttpClient.BoundRequestBuilder builder = asyncHttpClient.prepareGet(url);
if (!headers.isEmpty()) {
for (String headerKey : headers.keySet()) {
builder.setHeader(headerKey, headers.get(headerKey));
}
}
builder.setBody(content);
builder.setHeader("Content-Type", "application/json; charset=UTF-8");
builder.setHeader("Accept-Charset", "UTF-8");
builder.setHeader("Accept-Encoding", "gzip");
builder.setHeader("Content-Encoding", "gzip");
if (handler != null) {
builder.execute(handler);
} else {
builder.execute();
}
}
public static HttpResult httpPutLarge(String url, Map<String, String> headers, byte[] content) { public static HttpResult httpPutLarge(String url, Map<String, String> headers, byte[] content) {
try { try {
HttpClientBuilder builder = HttpClients.custom(); HttpClientBuilder builder = HttpClients.custom();
@ -313,6 +339,35 @@ public class HttpClient {
} }
} }
public static HttpResult httpGetLarge(String url, Map<String, String> headers, String content) {
try {
HttpClientBuilder builder = HttpClients.custom();
builder.setUserAgent(UtilsAndCommons.SERVER_VERSION);
builder.setConnectionTimeToLive(500, TimeUnit.MILLISECONDS);
CloseableHttpClient httpClient = builder.build();
HttpGetWithEntity httpGetWithEntity = new HttpGetWithEntity();
httpGetWithEntity.setURI(new URI(url));
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpGetWithEntity.setHeader(entry.getKey(), entry.getValue());
}
httpGetWithEntity.setEntity(new StringEntity(content, ContentType.create("application/json", "UTF-8")));
HttpResponse response = httpClient.execute(httpGetWithEntity);
HttpEntity entity = response.getEntity();
HeaderElement[] headerElements = entity.getContentType().getElements();
String charset = headerElements[0].getParameterByName("charset").getValue();
return new HttpResult(response.getStatusLine().getStatusCode(),
IOUtils.toString(entity.getContent(), charset), Collections.<String, String>emptyMap());
} catch (Exception e) {
return new HttpResult(500, e.toString(), Collections.<String, String>emptyMap());
}
}
public static HttpResult httpPostLarge(String url, Map<String, String> headers, String content) { public static HttpResult httpPostLarge(String url, Map<String, String> headers, String content) {
try { try {
HttpClientBuilder builder = HttpClients.custom(); HttpClientBuilder builder = HttpClients.custom();
@ -442,4 +497,14 @@ public class HttpClient {
return respHeaders.get(name); return respHeaders.get(name);
} }
} }
public static class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "GET";
@Override
public String getMethod() {
return METHOD_NAME;
}
}
} }

View File

@ -79,8 +79,8 @@ public class NamingProxy {
Map<String, String> params = new HashMap<>(8); Map<String, String> params = new HashMap<>(8);
params.put("keys", StringUtils.join(keys, ",")); params.put("keys", StringUtils.join(keys, ","));
HttpClient.HttpResult result = HttpClient.httpGet("http://" + server + RunningConfig.getContextPath() HttpClient.HttpResult result = HttpClient.httpGetLarge("http://" + server + RunningConfig.getContextPath()
+ UtilsAndCommons.NACOS_NAMING_CONTEXT + DATA_GET_URL, new ArrayList<>(), params); + UtilsAndCommons.NACOS_NAMING_CONTEXT + DATA_GET_URL, new HashMap<>(8), JSON.toJSONString(params));
if (HttpURLConnection.HTTP_OK == result.code) { if (HttpURLConnection.HTTP_OK == result.code) {
return result.content.getBytes(); return result.content.getBytes();

View File

@ -15,6 +15,7 @@
*/ */
package com.alibaba.nacos.naming.misc; package com.alibaba.nacos.naming.misc;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.naming.boot.RunningConfig; import com.alibaba.nacos.naming.boot.RunningConfig;
import com.ning.http.client.AsyncCompletionHandler; import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.Response; import com.ning.http.client.Response;
@ -49,7 +50,7 @@ public class ServiceStatusSynchronizer implements Synchronizer {
} }
try { try {
HttpClient.asyncHttpPost(url, null, params, new AsyncCompletionHandler() { HttpClient.asyncHttpPostLarge(url, null, JSON.toJSONString(params), new AsyncCompletionHandler() {
@Override @Override
public Integer onCompleted(Response response) throws Exception { public Integer onCompleted(Response response) throws Exception {
if (response.getStatusCode() != HttpURLConnection.HTTP_OK) { if (response.getStatusCode() != HttpURLConnection.HTTP_OK) {

View File

@ -89,7 +89,7 @@ public class SwitchDomain implements Record, Cloneable {
private String overriddenServerStatus = null; private String overriddenServerStatus = null;
private String serverMode = "AP"; private boolean defaultInstanceEphemeral = true;
public boolean isEnableAuthentication() { public boolean isEnableAuthentication() {
return enableAuthentication; return enableAuthentication;
@ -342,12 +342,12 @@ public class SwitchDomain implements Record, Cloneable {
this.overriddenServerStatus = overriddenServerStatus; this.overriddenServerStatus = overriddenServerStatus;
} }
public String getServerMode() { public boolean isDefaultInstanceEphemeral() {
return serverMode; return defaultInstanceEphemeral;
} }
public void setServerMode(String serverMode) { public void setDefaultInstanceEphemeral(boolean defaultInstanceEphemeral) {
this.serverMode = serverMode; this.defaultInstanceEphemeral = defaultInstanceEphemeral;
} }
@Override @Override

View File

@ -59,5 +59,5 @@ public class SwitchEntry {
public static final String PARAM_JSON = "json"; public static final String PARAM_JSON = "json";
public static final String OVERRIDDEN_SERVER_STATUS = "overriddenServerStatus"; public static final String OVERRIDDEN_SERVER_STATUS = "overriddenServerStatus";
public static final String SERVER_MODE = "serverMode"; public static final String DEFAULT_INSTANCE_EPHEMERAL = "defaultInstanceEphemeral";
} }

View File

@ -18,7 +18,6 @@ package com.alibaba.nacos.naming.misc;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException; 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.ConsistencyService;
import com.alibaba.nacos.naming.consistency.Datum; import com.alibaba.nacos.naming.consistency.Datum;
import com.alibaba.nacos.naming.consistency.KeyBuilder; import com.alibaba.nacos.naming.consistency.KeyBuilder;
@ -263,9 +262,9 @@ public class SwitchManager implements RecordListener<SwitchDomain> {
switchDomain.setOverriddenServerStatus(status); switchDomain.setOverriddenServerStatus(status);
} }
if (entry.equals(SwitchEntry.SERVER_MODE)) { if (entry.equals(SwitchEntry.DEFAULT_INSTANCE_EPHEMERAL)) {
String mode = value; String defaultEphemeral = value;
switchDomain.setServerMode(ServerMode.valueOf(mode).name()); switchDomain.setDefaultInstanceEphemeral(Boolean.parseBoolean(defaultEphemeral));
} }
if (debug) { if (debug) {
@ -308,7 +307,7 @@ public class SwitchManager implements RecordListener<SwitchDomain> {
switchDomain.setPushCVersion(newSwitchDomain.getPushCVersion()); switchDomain.setPushCVersion(newSwitchDomain.getPushCVersion());
switchDomain.setEnableAuthentication(newSwitchDomain.isEnableAuthentication()); switchDomain.setEnableAuthentication(newSwitchDomain.isEnableAuthentication());
switchDomain.setOverriddenServerStatus(newSwitchDomain.getOverriddenServerStatus()); switchDomain.setOverriddenServerStatus(newSwitchDomain.getOverriddenServerStatus());
switchDomain.setServerMode(newSwitchDomain.getServerMode()); switchDomain.setDefaultInstanceEphemeral(newSwitchDomain.isDefaultInstanceEphemeral());
} }
public SwitchDomain getSwitchDomain() { public SwitchDomain getSwitchDomain() {

View File

@ -66,6 +66,10 @@ public class DistroFilter implements Filter {
try { try {
String path = new URI(req.getRequestURI()).getPath(); String path = new URI(req.getRequestURI()).getPath();
String serviceName = req.getParameter(CommonParams.SERVICE_NAME); String serviceName = req.getParameter(CommonParams.SERVICE_NAME);
// For client under 0.8.0:
if (StringUtils.isBlank(serviceName)) {
serviceName = req.getParameter("dom");
}
Method method = filterBase.getMethod(req.getMethod(), path); Method method = filterBase.getMethod(req.getMethod(), path);
if (method == null) { if (method == null) {

View File

@ -21,7 +21,7 @@
<inceptionYear>2018</inceptionYear> <inceptionYear>2018</inceptionYear>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Alibaba NACOS ${project.version}</name> <name>Alibaba NACOS ${project.version}</name>

View File

@ -17,7 +17,7 @@
<parent> <parent>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId> <artifactId>nacos-all</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -32,6 +32,8 @@ import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView; import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.config.server.utils.TimeUtils;
import com.alibaba.nacos.config.server.utils.TimeoutUtils;
import com.alibaba.nacos.naming.NamingApp; import com.alibaba.nacos.naming.NamingApp;
import org.junit.After; import org.junit.After;
@ -79,8 +81,6 @@ public class CPInstancesAPI_ITCase {
public void setUp() throws Exception { public void setUp() throws Exception {
String url = String.format("http://localhost:%d/", port); String url = String.format("http://localhost:%d/", port);
this.base = new URL(url); this.base = new URL(url);
NamingBase.prepareServer(port, "UP", "CP");
TimeUnit.SECONDS.sleep(5L);
naming = NamingFactory.createNamingService("127.0.0.1" + ":" + port); naming = NamingFactory.createNamingService("127.0.0.1" + ":" + port);
@ -105,7 +105,7 @@ public class CPInstancesAPI_ITCase {
* @TestStep : * @TestStep :
* @ExpectResult : * @ExpectResult :
*/ */
@Test(expected = IllegalStateException.class) @Test
public void registerInstance_ephemeral_true() throws Exception { public void registerInstance_ephemeral_true() throws Exception {
String serviceName = NamingBase.randomDomainName(); String serviceName = NamingBase.randomDomainName();
namingServiceCreate(serviceName, TEST_NAMESPACE_1, TEST_GROUP_1); namingServiceCreate(serviceName, TEST_NAMESPACE_1, TEST_GROUP_1);
@ -116,6 +116,9 @@ public class CPInstancesAPI_ITCase {
instance.setIp("11.11.11.11"); instance.setIp("11.11.11.11");
instance.setPort(80); instance.setPort(80);
naming1.registerInstance(serviceName, TEST_GROUP_1, instance); naming1.registerInstance(serviceName, TEST_GROUP_1, instance);
TimeUnit.SECONDS.sleep(3L);
naming1.deregisterInstance(serviceName, TEST_GROUP_1, instance);
namingServiceDelete(serviceName, TEST_NAMESPACE_1, TEST_GROUP_1);
} }
/** /**
@ -154,7 +157,8 @@ public class CPInstancesAPI_ITCase {
instance.setIp("11.11.11.11"); instance.setIp("11.11.11.11");
instance.setPort(80); instance.setPort(80);
naming1.registerInstance(serviceName, TEST_GROUP_1, instance); naming1.registerInstance(serviceName, TEST_GROUP_1, instance);
naming1.deregisterInstance(serviceName, TEST_GROUP_1, "11.11.11.11", 80, "c1"); naming1.deregisterInstance(serviceName, TEST_GROUP_1, instance);
TimeUnit.SECONDS.sleep(3L);
namingServiceDelete(serviceName, TEST_NAMESPACE_1, TEST_GROUP_1); namingServiceDelete(serviceName, TEST_NAMESPACE_1, TEST_GROUP_1);
} }

View File

@ -165,10 +165,10 @@ public class NamingBase {
} }
public static void prepareServer(int localPort) { public static void prepareServer(int localPort) {
prepareServer(localPort, "UP", "AP"); prepareServer(localPort, "UP");
} }
public static void prepareServer(int localPort, String status, String mode) { public static void prepareServer(int localPort, String status) {
String url = "http://127.0.0.1:" + localPort + "/nacos/v1/ns/operator/switches?entry=overriddenServerStatus&value=" + status; String url = "http://127.0.0.1:" + localPort + "/nacos/v1/ns/operator/switches?entry=overriddenServerStatus&value=" + status;
List<String> headers = new ArrayList<String>(); List<String> headers = new ArrayList<String>();
headers.add("User-Agent"); headers.add("User-Agent");
@ -177,15 +177,5 @@ public class NamingBase {
HttpClient.request(url, headers, new HashMap<String, String>(), "UTF-8", "PUT"); HttpClient.request(url, headers, new HashMap<String, String>(), "UTF-8", "PUT");
Assert.assertEquals(HttpStatus.SC_OK, result.code); Assert.assertEquals(HttpStatus.SC_OK, result.code);
url = "http://127.0.0.1:" + localPort + "/nacos/v1/ns/operator/switches?entry=serverMode&value=" + mode;
headers = new ArrayList<String>();
headers.add("User-Agent");
headers.add("Nacos-Server");
result =
HttpClient.request(url, headers, new HashMap<String, String>(), "UTF-8", "PUT");
Assert.assertEquals(HttpStatus.SC_OK, result.code);
} }
} }