mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Polish : spring-cloud-incubator/spring-cloud-alibaba#377 : Refactor
This commit is contained in:
parent
514fef53f5
commit
e48863640a
@ -20,12 +20,15 @@ import org.apache.dubbo.common.utils.Assert;
|
|||||||
import org.apache.dubbo.config.spring.util.PropertySourcesUtils;
|
import org.apache.dubbo.config.spring.util.PropertySourcesUtils;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||||
|
import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
|
||||||
|
import org.springframework.cloud.alibaba.dubbo.registry.handler.StandardDubboRegistryServiceIdHandler;
|
||||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
|
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
|
||||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.PathVariableServiceParameterResolver;
|
import org.springframework.cloud.alibaba.dubbo.service.parameter.PathVariableServiceParameterResolver;
|
||||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestBodyServiceParameterResolver;
|
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestBodyServiceParameterResolver;
|
||||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestHeaderServiceParameterResolver;
|
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestHeaderServiceParameterResolver;
|
||||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestParamServiceParameterResolver;
|
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestParamServiceParameterResolver;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
@ -67,6 +70,11 @@ public class DubboServiceAutoConfiguration {
|
|||||||
static class ParameterResolversConfiguration {
|
static class ParameterResolversConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public DubboRegistryServiceIdHandler dubboRegistryServiceIdHandler(ConfigurableApplicationContext context) {
|
||||||
|
return new StandardDubboRegistryServiceIdHandler(context);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459
|
* Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459
|
||||||
|
@ -30,16 +30,16 @@ import java.util.Set;
|
|||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
public class ServiceRestMetadata {
|
public class ServiceRestMetadata {
|
||||||
|
|
||||||
private String name;
|
private String url;
|
||||||
|
|
||||||
private Set<RestMethodMetadata> meta;
|
private Set<RestMethodMetadata> meta;
|
||||||
|
|
||||||
public String getName() {
|
public String getUrl() {
|
||||||
return name;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setUrl(String url) {
|
||||||
this.name = name;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<RestMethodMetadata> getMeta() {
|
public Set<RestMethodMetadata> getMeta() {
|
||||||
@ -55,12 +55,12 @@ public class ServiceRestMetadata {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (!(o instanceof ServiceRestMetadata)) return false;
|
if (!(o instanceof ServiceRestMetadata)) return false;
|
||||||
ServiceRestMetadata that = (ServiceRestMetadata) o;
|
ServiceRestMetadata that = (ServiceRestMetadata) o;
|
||||||
return Objects.equals(name, that.name) &&
|
return Objects.equals(url, that.url) &&
|
||||||
Objects.equals(meta, that.meta);
|
Objects.equals(meta, that.meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(name, meta);
|
return Objects.hash(url, meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ import org.springframework.beans.factory.ObjectProvider;
|
|||||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||||
import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
|
import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
|
||||||
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
|
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
|
||||||
import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry;
|
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -115,10 +114,10 @@ public class DubboServiceBeanMetadataResolver implements BeanClassLoaderAware, S
|
|||||||
List<URL> urls = serviceBean.getExportedUrls();
|
List<URL> urls = serviceBean.getExportedUrls();
|
||||||
|
|
||||||
urls.stream()
|
urls.stream()
|
||||||
.map(SpringCloudRegistry::getServiceName)
|
.map(URL::toString)
|
||||||
.forEach(serviceName -> {
|
.forEach(url -> {
|
||||||
ServiceRestMetadata metadata = new ServiceRestMetadata();
|
ServiceRestMetadata metadata = new ServiceRestMetadata();
|
||||||
metadata.setName(serviceName);
|
metadata.setUrl(url);
|
||||||
metadata.setMeta(methodRestMetadata);
|
metadata.setMeta(methodRestMetadata);
|
||||||
serviceRestMetadata.add(metadata);
|
serviceRestMetadata.add(metadata);
|
||||||
});
|
});
|
||||||
|
@ -18,10 +18,11 @@ package org.springframework.cloud.alibaba.dubbo.registry;
|
|||||||
|
|
||||||
import org.apache.dubbo.common.Constants;
|
import org.apache.dubbo.common.Constants;
|
||||||
import org.apache.dubbo.common.URL;
|
import org.apache.dubbo.common.URL;
|
||||||
import org.apache.dubbo.common.utils.NetUtils;
|
import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
|
||||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
import org.springframework.cloud.client.DefaultServiceInstance;
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
@ -29,20 +30,49 @@ import java.util.LinkedHashMap;
|
|||||||
* Abstract {@link RegistrationFactory} implementation
|
* Abstract {@link RegistrationFactory} implementation
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @param <T> The subclass of {@link Registration}
|
* @param <R> The subclass of {@link Registration}
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractRegistrationFactory<T extends Registration> implements RegistrationFactory<T> {
|
public abstract class AbstractRegistrationFactory<R extends Registration> implements RegistrationFactory<R> {
|
||||||
|
|
||||||
protected ServiceInstance createServiceInstance(String serviceName, URL url) {
|
public final R create(URL url, ConfigurableApplicationContext applicationContext) {
|
||||||
|
ServiceInstance serviceInstance = createServiceInstance(url, applicationContext);
|
||||||
|
return create(url, applicationContext, serviceInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sub-class should override this method to create an instance of {@link R}
|
||||||
|
*
|
||||||
|
* @param url The Dubbo's {@link URL}
|
||||||
|
* @param applicationContext {@link ConfigurableApplicationContext}
|
||||||
|
* @param serviceInstance {@link ServiceInstance}
|
||||||
|
* @return nullable
|
||||||
|
*/
|
||||||
|
protected abstract R create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance {@link ServiceInstance}. This method maybe override by sub-class.
|
||||||
|
*
|
||||||
|
* @param url The Dubbo's {@link URL}
|
||||||
|
* @param applicationContext {@link ConfigurableApplicationContext}
|
||||||
|
* @return an instance {@link ServiceInstance}
|
||||||
|
*/
|
||||||
|
protected ServiceInstance createServiceInstance(URL url, ConfigurableApplicationContext applicationContext) {
|
||||||
|
String serviceId = createServiceId(url, applicationContext);
|
||||||
// Append default category if absent
|
// Append default category if absent
|
||||||
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
|
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
|
||||||
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
|
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
|
||||||
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
|
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
|
||||||
String ip = NetUtils.getLocalHost();
|
String ip = url.getIp();
|
||||||
int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort());
|
int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort());
|
||||||
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceName, ip, port, false);
|
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceId, ip, port, false);
|
||||||
serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters()));
|
serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters()));
|
||||||
return serviceInstance;
|
return serviceInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String createServiceId(URL url, ConfigurableApplicationContext applicationContext) {
|
||||||
|
DubboRegistryServiceIdHandler handler = applicationContext.getBean(DubboRegistryServiceIdHandler.class);
|
||||||
|
return handler.createServiceId(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
package org.springframework.cloud.alibaba.dubbo.registry;
|
package org.springframework.cloud.alibaba.dubbo.registry;
|
||||||
|
|
||||||
import org.apache.dubbo.common.URL;
|
import org.apache.dubbo.common.URL;
|
||||||
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default {@link RegistrationFactory}
|
* Default {@link RegistrationFactory}
|
||||||
@ -28,7 +29,7 @@ import org.springframework.context.ApplicationContext;
|
|||||||
public class DefaultRegistrationFactory extends AbstractRegistrationFactory<Registration> {
|
public class DefaultRegistrationFactory extends AbstractRegistrationFactory<Registration> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Registration create(String serviceName, URL url, ApplicationContext applicationContext) {
|
protected Registration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
|
||||||
return new DelegatingRegistration(createServiceInstance(serviceName, url));
|
return new DelegatingRegistration(serviceInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,24 +18,23 @@ package org.springframework.cloud.alibaba.dubbo.registry;
|
|||||||
|
|
||||||
import org.apache.dubbo.common.URL;
|
import org.apache.dubbo.common.URL;
|
||||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Registration} Factory to createServiceInstance a instance of {@link Registration}
|
* {@link Registration} Factory to createServiceInstance a instance of {@link Registration}
|
||||||
*
|
*
|
||||||
* @param <T> The subclass of {@link Registration}
|
* @param <R> The subclass of {@link Registration}
|
||||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
*/
|
*/
|
||||||
public interface RegistrationFactory<T extends Registration> {
|
public interface RegistrationFactory<R extends Registration> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a instance of {@link T}
|
* Create a instance of {@link R}
|
||||||
*
|
*
|
||||||
* @param serviceName The service name of Dubbo service interface
|
* @param url The Dubbo's {@link URL}
|
||||||
* @param url The Dubbo's URL
|
* @param applicationContext {@link ConfigurableApplicationContext}
|
||||||
* @param applicationContext {@link ApplicationContext}
|
* @return a instance of {@link R}, if null, it indicates the registration will not be executed.
|
||||||
* @return a instance of {@link T}
|
|
||||||
*/
|
*/
|
||||||
T create(String serviceName, URL url, ApplicationContext applicationContext);
|
R create(URL url, ConfigurableApplicationContext applicationContext);
|
||||||
}
|
}
|
||||||
|
@ -18,44 +18,35 @@ package org.springframework.cloud.alibaba.dubbo.registry;
|
|||||||
|
|
||||||
import org.apache.dubbo.common.Constants;
|
import org.apache.dubbo.common.Constants;
|
||||||
import org.apache.dubbo.common.URL;
|
import org.apache.dubbo.common.URL;
|
||||||
import org.apache.dubbo.common.utils.NamedThreadFactory;
|
|
||||||
import org.apache.dubbo.common.utils.UrlUtils;
|
import org.apache.dubbo.common.utils.UrlUtils;
|
||||||
import org.apache.dubbo.registry.NotifyListener;
|
import org.apache.dubbo.registry.NotifyListener;
|
||||||
import org.apache.dubbo.registry.RegistryFactory;
|
import org.apache.dubbo.registry.RegistryFactory;
|
||||||
import org.apache.dubbo.registry.support.FailbackRegistry;
|
import org.apache.dubbo.registry.support.FailbackRegistry;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
|
||||||
import org.springframework.cloud.client.ServiceInstance;
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||||
import org.springframework.cloud.client.serviceregistry.Registration;
|
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||||
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.core.ResolvableType;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static com.alibaba.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
|
import static java.util.Collections.singletonList;
|
||||||
import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY;
|
import static org.apache.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
|
||||||
import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY;
|
import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
|
||||||
import static com.alibaba.dubbo.common.Constants.ROUTERS_CATEGORY;
|
import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
|
||||||
import static java.lang.Long.getLong;
|
import static org.apache.dubbo.common.Constants.PROVIDER_SIDE;
|
||||||
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
|
import static org.apache.dubbo.common.Constants.ROUTERS_CATEGORY;
|
||||||
import static org.springframework.beans.BeanUtils.instantiateClass;
|
import static org.apache.dubbo.common.Constants.SIDE_KEY;
|
||||||
import static org.springframework.core.ResolvableType.forInstance;
|
|
||||||
import static org.springframework.core.ResolvableType.forType;
|
|
||||||
import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames;
|
|
||||||
import static org.springframework.util.ClassUtils.isPresent;
|
|
||||||
import static org.springframework.util.ClassUtils.resolveClassName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
|
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
|
||||||
@ -64,169 +55,96 @@ import static org.springframework.util.ClassUtils.resolveClassName;
|
|||||||
*/
|
*/
|
||||||
public class SpringCloudRegistry extends FailbackRegistry {
|
public class SpringCloudRegistry extends FailbackRegistry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter name of {@link #allServicesLookupInterval}
|
||||||
|
*/
|
||||||
|
public static final String ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.all.services.lookup.interval";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter name of {@link #registeredServicesLookupInterval}
|
||||||
|
*/
|
||||||
|
public static final String REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.registered.services.lookup.interval";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All supported categories
|
* All supported categories
|
||||||
*/
|
*/
|
||||||
private static final String[] ALL_SUPPORTED_CATEGORIES = of(
|
public static final String[] ALL_SUPPORTED_CATEGORIES = of(
|
||||||
PROVIDERS_CATEGORY,
|
PROVIDERS_CATEGORY,
|
||||||
CONSUMERS_CATEGORY,
|
CONSUMERS_CATEGORY,
|
||||||
ROUTERS_CATEGORY,
|
ROUTERS_CATEGORY,
|
||||||
CONFIGURATORS_CATEGORY
|
CONFIGURATORS_CATEGORY
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final int CATEGORY_INDEX = 0;
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
private static final int SERVICE_INTERFACE_INDEX = CATEGORY_INDEX + 1;
|
|
||||||
|
|
||||||
private static final int SERVICE_VERSION_INDEX = SERVICE_INTERFACE_INDEX + 1;
|
|
||||||
|
|
||||||
private static final int SERVICE_GROUP_INDEX = SERVICE_VERSION_INDEX + 1;
|
|
||||||
|
|
||||||
private static final String WILDCARD = "*";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interval in second of lookup service names(only for Dubbo-OPS)
|
* The interval in second of lookup service names(only for Dubbo-OPS)
|
||||||
*/
|
*/
|
||||||
private static final long ALL_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.all.services.lookup.interval", 30);
|
private final long allServicesLookupInterval;
|
||||||
|
|
||||||
/**
|
private final long registeredServicesLookupInterval;
|
||||||
* The interval in second of lookup regigered service instances
|
|
||||||
*/
|
|
||||||
private static final long REGISTERED_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.registered.services.lookup.interval", 300);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link ScheduledExecutorService Scheduler} to lookup the registered services
|
|
||||||
*/
|
|
||||||
private static final ScheduledExecutorService registeredServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-registered-services-lookup-"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link ScheduledExecutorService Scheduler} to lookup all services (only for Dubbo-OPS)
|
|
||||||
*/
|
|
||||||
private static volatile ScheduledExecutorService allServicesLookupScheduler;
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The separator for service name
|
|
||||||
*/
|
|
||||||
private static final String SERVICE_NAME_SEPARATOR = ":";
|
|
||||||
|
|
||||||
private final ApplicationContext applicationContext;
|
|
||||||
|
|
||||||
private final ServiceRegistry<Registration> serviceRegistry;
|
private final ServiceRegistry<Registration> serviceRegistry;
|
||||||
|
|
||||||
private final DiscoveryClient discoveryClient;
|
|
||||||
|
|
||||||
private final RegistrationFactory registrationFactory;
|
private final RegistrationFactory registrationFactory;
|
||||||
|
|
||||||
public SpringCloudRegistry(URL url, ApplicationContext applicationContext) {
|
private final DiscoveryClient discoveryClient;
|
||||||
|
|
||||||
|
private final DubboRegistryServiceIdHandler dubboRegistryServiceIdHandler;
|
||||||
|
|
||||||
|
private final ScheduledExecutorService servicesLookupScheduler;
|
||||||
|
|
||||||
|
private final ConfigurableApplicationContext applicationContext;
|
||||||
|
|
||||||
|
public SpringCloudRegistry(URL url,
|
||||||
|
ServiceRegistry<Registration> serviceRegistry,
|
||||||
|
RegistrationFactory registrationFactory,
|
||||||
|
DiscoveryClient discoveryClient,
|
||||||
|
ScheduledExecutorService servicesLookupScheduler,
|
||||||
|
ConfigurableApplicationContext applicationContext) {
|
||||||
super(url);
|
super(url);
|
||||||
|
this.allServicesLookupInterval = url.getParameter(ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 30L);
|
||||||
|
this.registeredServicesLookupInterval = url.getParameter(REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 300L);
|
||||||
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
this.registrationFactory = registrationFactory;
|
||||||
|
this.discoveryClient = discoveryClient;
|
||||||
|
this.dubboRegistryServiceIdHandler = applicationContext.getBean(DubboRegistryServiceIdHandler.class);
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
|
this.servicesLookupScheduler = servicesLookupScheduler;
|
||||||
this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader());
|
|
||||||
this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
|
|
||||||
applicationContext.getClassLoader();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private RegistrationFactory buildRegistrationFactory(ServiceRegistry<Registration> serviceRegistry,
|
protected boolean shouldRegister(Registration registration) {
|
||||||
ClassLoader classLoader) {
|
Map<String, String> metadata = registration.getMetadata();
|
||||||
RegistrationFactory registrationFactory = null;
|
String side = metadata.get(SIDE_KEY);
|
||||||
List<String> factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader);
|
return PROVIDER_SIDE.equals(side); // Only register the Provider.
|
||||||
|
|
||||||
ResolvableType serviceRegistryType = forInstance(serviceRegistry);
|
|
||||||
// Get first generic Class
|
|
||||||
Class<?> registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0);
|
|
||||||
|
|
||||||
for (String factoryClassName : factoryClassNames) {
|
|
||||||
if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue
|
|
||||||
Class<?> factoryClass = resolveClassName(factoryClassName, classLoader);
|
|
||||||
ResolvableType registrationFactoryType = forType(factoryClass);
|
|
||||||
Class<?> actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0);
|
|
||||||
if (registrationClass.equals(actualRegistrationClass)) {
|
|
||||||
registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (registrationFactory == null) {
|
|
||||||
|
|
||||||
if (logger.isWarnEnabled()) {
|
|
||||||
logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]",
|
|
||||||
registrationClass.getSimpleName(), serviceRegistry.getClass().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
registrationFactory = new DefaultRegistrationFactory();
|
|
||||||
} else {
|
|
||||||
if (logger.isInfoEnabled()) {
|
|
||||||
logger.info("{} has been resolved by ServiceRegistry[{}]",
|
|
||||||
registrationFactory.getClass().getName(), serviceRegistry.getClass().getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return registrationFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> resolveGenericClass(ResolvableType implementedType, Class<?> interfaceClass, int index) {
|
|
||||||
|
|
||||||
ResolvableType resolvableType = implementedType;
|
|
||||||
|
|
||||||
try {
|
|
||||||
OUTER:
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
ResolvableType[] interfaceTypes = resolvableType.getInterfaces();
|
|
||||||
|
|
||||||
for (ResolvableType interfaceType : interfaceTypes) {
|
|
||||||
if (interfaceType.resolve().equals(interfaceClass)) {
|
|
||||||
resolvableType = interfaceType;
|
|
||||||
break OUTER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ResolvableType superType = resolvableType.getSuperType();
|
|
||||||
|
|
||||||
Class<?> superClass = superType.resolve();
|
|
||||||
|
|
||||||
if (Object.class.equals(superClass)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvableType = superType;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Throwable e) {
|
|
||||||
resolvableType = ResolvableType.forType(void.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolvableType.resolveGeneric(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doRegister(URL url) {
|
public void doRegister(URL url) {
|
||||||
final String serviceName = getServiceName(url);
|
final Registration registration = createRegistration(url);
|
||||||
final Registration registration = createRegistration(serviceName, url);
|
if (shouldRegister(registration)) {
|
||||||
serviceRegistry.register(registration);
|
serviceRegistry.register(registration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doUnregister(URL url) {
|
public void doUnregister(URL url) {
|
||||||
final String serviceName = getServiceName(url);
|
final Registration registration = createRegistration(url);
|
||||||
final Registration registration = createRegistration(serviceName, url);
|
if (shouldRegister(registration)) {
|
||||||
this.serviceRegistry.deregister(registration);
|
this.serviceRegistry.deregister(registration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doSubscribe(URL url, NotifyListener listener) {
|
public void doSubscribe(URL url, NotifyListener listener) {
|
||||||
List<String> serviceNames = getServiceNames(url, listener);
|
List<String> serviceNames = getServiceNames(url, listener);
|
||||||
doSubscribe(url, listener, serviceNames);
|
doSubscribe(url, listener, serviceNames);
|
||||||
this.registeredServicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
|
this.servicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
doSubscribe(url, listener, serviceNames);
|
doSubscribe(url, listener, serviceNames);
|
||||||
}
|
}
|
||||||
}, REGISTERED_SERVICES_LOOKUP_INTERVAL, REGISTERED_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS);
|
}, registeredServicesLookupInterval, registeredServicesLookupInterval, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -234,136 +152,34 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
|||||||
if (isAdminProtocol(url)) {
|
if (isAdminProtocol(url)) {
|
||||||
shutdownServiceNamesLookup();
|
shutdownServiceNamesLookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (registeredServicesLookupScheduler != null) {
|
|
||||||
// registeredServicesLookupScheduler.shutdown();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
return false;
|
return !discoveryClient.getServices().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shutdownServiceNamesLookup() {
|
private void shutdownServiceNamesLookup() {
|
||||||
if (allServicesLookupScheduler != null) {
|
if (servicesLookupScheduler != null) {
|
||||||
allServicesLookupScheduler.shutdown();
|
servicesLookupScheduler.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Registration createRegistration(String serviceName, URL url) {
|
private Registration createRegistration(URL url) {
|
||||||
return registrationFactory.create(serviceName, url, applicationContext);
|
return registrationFactory.create(url, applicationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getServiceName(URL url) {
|
private void filterServiceNames(List<String> serviceNames) {
|
||||||
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
|
|
||||||
return getServiceName(url, category);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getServiceName(URL url, String category) {
|
|
||||||
StringBuilder serviceNameBuilder = new StringBuilder(category);
|
|
||||||
appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY);
|
|
||||||
appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY);
|
|
||||||
appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY);
|
|
||||||
return serviceNameBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void appendIfPresent(StringBuilder target, URL url, String parameterName) {
|
|
||||||
String parameterValue = url.getParameter(parameterName);
|
|
||||||
appendIfPresent(target, parameterValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void appendIfPresent(StringBuilder target, String parameterValue) {
|
|
||||||
if (StringUtils.hasText(parameterValue)) {
|
|
||||||
target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void filterServiceNames(List<String> serviceNames, URL url) {
|
|
||||||
|
|
||||||
final String[] categories = getCategories(url);
|
|
||||||
|
|
||||||
final String targetServiceInterface = url.getServiceInterface();
|
|
||||||
|
|
||||||
final String targetVersion = url.getParameter(Constants.VERSION_KEY);
|
|
||||||
|
|
||||||
final String targetGroup = url.getParameter(Constants.GROUP_KEY);
|
|
||||||
|
|
||||||
filter(serviceNames, new Filter<String>() {
|
filter(serviceNames, new Filter<String>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(String serviceName) {
|
public boolean accept(String serviceName) {
|
||||||
// split service name to segments
|
return dubboRegistryServiceIdHandler.supports(serviceName);
|
||||||
// (required) segments[0] = category
|
|
||||||
// (required) segments[1] = serviceInterface
|
|
||||||
// (required) segments[2] = version
|
|
||||||
// (optional) segments[3] = group
|
|
||||||
String[] segments = getServiceSegments(serviceName);
|
|
||||||
int length = segments.length;
|
|
||||||
if (length < SERVICE_GROUP_INDEX) { // must present 4 segments or more
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String category = getCategory(segments);
|
|
||||||
if (Arrays.binarySearch(categories, category) > -1) { // no match category
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String serviceInterface = getServiceInterface(segments);
|
|
||||||
if (!WILDCARD.equals(targetServiceInterface) &&
|
|
||||||
!Objects.equals(targetServiceInterface, serviceInterface)) { // no match service interface
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String version = getServiceVersion(segments);
|
|
||||||
if (!WILDCARD.equals(targetVersion) &&
|
|
||||||
!Objects.equals(targetVersion, version)) { // no match service version
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String group = getServiceGroup(segments);
|
|
||||||
if (group != null && !WILDCARD.equals(targetGroup)
|
|
||||||
&& !Objects.equals(targetGroup, group)) { // no match service group
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getServiceSegments(String serviceName) {
|
|
||||||
return StringUtils.delimitedListToStringArray(serviceName, SERVICE_NAME_SEPARATOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getCategory(String[] segments) {
|
|
||||||
return segments[CATEGORY_INDEX];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getServiceInterface(String[] segments) {
|
|
||||||
return segments[SERVICE_INTERFACE_INDEX];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getServiceVersion(String[] segments) {
|
|
||||||
return segments[SERVICE_VERSION_INDEX];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getServiceGroup(String[] segments) {
|
|
||||||
return segments.length > SERVICE_GROUP_INDEX ? segments[SERVICE_GROUP_INDEX] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the categories from {@link URL}
|
|
||||||
*
|
|
||||||
* @param url {@link URL}
|
|
||||||
* @return non-null array
|
|
||||||
*/
|
|
||||||
private String[] getCategories(URL url) {
|
|
||||||
return Constants.ANY_VALUE.equals(url.getServiceInterface()) ?
|
|
||||||
ALL_SUPPORTED_CATEGORIES : of(Constants.DEFAULT_CATEGORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> getAllServiceNames() {
|
private List<String> getAllServiceNames() {
|
||||||
return discoveryClient.getServices();
|
return new LinkedList<>(discoveryClient.getServices());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -378,7 +194,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
|||||||
initAllServicesLookupScheduler(url, listener);
|
initAllServicesLookupScheduler(url, listener);
|
||||||
return getServiceNamesForOps(url);
|
return getServiceNamesForOps(url);
|
||||||
} else {
|
} else {
|
||||||
return doGetServiceNames(url);
|
return singletonList(dubboRegistryServiceIdHandler.createServiceId(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,30 +204,14 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initAllServicesLookupScheduler(final URL url, final NotifyListener listener) {
|
private void initAllServicesLookupScheduler(final URL url, final NotifyListener listener) {
|
||||||
if (allServicesLookupScheduler == null) {
|
servicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
|
||||||
allServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-all-services-lookup-"));
|
@Override
|
||||||
allServicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
|
public void run() {
|
||||||
@Override
|
List<String> serviceNames = getAllServiceNames();
|
||||||
public void run() {
|
filterServiceNames(serviceNames);
|
||||||
List<String> serviceNames = getAllServiceNames();
|
doSubscribe(url, listener, serviceNames);
|
||||||
filter(serviceNames, new Filter<String>() {
|
}
|
||||||
@Override
|
}, allServicesLookupInterval, allServicesLookupInterval, TimeUnit.SECONDS);
|
||||||
public boolean accept(String serviceName) {
|
|
||||||
boolean accepted = false;
|
|
||||||
for (String category : ALL_SUPPORTED_CATEGORIES) {
|
|
||||||
String prefix = category + SERVICE_NAME_SEPARATOR;
|
|
||||||
if (StringUtils.startsWithIgnoreCase(serviceName, prefix)) {
|
|
||||||
accepted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return accepted;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
doSubscribe(url, listener, serviceNames);
|
|
||||||
}
|
|
||||||
}, ALL_SERVICES_LOOKUP_INTERVAL, ALL_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doSubscribe(final URL url, final NotifyListener listener, final List<String> serviceNames) {
|
private void doSubscribe(final URL url, final NotifyListener listener, final List<String> serviceNames) {
|
||||||
@ -421,16 +221,6 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> doGetServiceNames(URL url) {
|
|
||||||
String[] categories = getCategories(url);
|
|
||||||
List<String> serviceNames = new ArrayList<String>(categories.length);
|
|
||||||
for (String category : categories) {
|
|
||||||
final String serviceName = getServiceName(url, category);
|
|
||||||
serviceNames.add(serviceName);
|
|
||||||
}
|
|
||||||
return serviceNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the Healthy {@link ServiceInstance service instance} to subscriber.
|
* Notify the Healthy {@link ServiceInstance service instance} to subscriber.
|
||||||
*
|
*
|
||||||
@ -487,7 +277,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
|||||||
*/
|
*/
|
||||||
private List<String> getServiceNamesForOps(URL url) {
|
private List<String> getServiceNamesForOps(URL url) {
|
||||||
List<String> serviceNames = getAllServiceNames();
|
List<String> serviceNames = getAllServiceNames();
|
||||||
filterServiceNames(serviceNames, url);
|
filterServiceNames(serviceNames);
|
||||||
return serviceNames;
|
return serviceNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,7 +298,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
|||||||
/**
|
/**
|
||||||
* A filter
|
* A filter
|
||||||
*/
|
*/
|
||||||
private interface Filter<T> {
|
public interface Filter<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether or not the specified data should be accepted.
|
* Tests whether or not the specified data should be accepted.
|
||||||
|
@ -17,9 +17,28 @@
|
|||||||
package org.springframework.cloud.alibaba.dubbo.registry;
|
package org.springframework.cloud.alibaba.dubbo.registry;
|
||||||
|
|
||||||
import org.apache.dubbo.common.URL;
|
import org.apache.dubbo.common.URL;
|
||||||
|
import org.apache.dubbo.common.utils.NamedThreadFactory;
|
||||||
import org.apache.dubbo.registry.Registry;
|
import org.apache.dubbo.registry.Registry;
|
||||||
import org.apache.dubbo.registry.RegistryFactory;
|
import org.apache.dubbo.registry.RegistryFactory;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||||
|
import org.springframework.cloud.client.serviceregistry.Registration;
|
||||||
|
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.core.ResolvableType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
|
import static java.lang.System.getProperty;
|
||||||
|
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
|
||||||
|
import static org.springframework.beans.BeanUtils.instantiateClass;
|
||||||
|
import static org.springframework.core.ResolvableType.forInstance;
|
||||||
|
import static org.springframework.core.ResolvableType.forType;
|
||||||
|
import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames;
|
||||||
|
import static org.springframework.util.ClassUtils.isPresent;
|
||||||
|
import static org.springframework.util.ClassUtils.resolveClassName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
|
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
|
||||||
@ -30,14 +49,122 @@ import org.springframework.context.ApplicationContext;
|
|||||||
*/
|
*/
|
||||||
public class SpringCloudRegistryFactory implements RegistryFactory {
|
public class SpringCloudRegistryFactory implements RegistryFactory {
|
||||||
|
|
||||||
private static ApplicationContext applicationContext;
|
private static String SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX =
|
||||||
|
getProperty("dubbo.services.lookup.scheduler.thread.name.prefix ", "dubbo-services-lookup-");
|
||||||
|
|
||||||
|
private static ConfigurableApplicationContext applicationContext;
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final ScheduledExecutorService servicesLookupScheduler;
|
||||||
|
|
||||||
|
private ServiceRegistry<Registration> serviceRegistry;
|
||||||
|
|
||||||
|
private RegistrationFactory registrationFactory;
|
||||||
|
|
||||||
|
private DiscoveryClient discoveryClient;
|
||||||
|
|
||||||
|
private volatile boolean initialized = false;
|
||||||
|
|
||||||
|
public SpringCloudRegistryFactory() {
|
||||||
|
servicesLookupScheduler = newSingleThreadScheduledExecutor(
|
||||||
|
new NamedThreadFactory(SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init() {
|
||||||
|
if (initialized || applicationContext == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
|
||||||
|
this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader());
|
||||||
|
this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Registry getRegistry(URL url) {
|
public Registry getRegistry(URL url) {
|
||||||
return new SpringCloudRegistry(url, applicationContext);
|
init();
|
||||||
|
return new SpringCloudRegistry(url, serviceRegistry, registrationFactory, discoveryClient,
|
||||||
|
servicesLookupScheduler, applicationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setApplicationContext(ApplicationContext applicationContext) {
|
public static void setApplicationContext(ConfigurableApplicationContext applicationContext) {
|
||||||
SpringCloudRegistryFactory.applicationContext = applicationContext;
|
SpringCloudRegistryFactory.applicationContext = applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private RegistrationFactory buildRegistrationFactory(ServiceRegistry<Registration> serviceRegistry,
|
||||||
|
ClassLoader classLoader) {
|
||||||
|
RegistrationFactory registrationFactory = null;
|
||||||
|
List<String> factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader);
|
||||||
|
|
||||||
|
ResolvableType serviceRegistryType = forInstance(serviceRegistry);
|
||||||
|
// Get first generic Class
|
||||||
|
Class<?> registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0);
|
||||||
|
|
||||||
|
for (String factoryClassName : factoryClassNames) {
|
||||||
|
if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue
|
||||||
|
Class<?> factoryClass = resolveClassName(factoryClassName, classLoader);
|
||||||
|
ResolvableType registrationFactoryType = forType(factoryClass);
|
||||||
|
Class<?> actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0);
|
||||||
|
if (registrationClass.equals(actualRegistrationClass)) {
|
||||||
|
registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registrationFactory == null) {
|
||||||
|
|
||||||
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]",
|
||||||
|
registrationClass.getSimpleName(), serviceRegistry.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
registrationFactory = new DefaultRegistrationFactory();
|
||||||
|
} else {
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("{} has been resolved by ServiceRegistry[{}]",
|
||||||
|
registrationFactory.getClass().getName(), serviceRegistry.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return registrationFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<?> resolveGenericClass(ResolvableType implementedType, Class<?> interfaceClass, int index) {
|
||||||
|
|
||||||
|
ResolvableType resolvableType = implementedType;
|
||||||
|
|
||||||
|
try {
|
||||||
|
OUTER:
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
ResolvableType[] interfaceTypes = resolvableType.getInterfaces();
|
||||||
|
|
||||||
|
for (ResolvableType interfaceType : interfaceTypes) {
|
||||||
|
if (interfaceType.resolve().equals(interfaceClass)) {
|
||||||
|
resolvableType = interfaceType;
|
||||||
|
break OUTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResolvableType superType = resolvableType.getSuperType();
|
||||||
|
|
||||||
|
Class<?> superClass = superType.resolve();
|
||||||
|
|
||||||
|
if (Object.class.equals(superClass)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvableType = superType;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Throwable e) {
|
||||||
|
resolvableType = ResolvableType.forType(void.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolvableType.resolveGeneric(index);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import org.springframework.cloud.client.ServiceInstance;
|
|||||||
import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance;
|
import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance;
|
||||||
import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration;
|
import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration;
|
||||||
import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
|
import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zookeeper {@link RegistrationFactory}
|
* Zookeeper {@link RegistrationFactory}
|
||||||
@ -33,10 +33,7 @@ import org.springframework.context.ApplicationContext;
|
|||||||
public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory<ZookeeperRegistration> {
|
public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory<ZookeeperRegistration> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ZookeeperRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
|
protected ZookeeperRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
|
||||||
|
|
||||||
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
|
|
||||||
|
|
||||||
ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(),
|
ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(),
|
||||||
serviceInstance.getServiceId(), serviceInstance.getMetadata());
|
serviceInstance.getServiceId(), serviceInstance.getMetadata());
|
||||||
|
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.cloud.alibaba.dubbo.registry.handler;
|
||||||
|
|
||||||
|
import org.apache.dubbo.common.URL;
|
||||||
|
import org.apache.dubbo.registry.Registry;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dubbo {@link Registry} Spring Cloud Service Id Builder
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
|
*/
|
||||||
|
public interface DubboRegistryServiceIdHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supports the specified id of Spring Cloud Service or not
|
||||||
|
*
|
||||||
|
* @param serviceId the specified id of Spring Cloud Service
|
||||||
|
* @return if supports, return <code>true</code>, or <code>false</code>
|
||||||
|
*/
|
||||||
|
boolean supports(String serviceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the id of Spring Cloud Service
|
||||||
|
*
|
||||||
|
* @param url The Dubbo's {@link URL}
|
||||||
|
* @return non-null
|
||||||
|
*/
|
||||||
|
String createServiceId(URL url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The instance if {@link ConfigurableApplicationContext} .
|
||||||
|
*
|
||||||
|
* @return non-null
|
||||||
|
*/
|
||||||
|
ConfigurableApplicationContext getContext();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.cloud.alibaba.dubbo.registry.handler;
|
||||||
|
|
||||||
|
import org.apache.dubbo.common.Constants;
|
||||||
|
import org.apache.dubbo.common.URL;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static java.lang.System.getProperty;
|
||||||
|
import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
|
||||||
|
import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
|
||||||
|
import static org.springframework.util.StringUtils.startsWithIgnoreCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Standard {@link DubboRegistryServiceIdHandler}
|
||||||
|
* <p>
|
||||||
|
* The service ID pattern is "${category}:${interface}:${version}:${group}"
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||||
|
*/
|
||||||
|
public class StandardDubboRegistryServiceIdHandler implements DubboRegistryServiceIdHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The separator for service name that could be changed by the Java Property "dubbo.service.name.separator".
|
||||||
|
*/
|
||||||
|
protected static final String SERVICE_NAME_SEPARATOR = getProperty("dubbo.service.name.separator", ":");
|
||||||
|
|
||||||
|
private final ConfigurableApplicationContext context;
|
||||||
|
|
||||||
|
public StandardDubboRegistryServiceIdHandler(ConfigurableApplicationContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(String serviceId) {
|
||||||
|
return startsWithIgnoreCase(serviceId, PROVIDERS_CATEGORY) ||
|
||||||
|
startsWithIgnoreCase(serviceId, CONSUMERS_CATEGORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createServiceId(URL url) {
|
||||||
|
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
|
||||||
|
if (!Objects.equals(category, PROVIDERS_CATEGORY) && !Objects.equals(category, CONSUMERS_CATEGORY)) {
|
||||||
|
category = PROVIDERS_CATEGORY;
|
||||||
|
}
|
||||||
|
return createServiceId(url, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurableApplicationContext getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method maybe override by sub-class.
|
||||||
|
*
|
||||||
|
* @param url The Dubbo's {@link URL}
|
||||||
|
* @param category The category
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected String createServiceId(URL url, String category) {
|
||||||
|
StringBuilder serviceNameBuilder = new StringBuilder(category);
|
||||||
|
appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY);
|
||||||
|
appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY);
|
||||||
|
appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY);
|
||||||
|
return serviceNameBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void appendIfPresent(StringBuilder target, URL url, String parameterName) {
|
||||||
|
String parameterValue = url.getParameter(parameterName);
|
||||||
|
appendIfPresent(target, parameterValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void appendIfPresent(StringBuilder target, String parameterValue) {
|
||||||
|
if (StringUtils.hasText(parameterValue)) {
|
||||||
|
target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ import org.springframework.cloud.client.ServiceInstance;
|
|||||||
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
|
||||||
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
|
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
|
||||||
import org.springframework.cloud.consul.serviceregistry.ConsulRegistration;
|
import org.springframework.cloud.consul.serviceregistry.ConsulRegistration;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -40,9 +40,7 @@ import java.util.Set;
|
|||||||
public class ConsulRegistrationFactory extends AbstractRegistrationFactory<ConsulRegistration> {
|
public class ConsulRegistrationFactory extends AbstractRegistrationFactory<ConsulRegistration> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsulRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
|
protected ConsulRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
|
||||||
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
|
|
||||||
|
|
||||||
Map<String, String> metadata = getMetadata(serviceInstance);
|
Map<String, String> metadata = getMetadata(serviceInstance);
|
||||||
List<String> tags = createTags(metadata);
|
List<String> tags = createTags(metadata);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import org.springframework.cloud.commons.util.InetUtils;
|
|||||||
import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig;
|
import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig;
|
||||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
|
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link EurekaRegistration} Factory
|
* {@link EurekaRegistration} Factory
|
||||||
@ -37,8 +37,7 @@ import org.springframework.context.ApplicationContext;
|
|||||||
public class EurekaRegistrationFactory extends AbstractRegistrationFactory<EurekaRegistration> {
|
public class EurekaRegistrationFactory extends AbstractRegistrationFactory<EurekaRegistration> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EurekaRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
|
protected EurekaRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
|
||||||
ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
|
|
||||||
CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class);
|
CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class);
|
||||||
ObjectProvider<HealthCheckHandler> healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
|
ObjectProvider<HealthCheckHandler> healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
|
||||||
EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);
|
EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.cloud.alibaba.dubbo.service;
|
package org.springframework.cloud.alibaba.dubbo.service;
|
||||||
|
|
||||||
|
import org.apache.dubbo.common.URL;
|
||||||
import org.apache.dubbo.config.spring.ReferenceBean;
|
import org.apache.dubbo.config.spring.ReferenceBean;
|
||||||
import org.apache.dubbo.rpc.service.GenericService;
|
import org.apache.dubbo.rpc.service.GenericService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -30,12 +31,10 @@ import java.util.Objects;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import static com.alibaba.dubbo.common.Constants.DEFAULT_CLUSTER;
|
import static org.apache.dubbo.common.Constants.DEFAULT_CLUSTER;
|
||||||
import static com.alibaba.dubbo.common.Constants.DEFAULT_PROTOCOL;
|
import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL;
|
||||||
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceGroup;
|
import static org.apache.dubbo.common.Constants.GROUP_KEY;
|
||||||
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceInterface;
|
import static org.apache.dubbo.common.Constants.VERSION_KEY;
|
||||||
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceSegments;
|
|
||||||
import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceVersion;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dubbo {@link GenericService} Factory
|
* Dubbo {@link GenericService} Factory
|
||||||
@ -66,11 +65,11 @@ public class DubboGenericServiceFactory {
|
|||||||
|
|
||||||
private ReferenceBean<GenericService> build(ServiceRestMetadata serviceRestMetadata,
|
private ReferenceBean<GenericService> build(ServiceRestMetadata serviceRestMetadata,
|
||||||
DubboTransportedMetadata dubboTransportedMetadata) {
|
DubboTransportedMetadata dubboTransportedMetadata) {
|
||||||
String dubboServiceName = serviceRestMetadata.getName();
|
String urlValue = serviceRestMetadata.getUrl();
|
||||||
String[] segments = getServiceSegments(dubboServiceName);
|
URL url = URL.valueOf(urlValue);
|
||||||
String interfaceName = getServiceInterface(segments);
|
String interfaceName = url.getServiceInterface();
|
||||||
String version = getServiceVersion(segments);
|
String version = url.getParameter(VERSION_KEY);
|
||||||
String group = getServiceGroup(segments);
|
String group = url.getParameter(GROUP_KEY);
|
||||||
String protocol = dubboTransportedMetadata.getProtocol();
|
String protocol = dubboTransportedMetadata.getProtocol();
|
||||||
String cluster = dubboTransportedMetadata.getCluster();
|
String cluster = dubboTransportedMetadata.getCluster();
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ org.springframework.context.ApplicationContextInitializer=\
|
|||||||
org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
|
org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
|
||||||
|
|
||||||
org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory=\
|
org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory=\
|
||||||
org.springframework.cloud.alibaba.dubbo.registry.DefaultRegistrationFactory,\
|
|
||||||
org.springframework.cloud.alibaba.dubbo.registry.netflix.eureka.EurekaRegistrationFactory,\
|
org.springframework.cloud.alibaba.dubbo.registry.netflix.eureka.EurekaRegistrationFactory,\
|
||||||
org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper.ZookeeperRegistrationFactory,\
|
org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper.ZookeeperRegistrationFactory,\
|
||||||
org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul.ConsulRegistrationFactory
|
org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul.ConsulRegistrationFactory
|
@ -1,5 +1,8 @@
|
|||||||
dubbo:
|
dubbo:
|
||||||
registry:
|
registry:
|
||||||
address: spring-cloud://nacos
|
# The Spring Cloud Dubbo's registry extension
|
||||||
|
address: spring-cloud://localhost
|
||||||
|
# The traditional Dubbo's registry
|
||||||
|
# address: zookeeper://127.0.0.1:2181
|
||||||
server:
|
server:
|
||||||
port: 7070
|
port: 7070
|
@ -10,7 +10,10 @@ dubbo:
|
|||||||
port: 8081
|
port: 8081
|
||||||
server: netty
|
server: netty
|
||||||
registry:
|
registry:
|
||||||
address: spring-cloud://nacos
|
# The Spring Cloud Dubbo's registry extension
|
||||||
|
address: spring-cloud://localhost
|
||||||
|
# The traditional Dubbo's registry
|
||||||
|
# address: zookeeper://127.0.0.1:2181
|
||||||
|
|
||||||
feign:
|
feign:
|
||||||
hystrix:
|
hystrix:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user