Multi service registry center
This commit is contained in:
@@ -4,7 +4,7 @@ English | [简体中文](./README.md)
|
||||
<a href="https://www.fizzgate.com"><img src="https://raw.githubusercontent.com/wiki/wehotel/fizz-gateway-community/img/icon-color.png" width="70%"></a>
|
||||
</p>
|
||||
<p>
|
||||
<img alt="Version" src="https://img.shields.io/badge/version-2.4.0-blue.svg?cacheSeconds=2592000" />
|
||||
<img alt="Version" src="https://img.shields.io/badge/version-2.4.1-blue.svg?cacheSeconds=2592000" />
|
||||
<a href="http://www.fizzgate.com/fizz-gateway-community/" target="_blank">
|
||||
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
|
||||
</a>
|
||||
@@ -111,6 +111,7 @@ Starting from v1.3.0, the frontend and backend of the management backend are mer
|
||||
| v2.3.2 | v2.3.2 |
|
||||
| v2.3.3 | v2.3.3 |
|
||||
| v2.4.0 | v2.4.0 |
|
||||
| v2.4.1 | v2.4.1 |
|
||||
|
||||
|
||||
Please download the corresponding management backend version according to the version of the community version
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<a href="https://www.fizzgate.com"><img src="https://raw.githubusercontent.com/wiki/wehotel/fizz-gateway-community/img/icon-color.png" width="70%"></a>
|
||||
</p>
|
||||
<p>
|
||||
<img alt="Version" src="https://img.shields.io/badge/version-2.4.0-blue.svg?cacheSeconds=2592000" />
|
||||
<img alt="Version" src="https://img.shields.io/badge/version-2.4.1-blue.svg?cacheSeconds=2592000" />
|
||||
<a href="http://www.fizzgate.com/fizz-gateway-community/" target="_blank">
|
||||
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
|
||||
</a>
|
||||
@@ -113,6 +113,7 @@ API地址:http://demo.fizzgate.com/proxy/[服务名]/[API_Path]
|
||||
| v2.3.2 | v2.3.2 |
|
||||
| v2.3.3 | v2.3.3 |
|
||||
| v2.4.0 | v2.4.0 |
|
||||
| v2.4.1 | v2.4.1 |
|
||||
|
||||
|
||||
请根据社区版的版本下载对应的管理后台版本
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring-framework.version>5.2.18.RELEASE</spring-framework.version>
|
||||
<spring-framework.version>5.2.19.RELEASE</spring-framework.version>
|
||||
<spring-session-bom.version>Dragonfruit-SR3</spring-session-bom.version>
|
||||
<reactor-bom.version>Dysprosium-SR25</reactor-bom.version>
|
||||
<lettuce.version>5.3.7.RELEASE</lettuce.version>
|
||||
<netty.version>4.1.70.Final</netty.version>
|
||||
<httpcore.version>4.4.14</httpcore.version>
|
||||
<log4j2.version>2.14.1</log4j2.version>
|
||||
<netty.version>4.1.72.Final</netty.version>
|
||||
<httpcore.version>4.4.15</httpcore.version>
|
||||
<log4j2.version>2.17.0</log4j2.version>
|
||||
<slf4j.version>1.7.32</slf4j.version>
|
||||
<commons-lang3.version>3.12.0</commons-lang3.version>
|
||||
<lombok.version>1.18.22</lombok.version>
|
||||
@@ -37,6 +37,7 @@
|
||||
<netty-tcnative.version>2.0.46.Final</netty-tcnative.version>
|
||||
<spring-cloud.version>2.2.9.RELEASE</spring-cloud.version>
|
||||
<resilience4j.version>1.7.1</resilience4j.version>
|
||||
<snakeyaml.version>1.30</snakeyaml.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -99,6 +100,12 @@
|
||||
<artifactId>resilience4j-reactor</artifactId>
|
||||
<version>${resilience4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-classes</artifactId>
|
||||
<version>${netty-tcnative.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
|
||||
@@ -187,6 +187,7 @@ public class FizzBootstrapApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("log4j2.contextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
|
||||
System.setProperty("log4j2.formatMsgNoLookups", "true");
|
||||
|
||||
SpringApplication springApplication = new SpringApplication(FizzBootstrapApplication.class);
|
||||
springApplication.setApplicationContextClass(CustomReactiveWebServerApplicationContext.class);
|
||||
|
||||
@@ -20,7 +20,7 @@ eureka:
|
||||
enabled: false #use Eureka? (default:false)
|
||||
serviceUrl:
|
||||
# need replace
|
||||
defaultZone: http://localhost:6600/eureka/ #please input the eureka client serviceUrl defaultZone (default:http://localhost:6600/eureka/)
|
||||
defaultZone: http://6.6.6.6:6600/eureka/ #please input the eureka client serviceUrl defaultZone (default:http://localhost:6600/eureka/)
|
||||
instance:
|
||||
prefer-ip-address: true
|
||||
################################################### Eureka config end ###################################################
|
||||
@@ -52,7 +52,7 @@ spring:
|
||||
aggregate:
|
||||
redis:
|
||||
# need replace
|
||||
host: 6.6.6.6 #please input the redis host (default:localhost)
|
||||
host: 1.1.1.1 #please input the redis host (default:localhost)
|
||||
# need replace
|
||||
port: 6379 #please input the redis port (default:6379)
|
||||
# need replace
|
||||
@@ -127,15 +127,22 @@ fizz:
|
||||
retry-count: 0 # default no retry
|
||||
retry-interval: 0 # default no retry interval
|
||||
crypto: true # if true, client will encrypt request body and decrypt response body
|
||||
# service-registration:
|
||||
# type: eureka # service registration type, can be eureka or nacos
|
||||
# application: ax # register the name of this application to server
|
||||
# port: 8601 # the port to be registered
|
||||
# service-url: http://6.6.6.6:6600/eureka/ # server address
|
||||
# type: nacos
|
||||
# application: ax
|
||||
service-registration:
|
||||
# eureka:
|
||||
# server-port: 8601
|
||||
# client:
|
||||
# enabled: true
|
||||
# serviceUrl:
|
||||
# defaultZone: http://3.3.3.3:6600/eureka
|
||||
# instance:
|
||||
# appname: fizz-dedicated-line
|
||||
# prefer-ip-address: true
|
||||
# nacos:
|
||||
# discovery:
|
||||
# enabled: true
|
||||
# service: fizz-dedicated-line
|
||||
# port: 8601
|
||||
# service-url: 6.6.6.6:8848
|
||||
# server-addr: 2.2.2.2:8848
|
||||
|
||||
fizz-trace-id:
|
||||
header: X-Trace-Id
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<!--<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level [%-29t] %30c{1}.%41M:%4L %m %ex%n"/>-->
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %30c{1}.%41M:%4L %m %ex%n"/>
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %30c{1}.%41M:%4L %m{nolookups} %ex%n"/>
|
||||
</Console>
|
||||
<LogSend name="LogSend">
|
||||
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %level %logger{36} - %msg%n"/>
|
||||
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %level %logger{36} - %msg{nolookups}%n"/>
|
||||
</LogSend>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
||||
@@ -27,6 +27,7 @@ public final class Consts {
|
||||
}
|
||||
|
||||
public static final class S {
|
||||
public static final String DEFAULT = "default";
|
||||
public static final String TRUE = "true";
|
||||
public static final String FALSE = "false";
|
||||
public static final String TRUE1 = "1";
|
||||
|
||||
34
fizz-common/src/main/java/we/util/FileUtils.java
Normal file
34
fizz-common/src/main/java/we/util/FileUtils.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package we.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public abstract class FileUtils {
|
||||
|
||||
private FileUtils() {
|
||||
}
|
||||
|
||||
public static String getAppRootDir() {
|
||||
return new File(Consts.S.EMPTY).getAbsolutePath();
|
||||
}
|
||||
|
||||
public static String getAbsoluteDir(Class<?> cls) {
|
||||
return new File(Objects.requireNonNull(cls.getResource(Consts.S.EMPTY)).getPath()).getAbsolutePath();
|
||||
}
|
||||
|
||||
public static String getAbsolutePath(Class<?> cls) {
|
||||
String absoluteDir = getAbsoluteDir(cls);
|
||||
return absoluteDir + File.separatorChar + cls.getSimpleName() + ".class";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file relative to src or resource dir, eg: we/util/FileUtils.class and application.yml
|
||||
*/
|
||||
public static String getAbsolutePath(String file) {
|
||||
return new File(Objects.requireNonNull(FileUtils.class.getClassLoader().getResource(file)).getPath()).getAbsolutePath();
|
||||
}
|
||||
}
|
||||
70
fizz-common/src/main/java/we/util/PropertiesUtils.java
Normal file
70
fizz-common/src/main/java/we/util/PropertiesUtils.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package we.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
import org.springframework.beans.PropertyAccessor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public abstract class PropertiesUtils {
|
||||
|
||||
private PropertiesUtils() {
|
||||
}
|
||||
|
||||
public static String normalize(String propertyName) {
|
||||
char[] chars = propertyName.toCharArray();
|
||||
StringBuilder b = new StringBuilder(chars.length);
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
char c = chars[i];
|
||||
if (c == Consts.S.DASH) {
|
||||
b.append(Character.toUpperCase(chars[++i]));
|
||||
} else {
|
||||
b.append(c);
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static Properties remove(Properties properties, String prefix) {
|
||||
Properties result = new Properties();
|
||||
properties.forEach(
|
||||
(k, v) -> {
|
||||
String s = k.toString();
|
||||
int idx = s.indexOf(prefix);
|
||||
if (idx > -1) {
|
||||
s = s.substring(prefix.length() + 1);
|
||||
}
|
||||
result.setProperty(s, v.toString());
|
||||
}
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void setBeanPropertyValue(Object bean, Properties properties) {
|
||||
setBeanPropertyValue(bean, properties, null);
|
||||
}
|
||||
|
||||
public static void setBeanPropertyValue(Object bean, Properties properties, Map<String, Class<?>> propertyTypeHint) {
|
||||
BeanWrapperImpl beanWrapper = new BeanWrapperImpl(bean);
|
||||
for (String propertyName : properties.stringPropertyNames()) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
fizz-common/src/main/java/we/util/YmlUtils.java
Normal file
34
fizz-common/src/main/java/we/util/YmlUtils.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package we.util;
|
||||
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public abstract class YmlUtils {
|
||||
|
||||
private YmlUtils() {
|
||||
}
|
||||
|
||||
public static Properties file2properties(String file) {
|
||||
Resource resource = new ClassPathResource(file);
|
||||
return getProperties(resource);
|
||||
}
|
||||
|
||||
public static Properties string2properties(String config) {
|
||||
Resource resource = new ByteArrayResource(config.getBytes());
|
||||
return getProperties(resource);
|
||||
}
|
||||
|
||||
private static Properties getProperties(Resource resource) {
|
||||
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
|
||||
yamlPropertiesFactoryBean.setResources(resource);
|
||||
return yamlPropertiesFactoryBean.getObject();
|
||||
}
|
||||
}
|
||||
@@ -329,6 +329,10 @@
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-classes</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
|
||||
@@ -19,27 +19,25 @@ package we.dedicated_line;
|
||||
|
||||
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.env.OriginTrackedMapPropertySource;
|
||||
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
|
||||
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
|
||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
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.PropertySource;
|
||||
import we.config.SystemConfig;
|
||||
import we.service_registry.FizzServiceRegistration;
|
||||
import we.service_registry.eureka.FizzEurekaHelper;
|
||||
import we.service_registry.eureka.FizzEurekaProperties;
|
||||
import we.service_registry.eureka.FizzEurekaServiceRegistration;
|
||||
import we.service_registry.nacos.FizzNacosHelper;
|
||||
import we.service_registry.nacos.FizzNacosProperties;
|
||||
import we.service_registry.nacos.FizzNacosServiceRegistration;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
@@ -51,9 +49,9 @@ import javax.annotation.PreDestroy;
|
||||
@AutoConfigureAfter({EurekaClientAutoConfiguration.class, NacosDiscoveryAutoConfiguration.class})
|
||||
public class DedicatedLineServiceRegistration implements ApplicationListener<DedicatedLineWebServerInitializedEvent> {
|
||||
|
||||
private ServiceRegistry serviceRegistry;
|
||||
private static final Logger log = LoggerFactory.getLogger(DedicatedLineServiceRegistration.class);
|
||||
|
||||
private Registration registration;
|
||||
private FizzServiceRegistration fizzServiceRegistration;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
@@ -63,69 +61,74 @@ public class DedicatedLineServiceRegistration implements ApplicationListener<Ded
|
||||
ConfigurableEnvironment env = applicationContext.getEnvironment();
|
||||
|
||||
String prefix = SystemConfig.FIZZ_DEDICATED_LINE_CLIENT_PREFIX + ".service-registration";
|
||||
String type = env.getProperty(prefix + ".type");
|
||||
boolean eureka = env.containsProperty((prefix + ".eureka.instance.appname"));
|
||||
boolean nacos = env.containsProperty((prefix + ".nacos.discovery.server-addr"));
|
||||
|
||||
if (StringUtils.isNotBlank(type)) {
|
||||
if ("eureka".equals(type)) {
|
||||
String application = env.getProperty(prefix + ".application");
|
||||
String ipAddress = env.getProperty(prefix + ".ip-address");
|
||||
String port = env.getProperty(prefix + ".port");
|
||||
String preferIpAddress = env.getProperty(prefix + ".prefer-ip-address", "true");
|
||||
String serviceUrl = env.getProperty(prefix + ".service-url");
|
||||
|
||||
FizzEurekaProperties fizzEurekaProperties = new FizzEurekaProperties().applicationContext(applicationContext)
|
||||
.appName(application)
|
||||
.ipAddress(ipAddress)
|
||||
.nonSecurePort(Integer.parseInt(port))
|
||||
.preferIpAddress(Boolean.parseBoolean(preferIpAddress))
|
||||
.serviceUrl(serviceUrl);
|
||||
FizzEurekaServiceRegistration fizzEurekaServiceRegistration = FizzEurekaHelper.getServiceRegistration(fizzEurekaProperties);
|
||||
|
||||
serviceRegistry = fizzEurekaServiceRegistration.serviceRegistry;
|
||||
registration = fizzEurekaServiceRegistration.registration;
|
||||
if (eureka || nacos) {
|
||||
if (eureka) {
|
||||
Properties eurekaProperties = new Properties();
|
||||
boolean find = false;
|
||||
for (PropertySource<?> propertySource : env.getPropertySources()) {
|
||||
if (propertySource instanceof OriginTrackedMapPropertySource) {
|
||||
OriginTrackedMapPropertySource originTrackedMapPropertySource = (OriginTrackedMapPropertySource) propertySource;
|
||||
String[] propertyNames = originTrackedMapPropertySource.getPropertyNames();
|
||||
for (String propertyName : propertyNames) {
|
||||
if (propertyName.length() > 55) {
|
||||
int eurekaPos = propertyName.indexOf("eureka");
|
||||
if (eurekaPos > -1) {
|
||||
eurekaProperties.setProperty(propertyName.substring(eurekaPos), originTrackedMapPropertySource.getProperty(propertyName).toString());
|
||||
find = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (find) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
log.error("no eureka config");
|
||||
return;
|
||||
}
|
||||
fizzServiceRegistration = FizzEurekaHelper.getServiceRegistration(applicationContext, eurekaProperties);
|
||||
}
|
||||
|
||||
if ("nacos".equals(type)) {
|
||||
String application = env.getProperty(prefix + ".application");
|
||||
String ipAddress = env.getProperty(prefix + ".ip-address");
|
||||
String port = env.getProperty(prefix + ".port");
|
||||
String serviceUrl = env.getProperty(prefix + ".service-url");
|
||||
String namespace = env.getProperty(prefix + ".namespace", "");
|
||||
String group = env.getProperty(prefix + ".group", "DEFAULT_GROUP");
|
||||
String clusterName = env.getProperty(prefix + ".clusterName", "DEFAULT");
|
||||
|
||||
FizzNacosProperties fizzNacosProperties = new FizzNacosProperties();
|
||||
fizzNacosProperties.setApplicationContext(applicationContext);
|
||||
fizzNacosProperties.setId(application + ':' + serviceUrl);
|
||||
fizzNacosProperties.setService(application);
|
||||
fizzNacosProperties.setIp(ipAddress == null ? applicationContext.getBean(InetUtils.class).findFirstNonLoopbackAddress().getHostAddress() : ipAddress);
|
||||
fizzNacosProperties.setPort(Integer.parseInt(port));
|
||||
fizzNacosProperties.setNamespace(namespace.equals("") ? null : namespace);
|
||||
fizzNacosProperties.setGroup(group);
|
||||
fizzNacosProperties.setClusterName(clusterName);
|
||||
fizzNacosProperties.setNamespace("");
|
||||
fizzNacosProperties.setSecretKey("");
|
||||
fizzNacosProperties.setAccessKey("");
|
||||
fizzNacosProperties.setUsername("");
|
||||
fizzNacosProperties.setPassword("");
|
||||
fizzNacosProperties.setEndpoint("");
|
||||
fizzNacosProperties.setLogName("");
|
||||
fizzNacosProperties.setNamingLoadCacheAtStart("false");
|
||||
fizzNacosProperties.setServerAddr(serviceUrl);
|
||||
|
||||
FizzNacosServiceRegistration fizzNacosServiceRegistration = FizzNacosHelper.getServiceRegistration(fizzNacosProperties);
|
||||
serviceRegistry = fizzNacosServiceRegistration.serviceRegistry;
|
||||
registration = fizzNacosServiceRegistration.registration;
|
||||
if (nacos) {
|
||||
Properties nacosProperties = new Properties();
|
||||
boolean find = false;
|
||||
for (PropertySource<?> propertySource : env.getPropertySources()) {
|
||||
if (propertySource instanceof OriginTrackedMapPropertySource) {
|
||||
OriginTrackedMapPropertySource originTrackedMapPropertySource = (OriginTrackedMapPropertySource) propertySource;
|
||||
String[] propertyNames = originTrackedMapPropertySource.getPropertyNames();
|
||||
for (String propertyName : propertyNames) {
|
||||
if (propertyName.length() > 64) {
|
||||
int naocsPos = propertyName.indexOf("nacos");
|
||||
if (naocsPos > -1) {
|
||||
nacosProperties.setProperty(propertyName.substring(naocsPos), originTrackedMapPropertySource.getProperty(propertyName).toString());
|
||||
find = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (find) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
log.error("no nacos config");
|
||||
return;
|
||||
}
|
||||
fizzServiceRegistration = FizzNacosHelper.getServiceRegistration(applicationContext, nacosProperties);
|
||||
}
|
||||
|
||||
serviceRegistry.register(registration);
|
||||
fizzServiceRegistration.register();
|
||||
}
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void stop() {
|
||||
if (serviceRegistry != null) {
|
||||
serviceRegistry.deregister(registration);
|
||||
if (fizzServiceRegistration != null) {
|
||||
fizzServiceRegistration.deregister();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import we.plugin.auth.Receiver;
|
||||
import we.proxy.CallbackService;
|
||||
import we.proxy.DiscoveryClientUriSelector;
|
||||
import we.proxy.ServiceInstance;
|
||||
import we.service_registry.RegistryCenterService;
|
||||
import we.util.Consts;
|
||||
import we.util.NettyDataBufferUtils;
|
||||
import we.util.ThreadContext;
|
||||
@@ -75,6 +76,9 @@ public class CallbackFilter extends FizzWebFilter {
|
||||
@Resource
|
||||
private CallbackFilterProperties callbackFilterProperties;
|
||||
|
||||
@Resource
|
||||
private RegistryCenterService registryCenterService;
|
||||
|
||||
@Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE)
|
||||
private ReactiveStringRedisTemplate rt;
|
||||
|
||||
@@ -142,7 +146,14 @@ public class CallbackFilter extends FizzWebFilter {
|
||||
List<Receiver> receivers = ac.callbackConfig.receivers;
|
||||
for (Receiver r : receivers) {
|
||||
if (r.type == ApiConfig.Type.SERVICE_DISCOVERY) {
|
||||
ServiceInstance inst = discoveryClientSelector.getNextInstance(r.service);
|
||||
ServiceInstance inst = null;
|
||||
if (r.registryCenter == null) {
|
||||
inst = discoveryClientSelector.getNextInstance(r.service);
|
||||
} else {
|
||||
String instance = registryCenterService.getInstance(r.registryCenter, r.service);
|
||||
String[] ipAndPort = StringUtils.split(instance, Consts.S.COLON);
|
||||
inst = new ServiceInstance(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
|
||||
}
|
||||
service2instMap.put(r.service, inst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,11 @@ public class RouteFilter extends FizzWebFilter {
|
||||
|
||||
} else if (route.type == ApiConfig.Type.SERVICE_DISCOVERY) {
|
||||
String pathQuery = getBackendPathQuery(req, route);
|
||||
return fizzWebClient.send2service(traceId, route.method, route.backendService, pathQuery, hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval)
|
||||
String svc = route.backendService;
|
||||
if (route.registryCenter != null) {
|
||||
svc = route.registryCenter + Consts.S.COMMA + route.backendService;
|
||||
}
|
||||
return fizzWebClient.send2service(traceId, route.method, svc, pathQuery, hdrs, req.getBody(), route.timeout, route.retryCount, route.retryInterval)
|
||||
.flatMap(genServerResponse(exchange));
|
||||
|
||||
} else if (route.type == ApiConfig.Type.REVERSE_PROXY) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import we.plugin.PluginConfig;
|
||||
import we.proxy.Route;
|
||||
import we.util.Consts;
|
||||
import we.util.JacksonUtils;
|
||||
import we.util.UrlTransformUtils;
|
||||
|
||||
@@ -71,6 +72,8 @@ public class ApiConfig {
|
||||
|
||||
public String service;
|
||||
|
||||
public String registryCenter;
|
||||
|
||||
public String backendService;
|
||||
|
||||
public Object fizzMethod = ALL_METHOD;
|
||||
@@ -141,6 +144,17 @@ public class ApiConfig {
|
||||
firstGatewayGroup = gatewayGroups.iterator().next();
|
||||
}
|
||||
|
||||
@JsonProperty("registryName")
|
||||
public void setRegistryCenter(String rc) {
|
||||
if (StringUtils.isNotBlank(rc)) {
|
||||
if (rc.equals(Consts.S.DEFAULT)) {
|
||||
registryCenter = Consts.S.DEFAULT;
|
||||
} else {
|
||||
registryCenter = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setPath(String p) {
|
||||
if (StringUtils.isNotBlank(p)) {
|
||||
if ("/".equals(p)) {
|
||||
@@ -212,7 +226,8 @@ public class ApiConfig {
|
||||
Route r = new Route().dedicatedLine( this.dedicatedLine)
|
||||
.type( this.type)
|
||||
.method( request.getMethod())
|
||||
.backendService(this.backendService)
|
||||
.registryCenter( this.registryCenter)
|
||||
.backendService( this.backendService)
|
||||
.backendPath( this.backendPath)
|
||||
.rpcMethod( this.rpcMethod)
|
||||
.rpcParamTypes( this.rpcParamTypes)
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
package we.plugin.auth;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import we.util.Consts;
|
||||
import we.util.JacksonUtils;
|
||||
|
||||
/**
|
||||
@@ -27,10 +30,23 @@ public class Receiver {
|
||||
|
||||
public String service;
|
||||
|
||||
public String registryCenter;
|
||||
|
||||
public int type;
|
||||
|
||||
public String path;
|
||||
|
||||
@JsonProperty("registryName")
|
||||
public void setRegistryCenter(String rc) {
|
||||
if (StringUtils.isNotBlank(rc)) {
|
||||
if (rc.equals(Consts.S.DEFAULT)) {
|
||||
registryCenter = Consts.S.DEFAULT;
|
||||
} else {
|
||||
registryCenter = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JacksonUtils.writeValueAsString(this);
|
||||
|
||||
@@ -242,7 +242,13 @@ public class CallbackService {
|
||||
|
||||
for (ServiceTypePath stp : req.assignServices) {
|
||||
if (stp.type == ApiConfig.Type.SERVICE_DISCOVERY) {
|
||||
send = fizzWebClient.send2service(req.id, req.method, stp.service, stp.path, req.headers, req.body)
|
||||
String svc = null;
|
||||
if (stp.registryCenter == null) {
|
||||
svc = stp.service;
|
||||
} else {
|
||||
svc = stp.registryCenter + Consts.S.COMMA + stp.service;
|
||||
}
|
||||
send = fizzWebClient.send2service(req.id, req.method, svc, stp.path, req.headers, req.body)
|
||||
.onErrorResume( crError(req, stp.service, stp.path) );
|
||||
} else {
|
||||
String traceId = CommonConstants.TRACE_ID_PREFIX + req.id;
|
||||
|
||||
@@ -17,12 +17,6 @@
|
||||
|
||||
package we.proxy;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -35,7 +29,6 @@ import org.springframework.web.reactive.function.BodyInserter;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.retry.Retry;
|
||||
@@ -44,10 +37,16 @@ import we.config.SystemConfig;
|
||||
import we.exception.ExternalService4xxException;
|
||||
import we.fizz.exception.FizzRuntimeException;
|
||||
import we.flume.clients.log4j2appender.LogService;
|
||||
import we.service_registry.RegistryCenterService;
|
||||
import we.util.Consts;
|
||||
import we.util.ThreadContext;
|
||||
import we.util.WebUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
@@ -67,6 +66,9 @@ public class FizzWebClient {
|
||||
@Resource
|
||||
private DiscoveryClientUriSelector discoveryClientUriSelector;
|
||||
|
||||
@Resource
|
||||
private RegistryCenterService registryCenterService;
|
||||
|
||||
@Resource(name = ProxyWebClientConfig.proxyWebClient)
|
||||
private WebClient webClient;
|
||||
|
||||
@@ -85,7 +87,16 @@ public class FizzWebClient {
|
||||
Mono<ClientResponse> cr = Mono.just(Consts.S.EMPTY).flatMap(dummy -> {
|
||||
if (isService(s)) {
|
||||
String path = uriOrSvc.substring(uriOrSvc.indexOf(Consts.S.FORWARD_SLASH, 10));
|
||||
String uri = discoveryClientUriSelector.getNextUri(s, path);
|
||||
String uri = null;
|
||||
int commaPos = s.indexOf(Consts.S.COMMA);
|
||||
if (commaPos > -1) {
|
||||
String rc = s.substring(0, commaPos);
|
||||
String svc = s.substring(commaPos + 1);
|
||||
String instance = registryCenterService.getInstance(rc, svc);
|
||||
uri = ThreadContext.getStringBuilder().append(Consts.S.HTTP_PROTOCOL_PREFIX).append(instance).append(path).toString();
|
||||
} else {
|
||||
uri = discoveryClientUriSelector.getNextUri(s, path);
|
||||
}
|
||||
return send2uri(traceId, method, uri, headers, body, timeout);
|
||||
} else {
|
||||
return send2uri(traceId, method, uriOrSvc, headers, body, timeout);
|
||||
@@ -123,7 +134,16 @@ public class FizzWebClient {
|
||||
long timeout, long numRetries, long retryInterval) {
|
||||
|
||||
Mono<ClientResponse> cr = Mono.just(Consts.S.EMPTY).flatMap(dummy -> {
|
||||
String uri = discoveryClientUriSelector.getNextUri(service, relativeUri);
|
||||
String uri = null;
|
||||
int commaPos = service.indexOf(Consts.S.COMMA);
|
||||
if (commaPos > -1) {
|
||||
String rc = service.substring(0, commaPos);
|
||||
String s = service.substring(commaPos + 1);
|
||||
String instance = registryCenterService.getInstance(rc, s);
|
||||
uri = ThreadContext.getStringBuilder().append(Consts.S.HTTP_PROTOCOL_PREFIX).append(instance).append(relativeUri).toString();
|
||||
} else {
|
||||
uri = discoveryClientUriSelector.getNextUri(service, relativeUri);
|
||||
}
|
||||
return send2uri(traceId, method, uri, headers, body, timeout);
|
||||
});
|
||||
if (numRetries > 0) {
|
||||
|
||||
@@ -36,6 +36,8 @@ public class Route {
|
||||
|
||||
public HttpMethod method;
|
||||
|
||||
public String registryCenter;
|
||||
|
||||
public String backendService;
|
||||
|
||||
public String backendPath;
|
||||
@@ -81,6 +83,11 @@ public class Route {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Route registryCenter(String rc) {
|
||||
registryCenter = rc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Route backendService(String bs) {
|
||||
backendService = bs;
|
||||
return this;
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
package we.proxy;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import we.util.Consts;
|
||||
import we.util.JacksonUtils;
|
||||
|
||||
/**
|
||||
@@ -25,12 +28,25 @@ import we.util.JacksonUtils;
|
||||
|
||||
public class ServiceTypePath {
|
||||
|
||||
public String registryCenter;
|
||||
|
||||
public String service;
|
||||
|
||||
public String path;
|
||||
|
||||
public int type;
|
||||
|
||||
@JsonProperty("registryName")
|
||||
public void setRegistryCenter(String rc) {
|
||||
if (StringUtils.isNotBlank(rc)) {
|
||||
if (rc.equals(Consts.S.DEFAULT)) {
|
||||
registryCenter = Consts.S.DEFAULT;
|
||||
} else {
|
||||
registryCenter = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JacksonUtils.writeValueAsString(this);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2020 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.service_registry;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public abstract class FizzServiceRegistration {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger(FizzServiceRegistration.class);
|
||||
|
||||
protected String id;
|
||||
|
||||
private Registration registration;
|
||||
|
||||
private ServiceRegistry serviceRegistry;
|
||||
|
||||
public FizzServiceRegistration(String id, Registration registration, ServiceRegistry serviceRegistry) {
|
||||
this.id = id;
|
||||
this.registration = registration;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
public void register() {
|
||||
serviceRegistry.register(registration);
|
||||
}
|
||||
|
||||
public void deregister() {
|
||||
serviceRegistry.deregister(registration);
|
||||
}
|
||||
|
||||
public abstract RegistryCenter.Status getRegistryCenterStatus();
|
||||
|
||||
public abstract String getInstance(String service);
|
||||
}
|
||||
119
fizz-core/src/main/java/we/service_registry/RegistryCenter.java
Normal file
119
fizz-core/src/main/java/we/service_registry/RegistryCenter.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2020 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.service_registry;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PropertiesLoaderUtils;
|
||||
import we.Fizz;
|
||||
import we.service_registry.eureka.FizzEurekaHelper;
|
||||
import we.service_registry.nacos.FizzNacosHelper;
|
||||
import we.util.JacksonUtils;
|
||||
import we.util.YmlUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public class RegistryCenter {
|
||||
|
||||
public enum Status {
|
||||
UP,
|
||||
DOWN,
|
||||
STARTING,
|
||||
OUT_OF_SERVICE,
|
||||
UNKNOWN;
|
||||
}
|
||||
|
||||
public static final int EUREKA = 1;
|
||||
public static final int NACOS = 2;
|
||||
|
||||
public static final int YML = 1;
|
||||
public static final int PROPERTIES = 2;
|
||||
|
||||
@JsonProperty(
|
||||
access = JsonProperty.Access.WRITE_ONLY
|
||||
)
|
||||
public boolean isDeleted = false;
|
||||
public long id;
|
||||
public String name;
|
||||
public int type;
|
||||
public int clientConfigFormat;
|
||||
public String clientConfig;
|
||||
|
||||
private FizzServiceRegistration fizzServiceRegistration;
|
||||
|
||||
@JsonCreator
|
||||
public RegistryCenter(
|
||||
@JsonProperty("isDeleted") int isDeleted,
|
||||
@JsonProperty("id") long id,
|
||||
@JsonProperty("name") String name,
|
||||
@JsonProperty("type") int type,
|
||||
@JsonProperty("format") int clientConfigFormat,
|
||||
@JsonProperty("content") String clientConfig
|
||||
) {
|
||||
|
||||
if (isDeleted == 1) {
|
||||
this.isDeleted = true;
|
||||
}
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.clientConfigFormat = clientConfigFormat;
|
||||
this.clientConfig = clientConfig;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public FizzServiceRegistration getFizzServiceRegistration() {
|
||||
if (fizzServiceRegistration == null) {
|
||||
Properties properties;
|
||||
if (this.clientConfigFormat == YML) {
|
||||
properties = YmlUtils.string2properties(clientConfig);
|
||||
} else {
|
||||
Resource resource = new ByteArrayResource(clientConfig.getBytes());
|
||||
try {
|
||||
properties = PropertiesLoaderUtils.loadProperties(resource);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (type == EUREKA) {
|
||||
fizzServiceRegistration = FizzEurekaHelper.getServiceRegistration(Fizz.context, properties);
|
||||
} else {
|
||||
fizzServiceRegistration = FizzNacosHelper.getServiceRegistration(Fizz.context, properties);
|
||||
}
|
||||
}
|
||||
return fizzServiceRegistration;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getInstance(String service) {
|
||||
return fizzServiceRegistration.getInstance(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JacksonUtils.writeValueAsString(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2020 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.service_registry;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import we.config.AggregateRedisConfig;
|
||||
import we.util.JacksonUtils;
|
||||
import we.util.Result;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class RegistryCenterService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RegistryCenterService.class);
|
||||
|
||||
private Map<String, RegistryCenter> registryCenterMap = new HashMap<>();
|
||||
|
||||
@Resource(name = AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE)
|
||||
private ReactiveStringRedisTemplate rt;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
Result<?> result = initRegistryCenter();
|
||||
if (result.code == Result.FAIL) {
|
||||
throw new RuntimeException(result.msg, result.t);
|
||||
}
|
||||
result = lsnRegistryCenterChange();
|
||||
if (result.code == Result.FAIL) {
|
||||
throw new RuntimeException(result.msg, result.t);
|
||||
}
|
||||
}
|
||||
|
||||
private Result<?> initRegistryCenter() {
|
||||
Result<?> result = Result.succ();
|
||||
Flux<Map.Entry<Object, Object>> registryCenterEntries = rt.opsForHash().entries("fizz_registry");
|
||||
registryCenterEntries.collectList()
|
||||
.defaultIfEmpty(Collections.emptyList())
|
||||
.flatMap(
|
||||
es -> {
|
||||
if (!es.isEmpty()) {
|
||||
String json = null;
|
||||
try {
|
||||
for (Map.Entry<Object, Object> e : es) {
|
||||
json = (String) e.getValue();
|
||||
RegistryCenter rc = JacksonUtils.readValue(json, RegistryCenter.class);
|
||||
registryCenterMap.put(rc.name, rc);
|
||||
log.info("init registry center {}", rc.name);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
result.code = Result.FAIL;
|
||||
result.msg = "init registry center error, json: " + json;
|
||||
result.t = t;
|
||||
}
|
||||
} else {
|
||||
log.info("no registry center");
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
)
|
||||
.onErrorReturn(
|
||||
throwable -> {
|
||||
result.code = Result.FAIL;
|
||||
result.msg = "init registry center error";
|
||||
result.t = throwable;
|
||||
return true;
|
||||
},
|
||||
result
|
||||
)
|
||||
.block();
|
||||
return result;
|
||||
}
|
||||
|
||||
private Result<?> lsnRegistryCenterChange() {
|
||||
Result<?> result = Result.succ();
|
||||
String channel = "fizz_registry_channel";
|
||||
rt.listenToChannel(channel)
|
||||
.doOnError(
|
||||
t -> {
|
||||
result.code = Result.FAIL;
|
||||
result.msg = "lsn error, channel: " + channel;
|
||||
result.t = t;
|
||||
log.error("lsn channel {} error", channel, t);
|
||||
}
|
||||
)
|
||||
.doOnSubscribe(
|
||||
s -> {
|
||||
log.info("success to lsn on {}", channel);
|
||||
}
|
||||
)
|
||||
.doOnNext(
|
||||
msg -> {
|
||||
String message = msg.getMessage();
|
||||
try {
|
||||
RegistryCenter rc = JacksonUtils.readValue(message, RegistryCenter.class);
|
||||
if (rc.isDeleted) {
|
||||
registryCenterMap.remove(rc.name);
|
||||
log.info("remove registry center {}", rc.name);
|
||||
} else {
|
||||
registryCenterMap.put(rc.name, rc);
|
||||
log.info("update registry center {}", rc.name);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
log.error("update registry center error, {}", message, t);
|
||||
}
|
||||
}
|
||||
)
|
||||
.subscribe();
|
||||
return result;
|
||||
}
|
||||
|
||||
public RegistryCenter getRegistryCenter(String name) {
|
||||
return registryCenterMap.get(name);
|
||||
}
|
||||
|
||||
public String getInstance(String registryCenter, String service) {
|
||||
return registryCenterMap.get(registryCenter).getInstance(service);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,9 @@ package we.service_registry.eureka;
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.HealthCheckHandler;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider;
|
||||
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
@@ -28,10 +30,13 @@ import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.InstanceInfoFactory;
|
||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
|
||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import we.util.Consts;
|
||||
import we.util.PropertiesUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
@@ -39,61 +44,88 @@ import java.util.Map;
|
||||
|
||||
public abstract class FizzEurekaHelper {
|
||||
|
||||
private static final int el = "eureka." .length();
|
||||
private static final int ecl = "eureka.client." .length();
|
||||
private static final int eil = "eureka.instance." .length();
|
||||
|
||||
private FizzEurekaHelper() {
|
||||
}
|
||||
|
||||
public static FizzEurekaServiceRegistration getServiceRegistration(FizzEurekaProperties fizzEurekaProperties) {
|
||||
public static FizzEurekaServiceRegistration getServiceRegistration(ApplicationContext applicationContext, Properties eurekaProperties) {
|
||||
|
||||
InetUtils inetUtils = fizzEurekaProperties.applicationContext.getBean(InetUtils.class);
|
||||
EurekaInstanceConfigBean eurekaInstanceConfig = new EurekaInstanceConfigBean(inetUtils);
|
||||
eurekaInstanceConfig.setAppname(fizzEurekaProperties.appName);
|
||||
eurekaInstanceConfig.setVirtualHostName(fizzEurekaProperties.getVirtualHostName());
|
||||
eurekaInstanceConfig.setNonSecurePort(fizzEurekaProperties.nonSecurePort);
|
||||
|
||||
String ip = fizzEurekaProperties.ipAddress;
|
||||
String instanceId;
|
||||
if (ip == null) {
|
||||
ip = inetUtils.findFirstNonLoopbackAddress().getHostAddress();
|
||||
instanceId = ip + ':' + fizzEurekaProperties.appName + ':' + fizzEurekaProperties.nonSecurePort;
|
||||
Properties eurekaProps = new Properties();
|
||||
for (String propertyName : eurekaProperties.stringPropertyNames()) {
|
||||
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 {
|
||||
instanceId = ip + ':' + fizzEurekaProperties.appName + ':' + fizzEurekaProperties.nonSecurePort;
|
||||
fizzEurekaProperties.instanceId(instanceId);
|
||||
pn = propertyName.substring(el);
|
||||
}
|
||||
if (pn.indexOf(Consts.S.DASH) > -1) {
|
||||
pn = PropertiesUtils.normalize(pn);
|
||||
}
|
||||
eurekaProps.setProperty(pn, eurekaProperties.getProperty(propertyName));
|
||||
}
|
||||
eurekaInstanceConfig.setIpAddress(ip);
|
||||
|
||||
eurekaInstanceConfig.setInstanceId(instanceId);
|
||||
eurekaInstanceConfig.setPreferIpAddress(fizzEurekaProperties.preferIpAddress);
|
||||
eurekaInstanceConfig.setSecurePortEnabled(fizzEurekaProperties.securePortEnabled);
|
||||
String healthCheckUrl = fizzEurekaProperties.getHealthCheckUrl();
|
||||
if (healthCheckUrl != null) {
|
||||
eurekaInstanceConfig.setHealthCheckUrl(healthCheckUrl);
|
||||
InetUtils inetUtils = null;
|
||||
try {
|
||||
inetUtils = applicationContext.getBean(InetUtils.class);
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
inetUtils = new InetUtils(new InetUtilsProperties());
|
||||
}
|
||||
EurekaInstanceConfigBean eurekaInstanceConfig = new EurekaInstanceConfigBean(inetUtils);
|
||||
PropertiesUtils.setBeanPropertyValue(eurekaInstanceConfig, eurekaProps);
|
||||
|
||||
String appname = eurekaInstanceConfig.getAppname();
|
||||
if (appname == null) {
|
||||
appname = applicationContext.getApplicationName();
|
||||
eurekaInstanceConfig.setAppname(appname);
|
||||
}
|
||||
|
||||
// VirtualHostName
|
||||
String virtualHostName = eurekaInstanceConfig.getVirtualHostName();
|
||||
|
||||
if (virtualHostName.equals("unknown")) {
|
||||
eurekaInstanceConfig.setVirtualHostName(appname);
|
||||
}
|
||||
|
||||
String serverPort = eurekaProps.getProperty("serverPort");
|
||||
if (serverPort == null) {
|
||||
serverPort = applicationContext.getEnvironment().getProperty("server.port");
|
||||
}
|
||||
assert serverPort != null;
|
||||
eurekaInstanceConfig.setNonSecurePort(Integer.parseInt(serverPort));
|
||||
|
||||
String ipAddress = eurekaInstanceConfig.getIpAddress();
|
||||
if (ipAddress == null) {
|
||||
ipAddress = inetUtils.findFirstNonLoopbackAddress().getHostAddress();
|
||||
eurekaInstanceConfig.setIpAddress(ipAddress);
|
||||
}
|
||||
|
||||
String instanceId = eurekaInstanceConfig.getInstanceId();
|
||||
if (instanceId == null) {
|
||||
eurekaInstanceConfig.setInstanceId(ipAddress + ':' + appname + ':' + serverPort);
|
||||
}
|
||||
eurekaInstanceConfig.setDataCenterInfo(fizzEurekaProperties.dataCenterInfo);
|
||||
|
||||
InstanceInfo instanceInfo = new InstanceInfoFactory().create(eurekaInstanceConfig);
|
||||
|
||||
ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(eurekaInstanceConfig, instanceInfo);
|
||||
|
||||
EurekaClientConfigBean eurekaClientConfig = new EurekaClientConfigBean();
|
||||
eurekaClientConfig.setRegion(fizzEurekaProperties.region);
|
||||
Map<String, String> serviceUrlMap = new HashMap<>();
|
||||
serviceUrlMap.put(fizzEurekaProperties.zone, fizzEurekaProperties.serviceUrl);
|
||||
eurekaClientConfig.setServiceUrl(serviceUrlMap);
|
||||
Map<String, Class<?>> propertyTypeHint = new HashMap<>();
|
||||
propertyTypeHint.put("serviceUrl", Map.class);
|
||||
PropertiesUtils.setBeanPropertyValue(eurekaClientConfig, eurekaProps, propertyTypeHint);
|
||||
|
||||
CloudEurekaClient eurekaClient = new CloudEurekaClient(applicationInfoManager, eurekaClientConfig, null, fizzEurekaProperties.applicationContext);
|
||||
CloudEurekaClient eurekaClient = new CloudEurekaClient(applicationInfoManager, eurekaClientConfig, null, applicationContext);
|
||||
|
||||
SimpleObjectProvider<HealthCheckHandler> healthCheckHandler = new SimpleObjectProvider<>(null);
|
||||
EurekaRegistration eurekaRegistration = EurekaRegistration.builder(eurekaInstanceConfig).with(applicationInfoManager).with(healthCheckHandler).with(eurekaClient).build();
|
||||
EurekaServiceRegistry serviceRegistry = new EurekaServiceRegistry();
|
||||
return new FizzEurekaServiceRegistration(fizzEurekaProperties.getId(), eurekaRegistration, serviceRegistry, eurekaClient);
|
||||
String registerCenter = eurekaProps.getProperty("register-center");
|
||||
if (registerCenter == null) {
|
||||
registerCenter = eurekaClientConfig.getServiceUrl().get(EurekaClientConfigBean.DEFAULT_ZONE);
|
||||
}
|
||||
|
||||
public static Map<String, FizzEurekaServiceRegistration> getServiceRegistration(List<FizzEurekaProperties> fizzEurekaPropertiesList) {
|
||||
Map<String, FizzEurekaServiceRegistration> result = new HashMap<>();
|
||||
for (FizzEurekaProperties properties : fizzEurekaPropertiesList) {
|
||||
FizzEurekaServiceRegistration fizzEurekaServiceRegistration = getServiceRegistration(properties);
|
||||
result.put(properties.getId(), fizzEurekaServiceRegistration);
|
||||
}
|
||||
return result;
|
||||
return new FizzEurekaServiceRegistration(registerCenter, eurekaRegistration, serviceRegistry, eurekaClient);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 the original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package we.service_registry.eureka;
|
||||
|
||||
import com.netflix.appinfo.DataCenterInfo;
|
||||
import com.netflix.appinfo.MyDataCenterInfo;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public class FizzEurekaProperties {
|
||||
|
||||
public ConfigurableApplicationContext applicationContext;
|
||||
|
||||
private String id;
|
||||
|
||||
public String appName;
|
||||
|
||||
private String virtualHostName;
|
||||
|
||||
public String ipAddress;
|
||||
|
||||
public int nonSecurePort = 80;
|
||||
|
||||
private String instanceId;
|
||||
|
||||
public boolean preferIpAddress = true;
|
||||
|
||||
public boolean securePortEnabled = false;
|
||||
|
||||
private String healthCheckUrl;
|
||||
|
||||
public DataCenterInfo dataCenterInfo = new MyDataCenterInfo(
|
||||
DataCenterInfo.Name.MyOwn);
|
||||
|
||||
public String region = "default";
|
||||
|
||||
public String zone = EurekaClientConfigBean.DEFAULT_ZONE;
|
||||
|
||||
public String serviceUrl;
|
||||
|
||||
public int securePort = 443;
|
||||
|
||||
public FizzEurekaProperties applicationContext(ConfigurableApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
if (id == null) {
|
||||
id = appName + ':' + serviceUrl;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties appName(String appName) {
|
||||
this.appName = appName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties virtualHostName(String virtualHostName) {
|
||||
this.virtualHostName = virtualHostName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getVirtualHostName() {
|
||||
if (virtualHostName == null) {
|
||||
virtualHostName = appName;
|
||||
}
|
||||
return virtualHostName;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties ipAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties nonSecurePort(int nonSecurePort) {
|
||||
this.nonSecurePort = nonSecurePort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties instanceId(String instanceId) {
|
||||
this.instanceId = instanceId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getInstanceId() {
|
||||
/*if (instanceId == null) {
|
||||
instanceId = ipAddress + ':' + appName + ':' + nonSecurePort;
|
||||
}*/
|
||||
return instanceId;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties preferIpAddress(boolean preferIpAddress) {
|
||||
this.preferIpAddress = preferIpAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties securePortEnabled(boolean securePortEnabled) {
|
||||
this.securePortEnabled = securePortEnabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties healthCheckUrl(String healthCheckUrl) {
|
||||
this.healthCheckUrl = healthCheckUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getHealthCheckUrl() {
|
||||
/*if (healthCheckUrl == null) {
|
||||
healthCheckUrl = "http://" + ipAddress + ':' + nonSecurePort + "/actuator/info";
|
||||
}*/
|
||||
return healthCheckUrl;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties region(String region) {
|
||||
this.region = region;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties zone(String zone) {
|
||||
this.zone = zone;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties serviceUrl(String serviceUrl) {
|
||||
this.serviceUrl = serviceUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FizzEurekaProperties securePort(int securePort) {
|
||||
this.securePort = securePort;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -17,28 +17,122 @@
|
||||
|
||||
package we.service_registry.eureka;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
|
||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import we.service_registry.FizzServiceRegistration;
|
||||
import we.service_registry.RegistryCenter;
|
||||
import we.util.Consts;
|
||||
import we.util.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public class FizzEurekaServiceRegistration {
|
||||
public class FizzEurekaServiceRegistration extends FizzServiceRegistration {
|
||||
|
||||
public String id;
|
||||
|
||||
public EurekaRegistration registration;
|
||||
|
||||
public EurekaServiceRegistry serviceRegistry;
|
||||
|
||||
public CloudEurekaClient client;
|
||||
private final CloudEurekaClient client;
|
||||
|
||||
public FizzEurekaServiceRegistration(String id, EurekaRegistration registration, EurekaServiceRegistry serviceRegistry, CloudEurekaClient client) {
|
||||
this.id = id;
|
||||
this.registration = registration;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
super(id, registration, serviceRegistry);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public DiscoveryClient getDiscoveryClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryCenter.Status getRegistryCenterStatus() {
|
||||
EurekaClientConfig eurekaClientConfig = client.getEurekaClientConfig();
|
||||
List<String> eurekaServerServiceUrls = eurekaClientConfig.getEurekaServerServiceUrls(EurekaClientConfigBean.DEFAULT_ZONE);
|
||||
boolean f = false;
|
||||
for (String serviceUrl : eurekaServerServiceUrls) {
|
||||
String vip;
|
||||
int port;
|
||||
int begin = serviceUrl.indexOf('p') + 4;
|
||||
int colon = serviceUrl.indexOf(':', begin);
|
||||
if (colon > -1) {
|
||||
int end = serviceUrl.indexOf('/', colon);
|
||||
vip = serviceUrl.substring(begin, colon);
|
||||
port = Integer.parseInt(serviceUrl.substring(colon + 1, end));
|
||||
} else {
|
||||
int end = serviceUrl.indexOf('/', begin);
|
||||
vip = serviceUrl.substring(begin, end);
|
||||
port = 80;
|
||||
}
|
||||
|
||||
Applications applications = client.getApplications(serviceUrl);
|
||||
for (Application registeredApplication : applications.getRegisteredApplications()) {
|
||||
List<InstanceInfo> instances = registeredApplication.getInstances();
|
||||
for (InstanceInfo instance : instances) {
|
||||
String vipAddress = instance.getVIPAddress();
|
||||
String ipAddr = instance.getIPAddr();
|
||||
if (vipAddress.equals(vip) || ipAddr.equals(vip)) {
|
||||
int p = instance.getPort();
|
||||
if (p == port) {
|
||||
f = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f) {
|
||||
for (InstanceInfo instance : instances) {
|
||||
InstanceInfo.InstanceStatus status = instance.getStatus();
|
||||
if (status != InstanceInfo.InstanceStatus.UP) {
|
||||
return transfrom(status);
|
||||
}
|
||||
}
|
||||
return transfrom(InstanceInfo.InstanceStatus.UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String join = StringUtils.join(eurekaServerServiceUrls, ',');
|
||||
throw Utils.runtimeExceptionWithoutStack("can't find any server with " + join);
|
||||
}
|
||||
|
||||
private RegistryCenter.Status transfrom(InstanceInfo.InstanceStatus status) {
|
||||
if ( status == InstanceInfo.InstanceStatus.UP) {
|
||||
return RegistryCenter.Status.UP;
|
||||
|
||||
} else if (status == InstanceInfo.InstanceStatus.DOWN) {
|
||||
return RegistryCenter.Status.DOWN;
|
||||
|
||||
} else if (status == InstanceInfo.InstanceStatus.OUT_OF_SERVICE) {
|
||||
return RegistryCenter.Status.OUT_OF_SERVICE;
|
||||
|
||||
} else if (status == InstanceInfo.InstanceStatus.STARTING) {
|
||||
return RegistryCenter.Status.STARTING;
|
||||
|
||||
} else {
|
||||
return RegistryCenter.Status.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstance(String service) {
|
||||
InstanceInfo inst = getInstanceInfo(service);
|
||||
return inst.getIPAddr() + Consts.S.COLON + inst.getPort();
|
||||
}
|
||||
|
||||
public InstanceInfo getInstanceInfo(String service) {
|
||||
List<InstanceInfo> insts = client.getInstancesByVipAddress(service, false);
|
||||
if (CollectionUtils.isEmpty(insts)) {
|
||||
throw Utils.runtimeExceptionWithoutStack(id + " eureka no " + service);
|
||||
}
|
||||
Applications apps = client.getApplications();
|
||||
int index = (int) (apps.getNextIndex(service.toUpperCase(), false).incrementAndGet() % insts.size());
|
||||
return insts.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,13 @@ import com.alibaba.cloud.nacos.NacosServiceManager;
|
||||
import com.alibaba.cloud.nacos.registry.NacosRegistration;
|
||||
import com.alibaba.cloud.nacos.registry.NacosServiceRegistry;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import we.util.Consts;
|
||||
import we.util.JacksonUtils;
|
||||
import we.util.PropertiesUtils;
|
||||
import we.util.ReflectionUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
@@ -33,25 +35,44 @@ import java.util.Map;
|
||||
|
||||
public abstract class FizzNacosHelper {
|
||||
|
||||
private static final int ndl = "nacos.discovery.".length();
|
||||
|
||||
private FizzNacosHelper() {
|
||||
}
|
||||
|
||||
public static FizzNacosServiceRegistration getServiceRegistration(FizzNacosProperties fizzNacosProperties) {
|
||||
public static FizzNacosServiceRegistration getServiceRegistration(ApplicationContext applicationContext, Properties nacosProperties) {
|
||||
|
||||
Properties ps = new Properties();
|
||||
for (String propertyName : nacosProperties.stringPropertyNames()) {
|
||||
String pn = propertyName.substring(ndl);
|
||||
if (pn.indexOf(Consts.S.DASH) > -1) {
|
||||
pn = PropertiesUtils.normalize(pn);
|
||||
}
|
||||
ps.setProperty(pn, nacosProperties.getProperty(propertyName));
|
||||
}
|
||||
|
||||
FizzNacosProperties fizzNacosProperties = new FizzNacosProperties();
|
||||
PropertiesUtils.setBeanPropertyValue(fizzNacosProperties, ps);
|
||||
|
||||
fizzNacosProperties.setApplicationContext(applicationContext);
|
||||
if (fizzNacosProperties.getId() == null) {
|
||||
fizzNacosProperties.setId(fizzNacosProperties.getServerAddr());
|
||||
}
|
||||
if (fizzNacosProperties.getService() == null) {
|
||||
fizzNacosProperties.setService(applicationContext.getApplicationName());
|
||||
}
|
||||
if (fizzNacosProperties.getPort() == -1) {
|
||||
fizzNacosProperties.setPort(Integer.parseInt(applicationContext.getEnvironment().getProperty("server.port")));
|
||||
}
|
||||
fizzNacosProperties.setNamingLoadCacheAtStart("false");
|
||||
|
||||
fizzNacosProperties.init();
|
||||
|
||||
NacosServiceRegistry nacosServiceRegistry = new NacosServiceRegistry(fizzNacosProperties);
|
||||
NacosServiceManager nacosServiceManager = new NacosServiceManager();
|
||||
ReflectionUtils.set(nacosServiceRegistry, "nacosServiceManager", nacosServiceManager);
|
||||
NacosRegistration nacosRegistration = new NacosRegistration(null, fizzNacosProperties, fizzNacosProperties.getApplicationContext());
|
||||
NacosRegistration nacosRegistration = new NacosRegistration(null, fizzNacosProperties, applicationContext);
|
||||
NamingService namingService = nacosServiceManager.getNamingService(fizzNacosProperties.getNacosProperties());
|
||||
return new FizzNacosServiceRegistration(fizzNacosProperties.getId(), nacosRegistration, nacosServiceRegistry, namingService);
|
||||
}
|
||||
|
||||
public static Map<String, FizzNacosServiceRegistration> getServiceRegistration(List<FizzNacosProperties> fizzNacosPropertiesList) {
|
||||
Map<String, FizzNacosServiceRegistration> result = new HashMap<>();
|
||||
for (FizzNacosProperties properties : fizzNacosPropertiesList) {
|
||||
FizzNacosServiceRegistration fizzNacosServiceRegistration = getServiceRegistration(properties);
|
||||
result.put(properties.getId(), fizzNacosServiceRegistration);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.nacos.api.naming.PreservedMetadataKeys;
|
||||
import com.alibaba.nacos.client.naming.utils.UtilAndComs;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -38,23 +39,23 @@ import static com.alibaba.nacos.api.PropertyKeyConst.*;
|
||||
|
||||
public class FizzNacosProperties extends NacosDiscoveryProperties {
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private String id;
|
||||
|
||||
private String serverAddr;
|
||||
|
||||
private String username;
|
||||
private String username = "";
|
||||
|
||||
private String password;
|
||||
private String password = "";
|
||||
|
||||
private String endpoint;
|
||||
private String endpoint = "";
|
||||
|
||||
private String namespace;
|
||||
|
||||
private long watchDelay = 30000;
|
||||
|
||||
private String logName;
|
||||
private String logName = "";
|
||||
|
||||
private String service;
|
||||
|
||||
@@ -78,9 +79,9 @@ public class FizzNacosProperties extends NacosDiscoveryProperties {
|
||||
|
||||
private boolean secure = false;
|
||||
|
||||
private String accessKey;
|
||||
private String accessKey = "";
|
||||
|
||||
private String secretKey;
|
||||
private String secretKey = "";
|
||||
|
||||
private Integer heartBeatInterval;
|
||||
|
||||
@@ -143,11 +144,11 @@ public class FizzNacosProperties extends NacosDiscoveryProperties {
|
||||
init = true;
|
||||
}
|
||||
|
||||
public void setApplicationContext(ConfigurableApplicationContext applicationContext) {
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public ConfigurableApplicationContext getApplicationContext() {
|
||||
public ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,28 +17,99 @@
|
||||
|
||||
package we.service_registry.nacos;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.cloud.nacos.registry.NacosRegistration;
|
||||
import com.alibaba.cloud.nacos.registry.NacosServiceRegistry;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.api.naming.NamingService;
|
||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||
import org.springframework.util.StringUtils;
|
||||
import we.service_registry.FizzServiceRegistration;
|
||||
import we.service_registry.RegistryCenter;
|
||||
import we.util.Consts;
|
||||
import we.util.Utils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
public class FizzNacosServiceRegistration {
|
||||
public class FizzNacosServiceRegistration extends FizzServiceRegistration {
|
||||
|
||||
public String id;
|
||||
private NamingService namingService;
|
||||
|
||||
public NacosRegistration registration;
|
||||
private final String groupName;
|
||||
|
||||
public NacosServiceRegistry serviceRegistry;
|
||||
private List<String> clusterNameList;
|
||||
|
||||
public NamingService namingService;
|
||||
private boolean useGroupName;
|
||||
|
||||
private boolean userClusterName;
|
||||
|
||||
public FizzNacosServiceRegistration(String id, NacosRegistration registration, NacosServiceRegistry serviceRegistry, NamingService namingService) {
|
||||
this.id = id;
|
||||
this.registration = registration;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
super(id, registration, serviceRegistry);
|
||||
this.namingService = namingService;
|
||||
NacosDiscoveryProperties discoveryProperties = registration.getNacosDiscoveryProperties();
|
||||
groupName = discoveryProperties.getGroup();
|
||||
if (StringUtils.hasText(groupName)) {
|
||||
useGroupName = true;
|
||||
}
|
||||
String clusterName = discoveryProperties.getClusterName();
|
||||
if (StringUtils.hasText(clusterName)) {
|
||||
userClusterName = true;
|
||||
clusterNameList = Collections.singletonList(clusterName);
|
||||
}
|
||||
}
|
||||
|
||||
public NamingService getNamingService() {
|
||||
return namingService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryCenter.Status getRegistryCenterStatus() {
|
||||
String status = namingService.getServerStatus();
|
||||
return transfrom(status);
|
||||
}
|
||||
|
||||
private RegistryCenter.Status transfrom(String status) {
|
||||
if (status.equals("UP")) {
|
||||
return RegistryCenter.Status.UP;
|
||||
|
||||
} else if (status.equals("DOWN")) {
|
||||
return RegistryCenter.Status.DOWN;
|
||||
|
||||
} else {
|
||||
log.warn("{} status is {}", id, status);
|
||||
return RegistryCenter.Status.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstance(String service) {
|
||||
Instance instance = getInstanceInfo(service);
|
||||
return instance.getIp() + Consts.S.COLON + instance.getPort();
|
||||
}
|
||||
|
||||
public Instance getInstanceInfo(String service) {
|
||||
Instance instance = null;
|
||||
try {
|
||||
if (useGroupName && userClusterName) {
|
||||
instance = namingService.selectOneHealthyInstance(service, groupName, clusterNameList);
|
||||
} else if (useGroupName) {
|
||||
instance = namingService.selectOneHealthyInstance(service, groupName);
|
||||
} else if (userClusterName) {
|
||||
instance = namingService.selectOneHealthyInstance(service, clusterNameList);
|
||||
} else {
|
||||
instance = namingService.selectOneHealthyInstance(service);
|
||||
}
|
||||
} catch (NacosException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (instance == null) {
|
||||
throw Utils.runtimeExceptionWithoutStack(id + " nacos no " + service);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package we.service_registry;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import we.Fizz;
|
||||
import we.redis.RedisProperties;
|
||||
import we.redis.RedisServerConfiguration;
|
||||
import we.redis.RedisTemplateConfiguration;
|
||||
import we.service_registry.eureka.FizzEurekaServiceRegistration;
|
||||
import we.util.ReflectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author hongqiaowei
|
||||
*/
|
||||
|
||||
@TestPropertySource("/application.properties")
|
||||
@SpringJUnitConfig(classes = {RedisProperties.class, RedisTemplateConfiguration.class, RedisServerConfiguration.class})
|
||||
public class RegistryCenterServiceTests {
|
||||
|
||||
@Resource
|
||||
StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Resource
|
||||
ReactiveStringRedisTemplate reactiveStringRedisTemplate;
|
||||
|
||||
RegistryCenterService registryCenterService;
|
||||
|
||||
// @BeforeEach
|
||||
void beforeEach() throws NoSuchFieldException {
|
||||
registryCenterService = new RegistryCenterService();
|
||||
ReflectionUtils.set(registryCenterService, "rt", reactiveStringRedisTemplate);
|
||||
}
|
||||
|
||||
// @Test
|
||||
void initTest() throws Throwable {
|
||||
|
||||
System.setProperty("server.port", "8866");
|
||||
Fizz.context = new GenericApplicationContext();
|
||||
Fizz.context.refresh();
|
||||
|
||||
Map<String, String> registryCenterServiceMap = new HashMap<>();
|
||||
String yml = FileUtil.readString("eureka.yml", CharsetUtil.CHARSET_UTF_8);
|
||||
registryCenterServiceMap.put("1", "{\"id\":1,\"name\":\"default\",\"type\":1,\"format\":1,\"content\":\"" + yml + "\",\"isDeleted\":0}");
|
||||
stringRedisTemplate.opsForHash().putAll("fizz_registry", registryCenterServiceMap);
|
||||
|
||||
registryCenterService.init();
|
||||
RegistryCenter def = registryCenterService.getRegistryCenter("default");
|
||||
FizzServiceRegistration fizzServiceRegistration = def.getFizzServiceRegistration();
|
||||
fizzServiceRegistration.register();
|
||||
// Thread.currentThread().join();
|
||||
}
|
||||
}
|
||||
30
fizz-core/src/test/java/we/util/YmlUtilsTest.java
Normal file
30
fizz-core/src/test/java/we/util/YmlUtilsTest.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package we.util;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class YmlUtilsTest {
|
||||
|
||||
@Test
|
||||
void config2bean() throws IOException {
|
||||
String s = FileUtil.readString("eureka.yml", CharsetUtil.CHARSET_UTF_8);
|
||||
Properties properties = YmlUtils.string2properties(s);
|
||||
// System.err.println("properties: \n" + properties);
|
||||
properties = PropertiesUtils.remove(properties, "eureka.client");
|
||||
EurekaClientConfigBean eurekaClientConfig = new EurekaClientConfigBean();
|
||||
Map<String, Class<?>> propertyTypeHint = new HashMap<>();
|
||||
propertyTypeHint.put("serviceUrl", Map.class);
|
||||
PropertiesUtils.setBeanPropertyValue(eurekaClientConfig, properties, propertyTypeHint);
|
||||
// System.err.println(JacksonUtils.writeValueAsString(eurekaClientConfig));
|
||||
|
||||
// ClassPathResource resource = new ClassPathResource("application.properties");
|
||||
// properties = PropertiesLoaderUtils.loadProperties(resource);
|
||||
}
|
||||
}
|
||||
10
fizz-core/src/test/resources/eureka.yml
Normal file
10
fizz-core/src/test/resources/eureka.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
eureka:
|
||||
client:
|
||||
enabled: true
|
||||
serviceUrl:
|
||||
defaultZone: http://6.6.6.6:6600/eureka,http://8.8.8.8:6600/eureka
|
||||
instance:
|
||||
appname: abc
|
||||
prefer-ip-address: true
|
||||
lease-renewal-interval-in-seconds: 66
|
||||
@@ -179,6 +179,12 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>netty-tcnative-classes</artifactId>
|
||||
<groupId>io.netty</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -218,6 +224,10 @@
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>netty-tcnative-classes</artifactId>
|
||||
<groupId>io.netty</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
@@ -245,6 +255,12 @@
|
||||
<dependency>
|
||||
<groupId>com.fizzgate</groupId>
|
||||
<artifactId>fizz-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>netty-tcnative-classes</artifactId>
|
||||
<groupId>io.netty</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fizzgate</groupId>
|
||||
|
||||
16
pom.xml
16
pom.xml
@@ -6,13 +6,13 @@
|
||||
<properties>
|
||||
<!--<java.version>1.8</java.version>-->
|
||||
<spring-boot.version>2.2.13.RELEASE</spring-boot.version>
|
||||
<spring-framework.version>5.2.18.RELEASE</spring-framework.version>
|
||||
<spring-framework.version>5.2.19.RELEASE</spring-framework.version>
|
||||
<reactor-bom.version>Dysprosium-SR25</reactor-bom.version>
|
||||
<lettuce.version>5.3.7.RELEASE</lettuce.version>
|
||||
<nacos.cloud.version>2.2.6.RELEASE</nacos.cloud.version>
|
||||
<netty.version>4.1.70.Final</netty.version>
|
||||
<httpcore.version>4.4.14</httpcore.version>
|
||||
<log4j2.version>2.14.1</log4j2.version>
|
||||
<netty.version>4.1.72.Final</netty.version>
|
||||
<httpcore.version>4.4.15</httpcore.version>
|
||||
<log4j2.version>2.17.0</log4j2.version>
|
||||
<slf4j.version>1.7.32</slf4j.version>
|
||||
<apache.dubbo.version>2.7.5</apache.dubbo.version>
|
||||
<grpc.version>1.16.1</grpc.version>
|
||||
@@ -25,6 +25,7 @@
|
||||
<netty-tcnative.version>2.0.46.Final</netty-tcnative.version>
|
||||
<spring-cloud.version>2.2.9.RELEASE</spring-cloud.version>
|
||||
<resilience4j.version>1.7.1</resilience4j.version>
|
||||
<snakeyaml.version>1.30</snakeyaml.version>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
@@ -433,11 +434,16 @@
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<version>${netty-tcnative.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-classes</artifactId>
|
||||
<version>${netty-tcnative.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-crypto</artifactId>
|
||||
<version>5.7.16</version>
|
||||
<version>5.7.17</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
Reference in New Issue
Block a user