1
0
mirror of https://gitee.com/mirrors/Spring-Cloud-Alibaba.git synced 2021-06-26 13:25:11 +08:00
This commit is contained in:
mercyblitz 2019-07-31 16:41:52 +08:00
parent 7225f63f56
commit 9e0a5185d1
7 changed files with 284 additions and 132 deletions

View File

@ -19,6 +19,13 @@ package com.alibaba.cloud.dubbo.autoconfigure;
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository; import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent; import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent;
import com.netflix.discovery.CacheRefreshedEvent; import com.netflix.discovery.CacheRefreshedEvent;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.AutoConfigureOrder;
@ -29,17 +36,25 @@ 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.discovery.event.HeartbeatEvent; import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient; import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
import org.springframework.cloud.zookeeper.discovery.dependency.ZookeeperDependencies;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.CONSUL_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.CONSUL_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME;
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceDiscoveryAutoConfiguration.ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME;
import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME;
import static org.springframework.util.CollectionUtils.isEmpty; import static org.apache.zookeeper.Watcher.Event.EventType.NodeChildrenChanged;
import static org.apache.zookeeper.Watcher.Event.EventType.NodeDataChanged;
import static org.springframework.util.StringUtils.hasText; import static org.springframework.util.StringUtils.hasText;
/** /**
@ -65,19 +80,25 @@ public class DubboServiceDiscoveryAutoConfiguration {
private final DubboServiceMetadataRepository dubboServiceMetadataRepository; private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
private final Logger logger = LoggerFactory.getLogger(getClass());
private final ApplicationEventPublisher applicationEventPublisher; private final ApplicationEventPublisher applicationEventPublisher;
private final ObjectProvider<DiscoveryClient> discoveryClient; private final DiscoveryClient discoveryClient;
public DubboServiceDiscoveryAutoConfiguration(DubboServiceMetadataRepository dubboServiceMetadataRepository, public DubboServiceDiscoveryAutoConfiguration(DubboServiceMetadataRepository dubboServiceMetadataRepository,
ApplicationEventPublisher applicationEventPublisher, ApplicationEventPublisher applicationEventPublisher,
ObjectProvider<DiscoveryClient> discoveryClient) { DiscoveryClient discoveryClient) {
this.dubboServiceMetadataRepository = dubboServiceMetadataRepository; this.dubboServiceMetadataRepository = dubboServiceMetadataRepository;
this.applicationEventPublisher = applicationEventPublisher; this.applicationEventPublisher = applicationEventPublisher;
this.discoveryClient = discoveryClient; this.discoveryClient = discoveryClient;
} }
private void forEachSubscribedServices(Consumer<String> serviceNameConsumer) {
dubboServiceMetadataRepository.getSubscribedServices().forEach(serviceNameConsumer);
}
/** /**
* Dispatch a {@link ServiceInstancesChangedEvent} * Dispatch a {@link ServiceInstancesChangedEvent}
* *
@ -85,14 +106,19 @@ public class DubboServiceDiscoveryAutoConfiguration {
* @param serviceInstances the {@link ServiceInstance instances} of some service * @param serviceInstances the {@link ServiceInstance instances} of some service
* @see AbstractSpringCloudRegistry#registerServiceInstancesChangedEventListener(URL, NotifyListener) * @see AbstractSpringCloudRegistry#registerServiceInstancesChangedEventListener(URL, NotifyListener)
*/ */
protected void dispatchServiceInstancesChangedEvent(String serviceName, Collection<ServiceInstance> serviceInstances) { private void dispatchServiceInstancesChangedEvent(String serviceName, Collection<ServiceInstance> serviceInstances) {
if (!hasText(serviceName) || isEmpty(serviceInstances)) { if (!hasText(serviceName) || serviceInstances == null) {
return; return;
} }
ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent(serviceName, serviceInstances); ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent(serviceName, serviceInstances);
applicationEventPublisher.publishEvent(event); applicationEventPublisher.publishEvent(event);
} }
private List<ServiceInstance> getInstances(String serviceName) {
return discoveryClient.getInstances(serviceName);
}
@Configuration @Configuration
@ConditionalOnBean(name = EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME) @ConditionalOnBean(name = EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME)
class EurekaConfiguration { class EurekaConfiguration {
@ -109,20 +135,96 @@ public class DubboServiceDiscoveryAutoConfiguration {
*/ */
@EventListener(HeartbeatEvent.class) @EventListener(HeartbeatEvent.class)
public void onHeartbeatEvent(HeartbeatEvent event) { public void onHeartbeatEvent(HeartbeatEvent event) {
discoveryClient.ifAvailable(discoveryClient -> { forEachSubscribedServices(serviceName -> {
dubboServiceMetadataRepository.getSubscribedServices().forEach(serviceName -> { List<ServiceInstance> serviceInstances = getInstances(serviceName);
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName); dispatchServiceInstancesChangedEvent(serviceName, serviceInstances);
dispatchServiceInstancesChangedEvent(serviceName, serviceInstances);
});
}); });
} }
} }
@Configuration @Configuration
@ConditionalOnBean(name = ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME) @ConditionalOnBean(name = ZOOKEEPER_DISCOVERY_AUTO_CONFIGURATION_CLASS_NAME)
class ZookeeperConfiguration { class ZookeeperConfiguration {
/**
* The Key is watched Zookeeper path, the value is an instance of {@link CuratorWatcher}
*/
private final Map<String, CuratorWatcher> watcherCaches = new ConcurrentHashMap<>();
private final ZookeeperDiscoveryProperties zookeeperDiscoveryProperties;
private final ObjectProvider<ZookeeperDependencies> zookeeperDependencies;
private final CuratorFramework curatorFramework;
private final String rootPath;
ZookeeperConfiguration(ZookeeperDiscoveryProperties zookeeperDiscoveryProperties,
ObjectProvider<ZookeeperDependencies> zookeeperDependencies,
CuratorFramework curatorFramework) {
this.zookeeperDiscoveryProperties = zookeeperDiscoveryProperties;
this.zookeeperDependencies = zookeeperDependencies;
this.curatorFramework = curatorFramework;
this.rootPath = zookeeperDiscoveryProperties.getRoot();
}
@EventListener(ContextRefreshedEvent.class)
public void onContextRefreshedEvent(ContextRefreshedEvent event) {
forEachSubscribedServices(this::registerServiceWatcher);
}
private void registerServiceWatcher(String serviceName) {
String servicePath = buildServicePath(serviceName);
CuratorWatcher watcher = watcherCaches.computeIfAbsent(servicePath,
path -> new ServiceInstancesChangedWatcher(serviceName));
try {
curatorFramework.getChildren().usingWatcher(watcher).forPath(servicePath);
} catch (KeeperException.NoNodeException e) {
// ignored
if (logger.isErrorEnabled()) {
logger.error(e.getMessage());
}
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
class ServiceInstancesChangedWatcher implements CuratorWatcher {
private final String serviceName;
ServiceInstancesChangedWatcher(String serviceName) {
this.serviceName = serviceName;
}
@Override
public void process(WatchedEvent event) throws Exception {
Watcher.Event.EventType eventType = event.getType();
if (NodeChildrenChanged.equals(eventType) || NodeDataChanged.equals(eventType)) {
dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
}
// re-register again
registerServiceWatcher(serviceName);
}
}
private String buildServicePath(String serviceName) {
return rootPath + "/" + serviceRelativePath(serviceName);
}
private String serviceRelativePath(String serviceName) {
return Optional.ofNullable(zookeeperDependencies.getIfAvailable())
.map(z -> z.getAliasForPath(serviceName))
.orElse(serviceName);
}
} }
@Configuration @Configuration

View File

@ -46,7 +46,7 @@ public class DubboMetadataInitializerInterceptor implements ClientHttpRequestInt
String serviceName = originalUri.getHost(); String serviceName = originalUri.getHost();
repository.initialize(serviceName); repository.initializeMetadata(serviceName);
// Execute next // Execute next
return execution.execute(request, body); return execution.execute(request, body);

View File

@ -31,6 +31,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.type.TypeFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.ServiceInstance;
@ -38,12 +39,10 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.commons.util.InetUtils; import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -74,7 +73,7 @@ import static org.springframework.util.StringUtils.hasText;
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a> * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
*/ */
@Repository @Repository
public class DubboServiceMetadataRepository { public class DubboServiceMetadataRepository implements SmartInitializingSingleton {
/** /**
* The prefix of {@link DubboMetadataService} : "dubbo.metadata-service." * The prefix of {@link DubboMetadataService} : "dubbo.metadata-service."
@ -95,6 +94,16 @@ public class DubboServiceMetadataRepository {
private final ObjectMapper objectMapper = new ObjectMapper(); private final ObjectMapper objectMapper = new ObjectMapper();
/**
* Monitor object for synchronization
*/
private final Object monitor = new Object();
/**
* A {@link Set} of service names that had been initialized
*/
private final Set<String> initializedServices = new LinkedHashSet<>();
// =================================== Registration =================================== // // =================================== Registration =================================== //
/** /**
@ -108,7 +117,7 @@ public class DubboServiceMetadataRepository {
// =================================== Subscription =================================== // // =================================== Subscription =================================== //
private Set<String> subscribedServices; private Set<String> subscribedServices = emptySet();
/** /**
* The subscribed {@link URL urls} {@link Map} of {@link DubboMetadataService}, * The subscribed {@link URL urls} {@link Map} of {@link DubboMetadataService},
@ -162,13 +171,47 @@ public class DubboServiceMetadataRepository {
// ==================================================================================== // // ==================================================================================== //
@PostConstruct @PostConstruct
public void init() { public void init() {
// Keep the order in following invocations
initSubscribedServices(); initSubscribedServices();
initSubscribedDubboMetadataServices(); }
initDubboRestServiceMetadataRepository();
@Override
public void afterSingletonsInstantiated() {
initializeMetadata();
}
/**
* Initialize the metadata
*/
private void initializeMetadata() {
subscribedServices.forEach(this::initializeMetadata);
if (logger.isInfoEnabled()) {
logger.info("The metadata of Dubbo services has been initialized");
}
}
/**
* Initialize the metadata of Dubbo Services
*/
public void initializeMetadata(String serviceName) {
synchronized (monitor) {
if (initializedServices.contains(serviceName)) {
if (logger.isDebugEnabled()) {
logger.debug("The metadata of Dubbo service[name : {}] has been initialized", serviceName);
}
} else {
if (logger.isInfoEnabled()) {
logger.info("The metadata of Dubbo service[name : {}] is about to be initialized", serviceName);
}
// Keep the order in following invocations
initSubscribedDubboMetadataService(serviceName);
initDubboRestServiceMetadataRepository(serviceName);
// mark this service name having been initialized
initializedServices.add(serviceName);
}
}
} }
/** /**
@ -245,19 +288,15 @@ public class DubboServiceMetadataRepository {
return unmodifiableSet(serviceRestMetadata); return unmodifiableSet(serviceRestMetadata);
} }
// /**
// * Get The subscribed {@link DubboMetadataService}'s {@link URL URLs}
// *
// * @return non-null read-only {@link List}
// */
// public List<URL> getSubscribedDubboMetadataServiceURLs() {
// return Collections.unmodifiableList(subscribedDubboMetadataServiceURLs);
// }
public List<URL> findSubscribedDubboMetadataServiceURLs(String serviceName, String group, String version, public List<URL> findSubscribedDubboMetadataServiceURLs(String serviceName, String group, String version,
String protocol) { String protocol) {
String serviceKey = URL.buildKey(serviceName, group, version); String serviceKey = URL.buildKey(serviceName, group, version);
List<URL> urls = subscribedDubboMetadataServiceURLs.get(serviceKey);
List<URL> urls = null;
synchronized (monitor) {
urls = subscribedDubboMetadataServiceURLs.get(serviceKey);
}
if (isEmpty(urls)) { if (isEmpty(urls)) {
return emptyList(); return emptyList();
@ -348,7 +387,7 @@ public class DubboServiceMetadataRepository {
* *
* @param serviceName the service name * @param serviceName the service name
*/ */
public void initialize(String serviceName) { protected void initDubboRestServiceMetadataRepository(String serviceName) {
if (dubboRestServiceMetadataRepository.containsKey(serviceName)) { if (dubboRestServiceMetadataRepository.containsKey(serviceName)) {
return; return;
@ -501,23 +540,26 @@ public class DubboServiceMetadataRepository {
subscribedServices.remove(currentApplicationName); subscribedServices.remove(currentApplicationName);
} }
private void initSubscribedDubboMetadataServices() { protected void initSubscribedDubboMetadataService(String serviceName) {
// clear subscribedDubboMetadataServiceURLs discoveryClient.getInstances(serviceName)
subscribedDubboMetadataServiceURLs.clear(); .stream()
.findAny()
subscribedServices.stream() .map(this::getDubboMetadataServiceURLs)
.map(discoveryClient::getInstances) .ifPresent(dubboMetadataServiceURLs -> {
.filter(this::isNotEmpty) dubboMetadataServiceURLs.forEach(dubboMetadataServiceURL -> {
.forEach(serviceInstances -> { try {
ServiceInstance serviceInstance = serviceInstances.get(0); initSubscribedDubboMetadataServiceURL(dubboMetadataServiceURL);
getDubboMetadataServiceURLs(serviceInstance).forEach(dubboMetadataServiceURL -> { initDubboMetadataServiceProxy(dubboMetadataServiceURL);
initSubscribedDubboMetadataServiceURLs(dubboMetadataServiceURL); } catch (Throwable e) {
initDubboMetadataServiceProxy(dubboMetadataServiceURL); if (logger.isErrorEnabled()) {
logger.error(e.getMessage(), e);
}
}
}); });
}); });
} }
private void initSubscribedDubboMetadataServiceURLs(URL dubboMetadataServiceURL) { private void initSubscribedDubboMetadataServiceURL(URL dubboMetadataServiceURL) {
// add subscriptions // add subscriptions
String serviceKey = dubboMetadataServiceURL.getServiceKey(); String serviceKey = dubboMetadataServiceURL.getServiceKey();
subscribedDubboMetadataServiceURLs.add(serviceKey, dubboMetadataServiceURL); subscribedDubboMetadataServiceURLs.add(serviceKey, dubboMetadataServiceURL);
@ -529,12 +571,4 @@ public class DubboServiceMetadataRepository {
// Initialize DubboMetadataService with right version // Initialize DubboMetadataService with right version
dubboMetadataConfigServiceProxy.initProxy(serviceName, version); dubboMetadataConfigServiceProxy.initProxy(serviceName, version);
} }
private void initDubboRestServiceMetadataRepository() {
subscribedServices.forEach(this::initialize);
}
private boolean isNotEmpty(Collection collection) {
return !CollectionUtils.isEmpty(collection);
}
} }

View File

@ -19,10 +19,6 @@ package com.alibaba.cloud.dubbo.openfeign;
import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.service.GenericService;
import feign.Contract;
import feign.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.cloud.dubbo.annotation.DubboTransported; import com.alibaba.cloud.dubbo.annotation.DubboTransported;
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata; import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
import com.alibaba.cloud.dubbo.metadata.DubboTransportedMethodMetadata; import com.alibaba.cloud.dubbo.metadata.DubboTransportedMethodMetadata;
@ -33,6 +29,10 @@ import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepositor
import com.alibaba.cloud.dubbo.metadata.resolver.DubboTransportedMethodMetadataResolver; import com.alibaba.cloud.dubbo.metadata.resolver.DubboTransportedMethodMetadataResolver;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory; import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory; import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
import feign.Contract;
import feign.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FeignContext; import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
@ -132,7 +132,7 @@ class TargeterInvocationHandler implements InvocationHandler {
} }
// Update Metadata // Update Metadata
repository.initialize(serviceName); repository.initializeMetadata(serviceName);
Map<Method, FeignMethodMetadata> feignMethodMetadataMap = getFeignMethodMetadataMap(serviceName, feignRestMethodMetadataMap); Map<Method, FeignMethodMetadata> feignMethodMetadataMap = getFeignMethodMetadataMap(serviceName, feignRestMethodMetadataMap);

View File

@ -37,8 +37,6 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -178,7 +176,12 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
@Override @Override
public void onApplicationEvent(ServiceInstancesChangedEvent event) { public void onApplicationEvent(ServiceInstancesChangedEvent event) {
String serviceName = event.getServiceName(); String serviceName = event.getServiceName();
subscribeDubboServiceURLs(url, listener, serviceName, s -> event.getServiceInstances()); Collection<ServiceInstance> serviceInstances = event.getServiceInstances();
if (logger.isInfoEnabled()) {
logger.info("The event of the service instances[name : {} , size: {}] changed has been arrived",
serviceName, serviceInstances.size());
}
subscribeDubboServiceURLs(url, listener, serviceName, s -> serviceInstances);
} }
}); });
} }
@ -193,39 +196,54 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
protected void subscribeDubboServiceURLs(URL url, NotifyListener listener, String serviceName, protected void subscribeDubboServiceURLs(URL url, NotifyListener listener, String serviceName,
Function<String, Collection<ServiceInstance>> serviceInstancesFunction) { Function<String, Collection<ServiceInstance>> serviceInstancesFunction) {
Optional.ofNullable(serviceName)
.map(dubboMetadataConfigServiceProxy::getProxy)
.filter(Objects::nonNull)
.ifPresent(dubboMetadataService -> {
List<URL> exportedURLs = getExportedURLs(dubboMetadataService, url);
List<URL> allSubscribedURLs = new LinkedList<>();
for (URL exportedURL : exportedURLs) {
Collection<ServiceInstance> serviceInstances = serviceInstancesFunction.apply(serviceName);
String protocol = exportedURL.getProtocol();
List<URL> subscribedURLs = new LinkedList<>();
serviceInstances.forEach(serviceInstance -> {
Integer port = repository.getDubboProtocolPort(serviceInstance, protocol);
String host = serviceInstance.getHost();
if (port == null) {
if (logger.isWarnEnabled()) {
logger.warn("The protocol[{}] port of Dubbo service instance[host : {}] " +
"can't be resolved", protocol, host);
}
} else {
URL subscribedURL = new URL(protocol, host, port, exportedURL.getParameters());
subscribedURLs.add(subscribedURL);
}
});
if (logger.isDebugEnabled()) { DubboMetadataService dubboMetadataService = dubboMetadataConfigServiceProxy.getProxy(serviceName);
logger.debug("The subscribed URL[{}] will notify all URLs : {}", url, subscribedURLs);
}
allSubscribedURLs.addAll(subscribedURLs); if (dubboMetadataService == null) { // If not found, try to initialize
if (logger.isInfoEnabled()) {
logger.info("The metadata of Dubbo service[key : {}] can't be found when the subscribed service[name : {}], " +
"and then try to initialize it", url.getServiceKey(), serviceName);
}
repository.initializeMetadata(serviceName);
dubboMetadataService = dubboMetadataConfigServiceProxy.getProxy(serviceName);
}
if (dubboMetadataService == null) { // It makes sure not-found, return immediately
if (logger.isWarnEnabled()) {
logger.warn("The metadata of Dubbo service[key : {}] still can't be found, it could effect the further " +
"Dubbo service invocation", url.getServiceKey());
}
return;
}
List<URL> exportedURLs = getExportedURLs(dubboMetadataService, url);
List<URL> allSubscribedURLs = new LinkedList<>();
for (URL exportedURL : exportedURLs) {
Collection<ServiceInstance> serviceInstances = serviceInstancesFunction.apply(serviceName);
String protocol = exportedURL.getProtocol();
List<URL> subscribedURLs = new LinkedList<>();
serviceInstances.forEach(serviceInstance -> {
Integer port = repository.getDubboProtocolPort(serviceInstance, protocol);
String host = serviceInstance.getHost();
if (port == null) {
if (logger.isWarnEnabled()) {
logger.warn("The protocol[{}] port of Dubbo service instance[host : {}] " +
"can't be resolved", protocol, host);
} }
} else {
URL subscribedURL = new URL(protocol, host, port, exportedURL.getParameters());
subscribedURLs.add(subscribedURL);
}
});
listener.notify(allSubscribedURLs); if (logger.isDebugEnabled()) {
}); logger.debug("The subscribed URL[{}] will notify all URLs : {}", url, subscribedURLs);
}
allSubscribedURLs.addAll(subscribedURLs);
}
listener.notify(allSubscribedURLs);
} }
private List<ServiceInstance> getServiceInstances(String serviceName) { private List<ServiceInstance> getServiceInstances(String serviceName) {
@ -286,5 +304,4 @@ public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
protected boolean isDubboMetadataServiceURL(URL url) { protected boolean isDubboMetadataServiceURL(URL url) {
return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface()); return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
} }
} }

View File

@ -16,12 +16,12 @@
*/ */
package com.alibaba.cloud.dubbo.bootstrap; package com.alibaba.cloud.dubbo.bootstrap;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
import java.util.HashMap;
import java.util.Map;
import org.apache.dubbo.config.annotation.Reference; import org.apache.dubbo.config.annotation.Reference;
import com.alibaba.cloud.dubbo.annotation.DubboTransported;
import com.alibaba.cloud.dubbo.service.RestService;
import com.alibaba.cloud.dubbo.service.User;
import com.alibaba.cloud.dubbo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
@ -41,10 +41,10 @@ import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import com.alibaba.cloud.dubbo.annotation.DubboTransported; import java.util.HashMap;
import com.alibaba.cloud.dubbo.service.RestService; import java.util.Map;
import com.alibaba.cloud.dubbo.service.User;
import com.alibaba.cloud.dubbo.service.UserService; import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
/** /**
* Dubbo Spring Cloud Consumer Bootstrap * Dubbo Spring Cloud Consumer Bootstrap
@ -172,7 +172,7 @@ public class DubboSpringCloudConsumerBootstrap {
// Spring Cloud Open Feign REST Call (Dubbo Transported) // Spring Cloud Open Feign REST Call (Dubbo Transported)
System.out.println(dubboFeignRestService.pathVariables("c", "b", "a")); System.out.println(dubboFeignRestService.pathVariables("c", "b", "a"));
// Spring Cloud Open Feign REST Call // Spring Cloud Open Feign REST Call
System.out.println(feignRestService.pathVariables("b", "a", "c")); // System.out.println(feignRestService.pathVariables("b", "a", "c"));
// RestTemplate call // RestTemplate call
System.out.println(restTemplate.getForEntity( System.out.println(restTemplate.getForEntity(
@ -186,7 +186,7 @@ public class DubboSpringCloudConsumerBootstrap {
// Spring Cloud Open Feign REST Call (Dubbo Transported) // Spring Cloud Open Feign REST Call (Dubbo Transported)
System.out.println(dubboFeignRestService.headers("b", 10, "a")); System.out.println(dubboFeignRestService.headers("b", 10, "a"));
// Spring Cloud Open Feign REST Call // Spring Cloud Open Feign REST Call
System.out.println(feignRestService.headers("b", "a", 10)); // System.out.println(feignRestService.headers("b", "a", 10));
} }
private void callParam() { private void callParam() {
@ -195,7 +195,7 @@ public class DubboSpringCloudConsumerBootstrap {
// Spring Cloud Open Feign REST Call (Dubbo Transported) // Spring Cloud Open Feign REST Call (Dubbo Transported)
System.out.println(dubboFeignRestService.param("mercyblitz")); System.out.println(dubboFeignRestService.param("mercyblitz"));
// Spring Cloud Open Feign REST Call // Spring Cloud Open Feign REST Call
System.out.println(feignRestService.param("mercyblitz")); // System.out.println(feignRestService.param("mercyblitz"));
} }
private void callParams() { private void callParams() {
@ -204,7 +204,7 @@ public class DubboSpringCloudConsumerBootstrap {
// Spring Cloud Open Feign REST Call (Dubbo Transported) // Spring Cloud Open Feign REST Call (Dubbo Transported)
System.out.println(dubboFeignRestService.params("1", 1)); System.out.println(dubboFeignRestService.params("1", 1));
// Spring Cloud Open Feign REST Call // Spring Cloud Open Feign REST Call
System.out.println(feignRestService.params("1", 1)); // System.out.println(feignRestService.params("1", 1));
// RestTemplate call // RestTemplate call
System.out.println(restTemplate.getForEntity( System.out.println(restTemplate.getForEntity(
@ -223,7 +223,7 @@ public class DubboSpringCloudConsumerBootstrap {
// Spring Cloud Open Feign REST Call (Dubbo Transported) // Spring Cloud Open Feign REST Call (Dubbo Transported)
System.out.println(dubboFeignRestService.requestBody("Hello,World", data)); System.out.println(dubboFeignRestService.requestBody("Hello,World", data));
// Spring Cloud Open Feign REST Call // Spring Cloud Open Feign REST Call
System.out.println(feignRestService.requestBody("Hello,World", data)); // System.out.println(feignRestService.requestBody("Hello,World", data));
// RestTemplate call // RestTemplate call
System.out.println(restTemplate.postForObject( System.out.println(restTemplate.postForObject(

View File

@ -1,9 +1,29 @@
package com.alibaba.cloud.dubbo.gateway; package com.alibaba.cloud.dubbo.gateway;
import static org.apache.commons.lang3.StringUtils.substringAfter; import org.apache.dubbo.rpc.service.GenericException;
import static org.apache.commons.lang3.StringUtils.substringBetween; import org.apache.dubbo.rpc.service.GenericService;
import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
import com.alibaba.cloud.dubbo.http.MutableHttpServerRequest;
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
import com.alibaba.cloud.dubbo.metadata.RequestMetadata;
import com.alibaba.cloud.dubbo.metadata.RestMethodMetadata;
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContext;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StreamUtils;
import org.springframework.web.servlet.HttpServletBean;
import org.springframework.web.util.UriComponents;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -15,30 +35,9 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletException; import static org.apache.commons.lang3.StringUtils.substringAfter;
import javax.servlet.ServletInputStream; import static org.apache.commons.lang3.StringUtils.substringBetween;
import javax.servlet.annotation.WebServlet; import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.dubbo.rpc.service.GenericException;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StreamUtils;
import org.springframework.web.servlet.HttpServletBean;
import org.springframework.web.util.UriComponents;
import com.alibaba.cloud.dubbo.http.MutableHttpServerRequest;
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
import com.alibaba.cloud.dubbo.metadata.RequestMetadata;
import com.alibaba.cloud.dubbo.metadata.RestMethodMetadata;
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContext;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceExecutionContextFactory;
import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
@WebServlet(urlPatterns = "/dsc/*") @WebServlet(urlPatterns = "/dsc/*")
public class DubboGatewayServlet extends HttpServletBean { public class DubboGatewayServlet extends HttpServletBean {
@ -86,7 +85,7 @@ public class DubboGatewayServlet extends HttpServletBean {
String restPath = substringAfter(request.getRequestURI(), serviceName); String restPath = substringAfter(request.getRequestURI(), serviceName);
// 初始化 serviceName REST 请求元数据 // 初始化 serviceName REST 请求元数据
repository.initialize(serviceName); repository.initializeMetadata(serviceName);
// HttpServletRequest 转化为 RequestMetadata // HttpServletRequest 转化为 RequestMetadata
RequestMetadata clientMetadata = buildRequestMetadata(request, restPath); RequestMetadata clientMetadata = buildRequestMetadata(request, restPath);