From a9ca62c7aedf7d027a5dfa9329b86db389eacb97 Mon Sep 17 00:00:00 2001 From: JackSun-Developer Date: Tue, 13 Apr 2021 20:49:07 +0800 Subject: [PATCH] [#5350] In version 1.4.1, modify the Server is Down prompt to the specific reason for the machine failure and send it to the user --- .../naming/cluster/ServerStatusManager.java | 5 +++++ .../consistency/ConsistencyService.java | 9 ++++++++ .../DelegateConsistencyServiceImpl.java | 21 +++++++++++++++++++ .../distro/DistroConsistencyServiceImpl.java | 12 +++++++++++ ...sistentConsistencyServiceDelegateImpl.java | 7 +++++++ .../impl/BasePersistentServiceProcessor.java | 3 +++ .../impl/PersistentServiceProcessor.java | 16 ++++++++++++++ .../StandalonePersistentServiceProcessor.java | 12 +++++++++++ .../raft/RaftConsistencyServiceImpl.java | 14 +++++++++++++ .../nacos/naming/web/TrafficReviseFilter.java | 8 +++++-- 10 files changed, 105 insertions(+), 2 deletions(-) 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 54c78d50447..a5ec113a1f2 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 @@ -24,6 +24,7 @@ import javax.annotation.PostConstruct; import javax.annotation.Resource; +import java.util.Optional; /** * Detect and control the working status of local server. @@ -68,6 +69,10 @@ public ServerStatus getServerStatus() { return serverStatus; } + public Optional getErrorMsg() { + return consistencyService.getErrorMsg(); + } + public class ServerStatusUpdater implements Runnable { @Override diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ConsistencyService.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ConsistencyService.java index 5b3b2ed6e4f..1d610b79d9d 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ConsistencyService.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ConsistencyService.java @@ -19,6 +19,8 @@ import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.naming.pojo.Record; +import java.util.Optional; + /** * Consistence service for all implementations to derive. * @@ -77,6 +79,13 @@ public interface ConsistencyService { */ void unListen(String key, RecordListener listener) throws NacosException; + /** + * Get the error message of the consistency protocol. + * + * @return the consistency protocol error message. + */ + Optional getErrorMsg(); + /** * Tell the status of this consistency service. * diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/DelegateConsistencyServiceImpl.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/DelegateConsistencyServiceImpl.java index d4d5e629416..c6df561ec6a 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/DelegateConsistencyServiceImpl.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/DelegateConsistencyServiceImpl.java @@ -23,6 +23,8 @@ import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Service; +import java.util.Optional; + /** * Consistency delegate. * @@ -81,6 +83,25 @@ public boolean isAvailable() { return ephemeralConsistencyService.isAvailable() && persistentConsistencyService.isAvailable(); } + @Override + public Optional getErrorMsg() { + String errorMsg; + if (ephemeralConsistencyService.getErrorMsg().isPresent() + && persistentConsistencyService.getErrorMsg().isPresent()) { + errorMsg = "'" + ephemeralConsistencyService.getErrorMsg().get() + "' in Distro protocol and '" + + persistentConsistencyService.getErrorMsg().get() + "' in jRaft protocol"; + } else if (ephemeralConsistencyService.getErrorMsg().isPresent() + && !persistentConsistencyService.getErrorMsg().isPresent()) { + errorMsg = ephemeralConsistencyService.getErrorMsg().get(); + } else if (!ephemeralConsistencyService.getErrorMsg().isPresent() + && persistentConsistencyService.getErrorMsg().isPresent()) { + errorMsg = persistentConsistencyService.getErrorMsg().get(); + } else { + errorMsg = null; + } + return Optional.ofNullable(errorMsg); + } + private ConsistencyService mapConsistencyService(String key) { return KeyBuilder.matchEphemeralKey(key) ? ephemeralConsistencyService : persistentConsistencyService; } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/DistroConsistencyServiceImpl.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/DistroConsistencyServiceImpl.java index ccc2bbe69d7..a3f4d6db86f 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/DistroConsistencyServiceImpl.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/ephemeral/distro/DistroConsistencyServiceImpl.java @@ -47,6 +47,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; @@ -350,6 +351,17 @@ public boolean isAvailable() { return isInitialized() || ServerStatus.UP.name().equals(switchDomain.getOverriddenServerStatus()); } + @Override + public Optional getErrorMsg() { + String errorMsg; + if (!isInitialized() && !ServerStatus.UP.name().equals(switchDomain.getOverriddenServerStatus())) { + errorMsg = "Distro protocol is not initialized"; + } else { + errorMsg = null; + } + return Optional.ofNullable(errorMsg); + } + public boolean isInitialized() { return distroProtocol.isInitialized() || !globalConfig.isDataWarmup(); } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/PersistentConsistencyServiceDelegateImpl.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/PersistentConsistencyServiceDelegateImpl.java index 34e07d8fd47..82efbb2c6ea 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/PersistentConsistencyServiceDelegateImpl.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/PersistentConsistencyServiceDelegateImpl.java @@ -28,6 +28,8 @@ import com.alibaba.nacos.sys.env.EnvUtil; import org.springframework.stereotype.Component; +import java.util.Optional; + /** * Persistent consistency service delegate. * @@ -89,6 +91,11 @@ public boolean isAvailable() { return switchOne().isAvailable(); } + @Override + public Optional getErrorMsg() { + return switchOne().getErrorMsg(); + } + private PersistentConsistencyService switchOne() { return switchNewPersistentService ? newPersistentConsistencyService : oldPersistentConsistencyService; } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/BasePersistentServiceProcessor.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/BasePersistentServiceProcessor.java index 5896c3142cd..43f4a31c7ac 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/BasePersistentServiceProcessor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/BasePersistentServiceProcessor.java @@ -92,6 +92,8 @@ enum Op { */ protected volatile boolean hasError = false; + protected volatile String jRaftErrorMsg; + /** * If use old raft, should not notify listener even new listener add. */ @@ -211,6 +213,7 @@ public List loadSnapshotOperate() { public void onError(Throwable error) { super.onError(error); hasError = true; + jRaftErrorMsg = error.getMessage(); } protected Type getDatumTypeFromKey(String key) { diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/PersistentServiceProcessor.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/PersistentServiceProcessor.java index c5835db913a..2b75ada59a1 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/PersistentServiceProcessor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/PersistentServiceProcessor.java @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeUnit; /** @@ -158,4 +159,19 @@ public void unListen(String key, RecordListener listener) throws NacosException public boolean isAvailable() { return hasLeader && !hasError; } + + @Override + public Optional getErrorMsg() { + String errorMsg; + if (hasLeader && hasError) { + errorMsg = "The raft peer is in error: " + jRaftErrorMsg; + } else if (hasLeader && !hasError) { + errorMsg = null; + } else if (!hasLeader && hasError) { + errorMsg = "Could not find leader! And the raft peer is in error: " + jRaftErrorMsg; + } else { + errorMsg = "Could not find leader!"; + } + return Optional.ofNullable(errorMsg); + } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/StandalonePersistentServiceProcessor.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/StandalonePersistentServiceProcessor.java index aa50a966cca..9604954acb5 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/StandalonePersistentServiceProcessor.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/impl/StandalonePersistentServiceProcessor.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.List; +import java.util.Optional; /** * Persistent service manipulation layer in stand-alone mode. @@ -107,4 +108,15 @@ public void unListen(String key, RecordListener listener) throws NacosException public boolean isAvailable() { return !hasError; } + + @Override + public Optional getErrorMsg() { + String errorMsg; + if (hasError) { + errorMsg = "The raft peer is in error: " + jRaftErrorMsg; + } else { + errorMsg = null; + } + return Optional.ofNullable(errorMsg); + } } diff --git a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftConsistencyServiceImpl.java b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftConsistencyServiceImpl.java index da7277b84c6..882348b764c 100644 --- a/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftConsistencyServiceImpl.java +++ b/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftConsistencyServiceImpl.java @@ -33,6 +33,7 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; +import java.util.Optional; /** * Use simplified Raft protocol to maintain the consistency status of Nacos cluster. @@ -54,6 +55,8 @@ public class RaftConsistencyServiceImpl implements PersistentConsistencyService private volatile boolean stopWork = false; + private String errorMsg; + public RaftConsistencyServiceImpl(ClusterVersionJudgement versionJudgement, RaftCore raftCore, SwitchDomain switchDomain) { this.raftCore = raftCore; @@ -127,6 +130,17 @@ public boolean isAvailable() { return raftCore.isInitialized() || ServerStatus.UP.name().equals(switchDomain.getOverriddenServerStatus()); } + @Override + public Optional getErrorMsg() { + String errorMsg; + if (!raftCore.isInitialized() && !ServerStatus.UP.name().equals(switchDomain.getOverriddenServerStatus())) { + errorMsg = "The old raft protocol node is not initialized"; + } else { + errorMsg = null; + } + return Optional.ofNullable(errorMsg); + } + /** * Put a new datum from other server. * 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 e738b7e7477..058f56fae1c 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 @@ -97,8 +97,12 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha return; } - resp.getWriter() - .write("server is " + serverStatusManager.getServerStatus().name() + " now, please try again later!"); + final String statusMsg = "server is " + serverStatusManager.getServerStatus().name() + "now"; + if (serverStatusManager.getErrorMsg().isPresent()) { + resp.getWriter().write(statusMsg + ", detailed error message: " + serverStatusManager.getErrorMsg()); + } else { + resp.getWriter().write(statusMsg + ", please try again later!"); + } resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE); } }