From dc2b28f6fa8c35b4938259c7f7ba080a701e5a15 Mon Sep 17 00:00:00 2001 From: hongqiaowei Date: Thu, 9 Jun 2022 18:37:27 +0800 Subject: [PATCH] Fallback and go on when nacos server down --- .../src/main/resources/application.yml | 2 + .../main/java/we/util/PropertiesUtils.java | 22 ++++++- .../main/java/we/util/ReflectionUtils.java | 7 ++ .../src/main/java/we/config/SystemConfig.java | 7 ++ .../DedicatedLineInfoService.java | 20 ++++-- .../dedicated_line/DedicatedLineService.java | 20 ++++-- .../DedicatedLineServiceRegistration.java | 21 ++++-- .../DedicatedLineWebServer.java | 37 ++++++----- .../RegistryCenterService.java | 28 ++++++-- .../eureka/FizzEurekaHelper.java | 22 ++++++- .../nacos/FizzNacosHelper.java | 21 +++++- .../nacos/FizzNacosServiceRegistration.java | 66 +++++++++++++++++++ 12 files changed, 229 insertions(+), 44 deletions(-) diff --git a/fizz-bootstrap/src/main/resources/application.yml b/fizz-bootstrap/src/main/resources/application.yml index 2474eba..7ca2e1a 100644 --- a/fizz-bootstrap/src/main/resources/application.yml +++ b/fizz-bootstrap/src/main/resources/application.yml @@ -116,6 +116,8 @@ fizz: code-field: "msgCode" message-field: "message" + fast-fail-when-registry-center-down: false + # dedicated-line: # server: # enable: true diff --git a/fizz-common/src/main/java/we/util/PropertiesUtils.java b/fizz-common/src/main/java/we/util/PropertiesUtils.java index db7c46b..4260b77 100644 --- a/fizz-common/src/main/java/we/util/PropertiesUtils.java +++ b/fizz-common/src/main/java/we/util/PropertiesUtils.java @@ -63,7 +63,7 @@ public abstract class PropertiesUtils { public static void setBeanPropertyValue(Object bean, Properties properties, Map> propertyTypeHint) { BeanWrapperImpl beanWrapper = new BeanWrapperImpl(bean); - for (String propertyName : properties.stringPropertyNames()) { + /*for (String propertyName : properties.stringPropertyNames()) { if (beanWrapper.isWritableProperty(propertyName)) { beanWrapper.setPropertyValue(propertyName, properties.get(propertyName)); } else if (propertyTypeHint != null) { @@ -77,6 +77,24 @@ public abstract class PropertiesUtils { } } } - } + }*/ + properties.forEach( + (n, v) -> { + String propertyName = (String) n; + if (beanWrapper.isWritableProperty(propertyName)) { + beanWrapper.setPropertyValue(propertyName, properties.get(propertyName)); + } else if (propertyTypeHint != null) { + int dotPos = propertyName.lastIndexOf(Consts.S.DOT); + if (dotPos > -1) { + String prefix = propertyName.substring(0, dotPos); + Class aClass = propertyTypeHint.get(prefix); + if (aClass != null && Map.class.isAssignableFrom(aClass)) { + String newPropertyName = prefix + PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR + propertyName.substring(dotPos + 1) + PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR; + beanWrapper.setPropertyValue(newPropertyName, properties.get(propertyName)); + } + } + } + } + ); } } diff --git a/fizz-common/src/main/java/we/util/ReflectionUtils.java b/fizz-common/src/main/java/we/util/ReflectionUtils.java index 3c95b8a..8e3b86d 100644 --- a/fizz-common/src/main/java/we/util/ReflectionUtils.java +++ b/fizz-common/src/main/java/we/util/ReflectionUtils.java @@ -18,6 +18,7 @@ package we.util; import java.lang.reflect.Field; +import java.lang.reflect.Method; /** * @author hongqiaowei @@ -39,4 +40,10 @@ public abstract class ReflectionUtils extends org.springframework.util.Reflectio makeAccessible(f); return getField(f, target); } + + public static Object invokeMethod(String method, Object target, Object... args) { + Method m = findMethod(target.getClass(), method); + makeAccessible(m); + return invokeMethod(m, target, args); + } } diff --git a/fizz-core/src/main/java/we/config/SystemConfig.java b/fizz-core/src/main/java/we/config/SystemConfig.java index 649542b..7965139 100644 --- a/fizz-core/src/main/java/we/config/SystemConfig.java +++ b/fizz-core/src/main/java/we/config/SystemConfig.java @@ -122,6 +122,13 @@ public class SystemConfig { private String fizzDedicatedLineClientId; + @Value("${fizz.fast-fail-when-registry-center-down:false}") + private boolean fastFailWhenRegistryCenterDown; + + public boolean isFastFailWhenRegistryCenterDown() { + return fastFailWhenRegistryCenterDown; + } + public int fizzDedicatedLineClientRequestTimeout() { return fizzDedicatedLineClientRequestTimeout; } diff --git a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineInfoService.java b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineInfoService.java index c0e1f51..b3822d1 100644 --- a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineInfoService.java +++ b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineInfoService.java @@ -19,6 +19,7 @@ package we.dedicated_line; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.redis.core.ReactiveStringRedisTemplate; import org.springframework.stereotype.Service; @@ -50,15 +51,20 @@ public class DedicatedLineInfoService { @Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE) private ReactiveStringRedisTemplate rt; + @Value("${fizz.dedicated-line.client.enable:true}") + private boolean fizzDedicatedLineClientEnable; + @PostConstruct public void init() throws Throwable { - Result result = initDedicatedLineInfo(); - if (result.code == Result.FAIL) { - throw new RuntimeException(result.msg, result.t); - } - result = lsnApiPairingInfoChange(); - if (result.code == Result.FAIL) { - throw new RuntimeException(result.msg, result.t); + if (fizzDedicatedLineClientEnable) { + Result result = initDedicatedLineInfo(); + if (result.code == Result.FAIL) { + throw new RuntimeException(result.msg, result.t); + } + result = lsnApiPairingInfoChange(); + if (result.code == Result.FAIL) { + throw new RuntimeException(result.msg, result.t); + } } } diff --git a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineService.java b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineService.java index d04ee83..a88728b 100644 --- a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineService.java +++ b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineService.java @@ -19,6 +19,7 @@ package we.dedicated_line; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.redis.core.ReactiveStringRedisTemplate; import org.springframework.http.HttpMethod; @@ -54,15 +55,20 @@ public class DedicatedLineService { @Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE) private ReactiveStringRedisTemplate rt; + @Value("${fizz.dedicated-line.server.enable:true}") + private boolean fizzDedicatedLineServerEnable; + @PostConstruct public void init() throws Throwable { - Result result = initDedicatedLine(); - if (result.code == Result.FAIL) { - throw new RuntimeException(result.msg, result.t); - } - result = lsnDedicatedLineChange(); - if (result.code == Result.FAIL) { - throw new RuntimeException(result.msg, result.t); + if (fizzDedicatedLineServerEnable) { + Result result = initDedicatedLine(); + if (result.code == Result.FAIL) { + throw new RuntimeException(result.msg, result.t); + } + result = lsnDedicatedLineChange(); + if (result.code == Result.FAIL) { + throw new RuntimeException(result.msg, result.t); + } } } diff --git a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java index 4869c0a..19e4283 100644 --- a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java +++ b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineServiceRegistration.java @@ -21,6 +21,7 @@ import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration; import lombok.SneakyThrows; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.env.OriginTrackedMapPropertySource; @@ -30,6 +31,7 @@ import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import we.config.SystemConfig; import we.service_registry.FizzServiceRegistration; @@ -53,15 +55,22 @@ public class DedicatedLineServiceRegistration implements ApplicationListener propertySource : env.getPropertySources()) { - if (propertySource instanceof OriginTrackedMapPropertySource) { - OriginTrackedMapPropertySource originTrackedMapPropertySource = (OriginTrackedMapPropertySource) propertySource; + // if (propertySource instanceof OriginTrackedMapPropertySource) { + if (MapPropertySource.class.isAssignableFrom(propertySource.getClass())) { + MapPropertySource originTrackedMapPropertySource = (MapPropertySource) propertySource; String[] propertyNames = originTrackedMapPropertySource.getPropertyNames(); for (String propertyName : propertyNames) { if (propertyName.length() > 55) { @@ -97,8 +107,9 @@ public class DedicatedLineServiceRegistration implements ApplicationListener propertySource : env.getPropertySources()) { - if (propertySource instanceof OriginTrackedMapPropertySource) { - OriginTrackedMapPropertySource originTrackedMapPropertySource = (OriginTrackedMapPropertySource) propertySource; + // if (propertySource instanceof OriginTrackedMapPropertySource) { + if (MapPropertySource.class.isAssignableFrom(propertySource.getClass())) { + MapPropertySource originTrackedMapPropertySource = (MapPropertySource) propertySource; String[] propertyNames = originTrackedMapPropertySource.getPropertyNames(); for (String propertyName : propertyNames) { if (propertyName.length() > 64) { diff --git a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineWebServer.java b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineWebServer.java index f99601d..6698a53 100644 --- a/fizz-core/src/main/java/we/dedicated_line/DedicatedLineWebServer.java +++ b/fizz-core/src/main/java/we/dedicated_line/DedicatedLineWebServer.java @@ -58,26 +58,33 @@ public class DedicatedLineWebServer { @Value("${fizz.dedicated-line.client.port:8601}") private int port = 8601; + @Value("${fizz.dedicated-line.client.enable:true}") + private boolean fizzDedicatedLineClientEnable; + @PostConstruct public void start() { - HttpWebHandlerAdapter adapter = (HttpWebHandlerAdapter) httpHandler; - NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory(port); - server = factory.getWebServer( - new DedicatedLineHttpHandler( - applicationContext, - new DefaultWebSessionManager(), - adapter.getCodecConfigurer(), - adapter.getLocaleContextResolver(), - adapter.getForwardedHeaderTransformer() - ) - ); - server.start(); - log.info("fizz dedicated line web server listen on {}", port); - applicationContext.publishEvent(new DedicatedLineWebServerInitializedEvent(server, applicationContext)); + if (fizzDedicatedLineClientEnable) { + HttpWebHandlerAdapter adapter = (HttpWebHandlerAdapter) httpHandler; + NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory(port); + server = factory.getWebServer( + new DedicatedLineHttpHandler( + applicationContext, + new DefaultWebSessionManager(), + adapter.getCodecConfigurer(), + adapter.getLocaleContextResolver(), + adapter.getForwardedHeaderTransformer() + ) + ); + server.start(); + log.info("fizz dedicated line web server listen on {}", port); + applicationContext.publishEvent(new DedicatedLineWebServerInitializedEvent(server, applicationContext)); + } } @PreDestroy public void stop() { - server.stop(); + if (server != null) { + server.stop(); + } } } diff --git a/fizz-core/src/main/java/we/service_registry/RegistryCenterService.java b/fizz-core/src/main/java/we/service_registry/RegistryCenterService.java index bceff00..670eb3a 100644 --- a/fizz-core/src/main/java/we/service_registry/RegistryCenterService.java +++ b/fizz-core/src/main/java/we/service_registry/RegistryCenterService.java @@ -27,6 +27,7 @@ import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import we.config.AggregateRedisConfig; +import we.config.SystemConfig; import we.util.Consts; import we.util.JacksonUtils; import we.util.Result; @@ -42,7 +43,7 @@ import java.util.Map; */ @Service -public class RegistryCenterService implements ApplicationListener { +public class RegistryCenterService implements ApplicationListener { private static final Logger LOGGER = LoggerFactory.getLogger(RegistryCenterService.class); @@ -54,6 +55,9 @@ public class RegistryCenterService implements ApplicationListener result = initRegistryCenter(); @@ -80,9 +84,19 @@ public class RegistryCenterService implements ApplicationListener { + String propertyName = (String) n; + String pn = null; + if (propertyName.charAt(ecl - 1) == Consts.S.DOT) { + pn = propertyName.substring(ecl); + } else if (propertyName.charAt(eil - 1) == Consts.S.DOT) { + pn = propertyName.substring(eil); + } else { + pn = propertyName.substring(el); + } + if (pn.indexOf(Consts.S.DASH) > -1) { + pn = PropertiesUtils.normalize(pn); + } + eurekaProps.put(pn, v); + } + ); InetUtils inetUtils = null; try { diff --git a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java index 1d93e0f..8f70636 100644 --- a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java +++ b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosHelper.java @@ -46,7 +46,7 @@ public abstract class FizzNacosHelper { public static FizzNacosServiceRegistration getServiceRegistration(ApplicationContext applicationContext, Properties nacosProperties) { Properties ps = new Properties(); - for (String propertyName : nacosProperties.stringPropertyNames()) { + /*for (String propertyName : nacosProperties.stringPropertyNames()) { String propertyValue = nacosProperties.getProperty(propertyName); if (propertyName.endsWith(PropertyKeyConst.USERNAME)) { ps.setProperty(PropertyKeyConst.USERNAME, propertyValue); @@ -59,7 +59,24 @@ public abstract class FizzNacosHelper { } ps.setProperty(pn, propertyValue); } - } + }*/ + + nacosProperties.forEach( + (n, propertyValue) -> { + String propertyName = (String) n; + if (propertyName.endsWith(PropertyKeyConst.USERNAME)) { + ps.put(PropertyKeyConst.USERNAME, propertyValue); + } else if (propertyName.endsWith(PropertyKeyConst.PASSWORD)) { + ps.put(PropertyKeyConst.PASSWORD, propertyValue); + } else { + String pn = propertyName.substring(ndl); + if (pn.indexOf(Consts.S.DASH) > -1) { + pn = PropertiesUtils.normalize(pn); + } + ps.put(pn, propertyValue); + } + } + ); FizzNacosProperties fizzNacosProperties = new FizzNacosProperties(ps); PropertiesUtils.setBeanPropertyValue(fizzNacosProperties, ps); diff --git a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java index 59c3e9e..1cd5e25 100644 --- a/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java +++ b/fizz-core/src/main/java/we/service_registry/nacos/FizzNacosServiceRegistration.java @@ -24,13 +24,29 @@ import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.pojo.Instance; import com.alibaba.nacos.api.naming.pojo.ListView; +import com.alibaba.nacos.client.naming.cache.ServiceInfoHolder; +import com.alibaba.nacos.client.naming.core.ServerListManager; +import com.alibaba.nacos.client.naming.core.ServiceInfoUpdateService; +import com.alibaba.nacos.client.naming.remote.NamingClientProxyDelegate; +import com.alibaba.nacos.client.naming.remote.gprc.NamingGrpcClientProxy; +import com.alibaba.nacos.client.naming.remote.gprc.redo.NamingGrpcRedoService; +import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientProxy; +import com.alibaba.nacos.common.remote.client.Connection; +import com.alibaba.nacos.common.remote.client.RpcClientStatus; +import com.alibaba.nacos.common.remote.client.grpc.GrpcClient; +import com.alibaba.nacos.common.utils.ThreadUtils; import org.springframework.util.StringUtils; import we.service_registry.FizzServiceRegistration; import we.util.Consts; +import we.util.ReflectionUtils; import we.util.Utils; import java.util.Collections; import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicReference; + +import static com.alibaba.nacos.client.utils.LogUtils.NAMING_LOGGER; /** * @author hongqiaowei @@ -67,8 +83,58 @@ public class FizzNacosServiceRegistration extends FizzServiceRegistration { return namingService; } + @Override + public void close() { + ServiceInfoHolder serviceInfoHolder = (ServiceInfoHolder) ReflectionUtils.get(namingService, "serviceInfoHolder"); + NamingClientProxyDelegate namingClientProxyDelegate = (NamingClientProxyDelegate) ReflectionUtils.get(namingService, "clientProxy"); + try { + serviceInfoHolder.shutdown(); + ServiceInfoUpdateService serviceInfoUpdateService = (ServiceInfoUpdateService) ReflectionUtils.get(namingClientProxyDelegate, "serviceInfoUpdateService"); + serviceInfoUpdateService.shutdown(); + ServerListManager serverListManager = (ServerListManager) ReflectionUtils.get(namingClientProxyDelegate, "serverListManager"); + serverListManager.shutdown(); + NamingHttpClientProxy namingHttpClientProxy = (NamingHttpClientProxy) ReflectionUtils.get(namingClientProxyDelegate, "httpClientProxy"); + namingHttpClientProxy.shutdown(); + NamingGrpcClientProxy namingGrpcClientProxy = (NamingGrpcClientProxy) ReflectionUtils.get(namingClientProxyDelegate, "grpcClientProxy"); + + GrpcClient grpcClient = (GrpcClient) ReflectionUtils.get(namingGrpcClientProxy, "rpcClient"); + + AtomicReference rpcClientStatus = (AtomicReference) ReflectionUtils.get(grpcClient, "rpcClientStatus"); + rpcClientStatus.set(RpcClientStatus.SHUTDOWN); + LOGGER.info("shutdown {} grpc client ,set status to shutdown", getId()); + + ScheduledExecutorService clientEventExecutor = (ScheduledExecutorService) ReflectionUtils.get(grpcClient, "clientEventExecutor"); + clientEventExecutor.shutdownNow(); + LOGGER.info("shutdown {} client event executor {}", getId(), clientEventExecutor); + + Connection currentConnection = (Connection) ReflectionUtils.get(grpcClient, "currentConnection"); + if (currentConnection != null) { + ReflectionUtils.invokeMethod("closeConnection", grpcClient, currentConnection); + LOGGER.info("close {} current connection {}", getId(), currentConnection.getConnectionId()); + } + + NamingGrpcRedoService namingGrpcRedoService = (NamingGrpcRedoService) ReflectionUtils.get(namingGrpcClientProxy, "redoService"); + namingGrpcRedoService.shutdown(); + + ScheduledExecutorService scheduledExecutorService = (ScheduledExecutorService) ReflectionUtils.get(namingClientProxyDelegate, "executorService"); + ThreadUtils.shutdownThreadPool(scheduledExecutorService, NAMING_LOGGER); + + LOGGER.info("nacos {} client resource is closed", getId()); + + } catch (Exception e) { + LOGGER.error("nacos {} naming service shutdown exception", getId(), e); + throw new RuntimeException(e); + } + } + @Override protected void shutdownClient() { + /*try { + namingService.shutDown(); + } catch (NacosException e) { + LOGGER.error("nacos {} naming service shutdown exception", getId(), e); + throw new RuntimeException(e); + }*/ } @Override