From fd8a6a6f6c262cbf8d20c049c84cd445651bd969 Mon Sep 17 00:00:00 2001 From: theonefx Date: Fri, 8 Jan 2021 15:42:03 +0800 Subject: [PATCH 1/3] #1805 use twice registry of dubbo --- ...oServiceRegistrationAutoConfiguration.java | 86 +++++++++++++------ ...viceRegistrationEventPublishingAspect.java | 27 ++++-- .../ServiceInstancePreDeregisteredEvent.java | 49 +++++++++++ .../ServiceInstancePreRegisteredEvent.java | 10 ++- 4 files changed, 137 insertions(+), 35 deletions(-) create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreDeregisteredEvent.java diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java index 6fca3f2ad..c1d23cb11 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java @@ -17,18 +17,21 @@ package com.alibaba.cloud.dubbo.autoconfigure; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import com.alibaba.cloud.dubbo.autoconfigure.condition.MissingSpringCloudRegistryConfigPropertyCondition; import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository; import com.alibaba.cloud.dubbo.registry.DubboServiceRegistrationEventPublishingAspect; +import com.alibaba.cloud.dubbo.registry.event.ServiceInstancePreDeregisteredEvent; import com.alibaba.cloud.dubbo.registry.event.ServiceInstancePreRegisteredEvent; import com.ecwid.consul.v1.agent.model.NewService; import com.netflix.appinfo.InstanceInfo; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.spring.ServiceBean; -import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,6 +45,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; @@ -51,7 +55,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.context.event.ApplicationContextEvent; import org.springframework.context.event.EventListener; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.CONSUL_AUTO_SERVICE_AUTO_CONFIGURATION_CLASS_NAME; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; @@ -106,10 +113,33 @@ public class DubboServiceRegistrationAutoConfiguration { return new RegistryConfig(ADDRESS, PROTOCOL); } + private Map, Set> registrations = new ConcurrentHashMap<>(); + + @Order + @EventListener(ApplicationContextEvent.class) + public void attachDubboMetadataAndRegistAgain(ApplicationContextEvent event) { + registrations.forEach( + (registry, registrations) -> registrations.forEach(registration -> { + attachDubboMetadataServiceMetadata(registration); + registry.register(registration); + })); + } + @EventListener(ServiceInstancePreRegisteredEvent.class) public void onServiceInstancePreRegistered(ServiceInstancePreRegisteredEvent event) { Registration registration = event.getSource(); - attachDubboMetadataServiceMetadata(registration); + ServiceRegistry registry = event.getRegistry(); + synchronized (registry) { + registrations.putIfAbsent(registry, new HashSet<>()); + registrations.get(registry).add(registration); + } + } + + @EventListener(ServiceInstancePreDeregisteredEvent.class) + public void onServiceInstancePreDeregistered( + ServiceInstancePreDeregisteredEvent event) { + ServiceRegistry registry = event.getRegistry(); + registrations.remove(registry); } private void attachDubboMetadataServiceMetadata(Registration registration) { @@ -132,21 +162,19 @@ public class DubboServiceRegistrationAutoConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnBean(name = EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME) - @Aspect class EurekaConfiguration implements SmartInitializingSingleton { @Autowired private ObjectProvider> serviceBeans; - @EventListener(ServiceInstancePreRegisteredEvent.class) - public void onServiceInstancePreRegistered( - ServiceInstancePreRegisteredEvent event) { - Registration registration = event.getSource(); - EurekaRegistration eurekaRegistration = EurekaRegistration.class - .cast(registration); - InstanceInfo instanceInfo = eurekaRegistration.getApplicationInfoManager() - .getInfo(); - attachDubboMetadataServiceMetadata(instanceInfo.getMetadata()); + @Order(Ordered.LOWEST_PRECEDENCE - 1) + @EventListener(ApplicationContextEvent.class) + public void onServiceInstancePreRegistered(ApplicationContextEvent event) { + registrations.forEach((registry, registrations)-> registrations.forEach(registration -> { + EurekaRegistration eurekaRegistration = (EurekaRegistration) registration; + InstanceInfo instanceInfo = eurekaRegistration.getApplicationInfoManager().getInfo(); + attachDubboMetadataServiceMetadata(instanceInfo.getMetadata()); + })); } /** @@ -171,21 +199,25 @@ public class DubboServiceRegistrationAutoConfiguration { @AutoConfigureOrder class ConsulConfiguration { - /** - * Handle the pre-registered event of {@link ServiceInstance} for Consul. - * @param event {@link ServiceInstancePreRegisteredEvent} - */ - @EventListener(ServiceInstancePreRegisteredEvent.class) - public void onServiceInstancePreRegistered( - ServiceInstancePreRegisteredEvent event) { - Registration registration = event.getSource(); - Class registrationClass = AopUtils.getTargetClass(registration); - String registrationClassName = registrationClass.getName(); - if (CONSUL_AUTO_SERVICE_AUTO_REGISTRATION_CLASS_NAME - .equalsIgnoreCase(registrationClassName)) { - ConsulRegistration consulRegistration = (ConsulRegistration) registration; - attachURLsIntoMetadata(consulRegistration); - } + @Order(Ordered.LOWEST_PRECEDENCE - 1) + @EventListener(ApplicationContextEvent.class) + public void attachURLsIntoMetadataBeforeReRegist(ApplicationContextEvent event) { + registrations.entrySet().removeIf(entry -> { + Set registrations = entry.getValue(); + registrations.removeIf(registration -> { + Class registrationClass = AopUtils.getTargetClass(registration); + String registrationClassName = registrationClass.getName(); + return !CONSUL_AUTO_SERVICE_AUTO_REGISTRATION_CLASS_NAME + .equalsIgnoreCase(registrationClassName); + }); + return registrations.isEmpty(); + }); + + registrations.forEach( + (registry, registrations) -> registrations.forEach(registration -> { + ConsulRegistration consulRegistration = (ConsulRegistration) registration; + attachURLsIntoMetadata(consulRegistration); + })); } private void attachURLsIntoMetadata(ConsulRegistration consulRegistration) { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java index 43e679f53..8cd5c6b7d 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java @@ -16,6 +16,7 @@ package com.alibaba.cloud.dubbo.registry; +import com.alibaba.cloud.dubbo.registry.event.ServiceInstancePreDeregisteredEvent; import com.alibaba.cloud.dubbo.registry.event.ServiceInstancePreRegisteredEvent; import com.alibaba.cloud.dubbo.registry.event.ServiceInstanceRegisteredEvent; import org.aspectj.lang.annotation.After; @@ -33,6 +34,7 @@ import org.springframework.context.ApplicationEventPublisherAware; * @author Mercy * @see ServiceInstancePreRegisteredEvent * @see ServiceInstanceRegisteredEvent + * @see ServiceInstancePreDeregisteredEvent */ @Aspect public class DubboServiceRegistrationEventPublishingAspect @@ -41,18 +43,29 @@ public class DubboServiceRegistrationEventPublishingAspect /** * The pointcut expression for {@link ServiceRegistry#register(Registration)}. */ - public static final String REGISTER_POINTCUT_EXPRESSION = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(*)) && args(registration)"; + public static final String REGISTER_POINTCUT_EXPRESSION = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(*)) && target(registry) && args(registration)"; + + /** + * The pointcut expression for {@link ServiceRegistry#deregister(Registration)}. + */ + public static final String DEREGISTER_POINTCUT_EXPRESSION = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.deregister(*)) && target(registry) && args(registration)"; private ApplicationEventPublisher applicationEventPublisher; - @Before(REGISTER_POINTCUT_EXPRESSION) - public void beforeRegister(Registration registration) { - applicationEventPublisher - .publishEvent(new ServiceInstancePreRegisteredEvent(registration)); + @Before(value = REGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration") + public void beforeRegister(ServiceRegistry registry, Registration registration) { + applicationEventPublisher.publishEvent( + new ServiceInstancePreRegisteredEvent(registry, registration)); + } + + @Before(value = DEREGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration") + public void beforeDeregister(ServiceRegistry registry, Registration registration) { + applicationEventPublisher.publishEvent( + new ServiceInstancePreDeregisteredEvent(registry, registration)); } - @After(REGISTER_POINTCUT_EXPRESSION) - public void afterRegister(Registration registration) { + @After(value = REGISTER_POINTCUT_EXPRESSION, argNames = "registry, registration") + public void afterRegister(ServiceRegistry registry, Registration registration) { applicationEventPublisher .publishEvent(new ServiceInstanceRegisteredEvent(registration)); } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreDeregisteredEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreDeregisteredEvent.java new file mode 100644 index 000000000..5e60be5b9 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreDeregisteredEvent.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed 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 + * + * https://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 com.alibaba.cloud.dubbo.registry.event; + +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; +import org.springframework.context.ApplicationEvent; + +/** + * The + * before-{@link org.springframework.cloud.client.serviceregistry.ServiceRegistry#register(org.springframework.cloud.client.serviceregistry.Registration) + * register} event for {@link org.springframework.cloud.client.ServiceInstance}. + * + * @author Mercy + */ +public class ServiceInstancePreDeregisteredEvent extends ApplicationEvent { + + private final ServiceRegistry registry; + + public ServiceInstancePreDeregisteredEvent(ServiceRegistry registry, + Registration source) { + super(source); + this.registry = registry; + } + + @Override + public Registration getSource() { + return (Registration) super.getSource(); + } + + public ServiceRegistry getRegistry() { + return registry; + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreRegisteredEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreRegisteredEvent.java index 4733fef69..e1b905c04 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreRegisteredEvent.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/event/ServiceInstancePreRegisteredEvent.java @@ -29,8 +29,12 @@ import org.springframework.context.ApplicationEvent; */ public class ServiceInstancePreRegisteredEvent extends ApplicationEvent { - public ServiceInstancePreRegisteredEvent(Registration source) { + private final ServiceRegistry registry; + + public ServiceInstancePreRegisteredEvent(ServiceRegistry registry, + Registration source) { super(source); + this.registry = registry; } @Override @@ -38,4 +42,8 @@ public class ServiceInstancePreRegisteredEvent extends ApplicationEvent { return (Registration) super.getSource(); } + public ServiceRegistry getRegistry() { + return registry; + } + } From 6c0edee13e32039bc2d65a3f959cd0b20e0468de Mon Sep 17 00:00:00 2001 From: theonefx Date: Mon, 11 Jan 2021 22:54:10 +0800 Subject: [PATCH 2/3] use starting status in eureka when first registry --- .../nacos/parser/NacosDataParserHandler.java | 8 +- .../nacos/registry/NacosServiceRegistry.java | 13 +-- ...oServiceRegistrationAutoConfiguration.java | 100 ++++++++++++++---- .../DubboBootstrapCommandLineRunner.java | 51 +++++++++ .../event/DubboBootstrapPreStartEvent.java | 35 ++++++ .../event/DubboBootstrapStartedEvent.java | 42 ++++++++ 6 files changed, 221 insertions(+), 28 deletions(-) create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboBootstrapCommandLineRunner.java create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapPreStartEvent.java create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapStartedEvent.java diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataParserHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataParserHandler.java index feea3582f..82ad817ce 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataParserHandler.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/parser/NacosDataParserHandler.java @@ -82,7 +82,7 @@ public final class NacosDataParserHandler { } NacosByteArrayResource nacosByteArrayResource = new NacosByteArrayResource( configValue.getBytes(), configName); - nacosByteArrayResource.setFilename(getFileName(configName , extension)); + nacosByteArrayResource.setFilename(getFileName(configName, extension)); List> propertySourceList = propertySourceLoader .load(configName, nacosByteArrayResource); if (CollectionUtils.isEmpty(propertySourceList)) { @@ -135,8 +135,8 @@ public final class NacosDataParserHandler { return DEFAULT_EXTENSION; } - private String getFileName(String name,String extension){ - if(StringUtils.isEmpty(extension)){ + private String getFileName(String name, String extension) { + if (StringUtils.isEmpty(extension)) { return name; } if (StringUtils.isEmpty(name)) { @@ -145,7 +145,7 @@ public final class NacosDataParserHandler { int idx = name.lastIndexOf(DOT); if (idx > 0 && idx < name.length() - 1) { String ext = name.substring(idx + 1); - if(extension.equalsIgnoreCase(ext)){ + if (extension.equalsIgnoreCase(ext)) { return name; } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java index 97ab73101..9a79a568f 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java @@ -40,11 +40,11 @@ import static org.springframework.util.ReflectionUtils.rethrowRuntimeException; * @author eshun */ public class NacosServiceRegistry implements ServiceRegistry { - + private static final String STATUS_UP = "UP"; - + private static final String STATUS_DOWN = "DOWN"; - + private static final Logger log = LoggerFactory.getLogger(NacosServiceRegistry.class); private final NacosDiscoveryProperties nacosDiscoveryProperties; @@ -123,7 +123,8 @@ public class NacosServiceRegistry implements ServiceRegistry { @Override public void setStatus(Registration registration, String status) { - if (!STATUS_UP.equalsIgnoreCase(status) && !STATUS_DOWN.equalsIgnoreCase(status)) { + if (!STATUS_UP.equalsIgnoreCase(status) + && !STATUS_DOWN.equalsIgnoreCase(status)) { log.warn("can't support status {},please choose UP or DOWN", status); return; } @@ -141,8 +142,8 @@ public class NacosServiceRegistry implements ServiceRegistry { try { Properties nacosProperties = nacosDiscoveryProperties.getNacosProperties(); - nacosServiceManager.getNamingMaintainService(nacosProperties) - .updateInstance(serviceId, nacosDiscoveryProperties.getGroup(), instance); + nacosServiceManager.getNamingMaintainService(nacosProperties).updateInstance( + serviceId, nacosDiscoveryProperties.getGroup(), instance); } catch (Exception e) { throw new RuntimeException("update nacos instance status fail", e); diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java index c1d23cb11..5861fdf06 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java @@ -24,6 +24,8 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import com.alibaba.cloud.dubbo.autoconfigure.condition.MissingSpringCloudRegistryConfigPropertyCondition; +import com.alibaba.cloud.dubbo.metadata.DubboBootstrapCommandLineRunner; +import com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapStartedEvent; import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository; import com.alibaba.cloud.dubbo.registry.DubboServiceRegistrationEventPublishingAspect; import com.alibaba.cloud.dubbo.registry.event.ServiceInstancePreDeregisteredEvent; @@ -31,6 +33,7 @@ import com.alibaba.cloud.dubbo.registry.event.ServiceInstancePreRegisteredEvent; import com.ecwid.consul.v1.agent.model.NewService; import com.netflix.appinfo.InstanceInfo; import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.config.spring.ServiceBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +50,7 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry; @@ -55,9 +59,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.event.ApplicationContextEvent; import org.springframework.context.event.EventListener; -import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.CONSUL_AUTO_SERVICE_AUTO_CONFIGURATION_CLASS_NAME; @@ -72,7 +74,8 @@ import static org.springframework.util.ObjectUtils.isEmpty; * @author Mercy */ @Configuration(proxyBeanMethods = false) -@Import({ DubboServiceRegistrationEventPublishingAspect.class }) +@Import({ DubboServiceRegistrationEventPublishingAspect.class, + DubboBootstrapCommandLineRunner.class }) @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) @AutoConfigureAfter(name = { EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME, @@ -116,8 +119,11 @@ public class DubboServiceRegistrationAutoConfiguration { private Map, Set> registrations = new ConcurrentHashMap<>(); @Order - @EventListener(ApplicationContextEvent.class) - public void attachDubboMetadataAndRegistAgain(ApplicationContextEvent event) { + @EventListener(DubboBootstrapStartedEvent.class) + public void attachDubboMetadataAndRegistAgain(DubboBootstrapStartedEvent event) { + if (!event.getSource().isReady() || !event.getSource().isStarted()) { + return; + } registrations.forEach( (registry, registrations) -> registrations.forEach(registration -> { attachDubboMetadataServiceMetadata(registration); @@ -128,11 +134,18 @@ public class DubboServiceRegistrationAutoConfiguration { @EventListener(ServiceInstancePreRegisteredEvent.class) public void onServiceInstancePreRegistered(ServiceInstancePreRegisteredEvent event) { Registration registration = event.getSource(); - ServiceRegistry registry = event.getRegistry(); - synchronized (registry) { - registrations.putIfAbsent(registry, new HashSet<>()); - registrations.get(registry).add(registration); + if (!DubboBootstrap.getInstance().isReady() + || !DubboBootstrap.getInstance().isStarted()) { + ServiceRegistry registry = event.getRegistry(); + synchronized (registry) { + registrations.putIfAbsent(registry, new HashSet<>()); + registrations.get(registry).add(registration); + } + } + else { + attachDubboMetadataServiceMetadata(registration); } + } @EventListener(ServiceInstancePreDeregisteredEvent.class) @@ -167,14 +180,62 @@ public class DubboServiceRegistrationAutoConfiguration { @Autowired private ObjectProvider> serviceBeans; - @Order(Ordered.LOWEST_PRECEDENCE - 1) - @EventListener(ApplicationContextEvent.class) - public void onServiceInstancePreRegistered(ApplicationContextEvent event) { - registrations.forEach((registry, registrations)-> registrations.forEach(registration -> { + @EventListener(DubboBootstrapStartedEvent.class) + public void onServiceInstancePreRegistered(DubboBootstrapStartedEvent event) { + DubboBootstrap bootstrap = event.getSource(); + if (!bootstrap.isReady() || !bootstrap.isStarted()) { + return; + } + registrations.forEach( + (registry, registrations) -> registrations.removeIf(registration -> { + if (!(registration instanceof EurekaRegistration)) { + return false; + } + EurekaRegistration eurekaRegistration = (EurekaRegistration) registration; + InstanceInfo instanceInfo = eurekaRegistration + .getApplicationInfoManager().getInfo(); + + EurekaInstanceConfigBean config = (EurekaInstanceConfigBean) eurekaRegistration + .getInstanceConfig(); + config.setInitialStatus(InstanceInfo.InstanceStatus.UP); + + attachDubboMetadataServiceMetadata(instanceInfo.getMetadata()); + eurekaRegistration.getApplicationInfoManager() + .registerAppMetadata(instanceInfo.getMetadata()); + eurekaRegistration.getApplicationInfoManager() + .setInstanceStatus(InstanceInfo.InstanceStatus.UP); + return true; + })); + } + + @EventListener(ServiceInstancePreRegisteredEvent.class) + public void onServiceInstancePreRegistered( + ServiceInstancePreRegisteredEvent event) { + Registration registration = event.getSource(); + if (!(registration instanceof EurekaRegistration)) { + return; + } + + if (DubboBootstrap.getInstance().isReady() + && DubboBootstrap.getInstance().isStarted()) { EurekaRegistration eurekaRegistration = (EurekaRegistration) registration; - InstanceInfo instanceInfo = eurekaRegistration.getApplicationInfoManager().getInfo(); + InstanceInfo instanceInfo = eurekaRegistration.getApplicationInfoManager() + .getInfo(); + + EurekaInstanceConfigBean config = (EurekaInstanceConfigBean) eurekaRegistration + .getInstanceConfig(); + config.setInitialStatus(InstanceInfo.InstanceStatus.UP); + attachDubboMetadataServiceMetadata(instanceInfo.getMetadata()); - })); + eurekaRegistration.getApplicationInfoManager() + .registerAppMetadata(instanceInfo.getMetadata()); + } + else { + EurekaRegistration eurekaRegistration = (EurekaRegistration) registration; + EurekaInstanceConfigBean config = (EurekaInstanceConfigBean) eurekaRegistration + .getInstanceConfig(); + config.setInitialStatus(InstanceInfo.InstanceStatus.STARTING); + } } /** @@ -199,9 +260,12 @@ public class DubboServiceRegistrationAutoConfiguration { @AutoConfigureOrder class ConsulConfiguration { - @Order(Ordered.LOWEST_PRECEDENCE - 1) - @EventListener(ApplicationContextEvent.class) - public void attachURLsIntoMetadataBeforeReRegist(ApplicationContextEvent event) { + @EventListener(DubboBootstrapStartedEvent.class) + public void attachURLsIntoMetadataBeforeReRegist( + DubboBootstrapStartedEvent event) { + if (!event.getSource().isReady() || !event.getSource().isStarted()) { + return; + } registrations.entrySet().removeIf(entry -> { Set registrations = entry.getValue(); registrations.removeIf(registration -> { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboBootstrapCommandLineRunner.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboBootstrapCommandLineRunner.java new file mode 100644 index 000000000..dc819d0e0 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboBootstrapCommandLineRunner.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed 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 + * + * https://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 com.alibaba.cloud.dubbo.metadata; + +import com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapStartedEvent; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.stereotype.Component; + +/** + * @see com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapPreStartEvent + * @see com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapStartedEvent + * @author theonefx + */ + +@Component +public class DubboBootstrapCommandLineRunner + implements CommandLineRunner, ApplicationEventPublisherAware { + + private ApplicationEventPublisher applicationEventPublisher; + + @Override + public void setApplicationEventPublisher( + ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } + + @Override + public void run(String... args) { + applicationEventPublisher.publishEvent( + new DubboBootstrapStartedEvent(DubboBootstrap.getInstance())); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapPreStartEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapPreStartEvent.java new file mode 100644 index 000000000..b38f0c843 --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapPreStartEvent.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed 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 + * + * https://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 com.alibaba.cloud.dubbo.metadata.event; + +import org.springframework.context.ApplicationEvent; + +/** + * @author theonefx + */ +public class DubboBootstrapPreStartEvent extends ApplicationEvent { + + /** + * Create a new {@code ApplicationEvent}. + * @param source the object on which the event initially occurred or with which the + * event is associated (never {@code null}) + */ + public DubboBootstrapPreStartEvent(Object source) { + super(source); + } + +} diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapStartedEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapStartedEvent.java new file mode 100644 index 000000000..c41996b8f --- /dev/null +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapStartedEvent.java @@ -0,0 +1,42 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed 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 + * + * https://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 com.alibaba.cloud.dubbo.metadata.event; + +import org.apache.dubbo.config.bootstrap.DubboBootstrap; + +import org.springframework.context.ApplicationEvent; + +/** + * @author theonefx + */ +public class DubboBootstrapStartedEvent extends ApplicationEvent { + + /** + * Create a new {@code ApplicationEvent}. + * @param source the object on which the event initially occurred or with which the + * event is associated (never {@code null}) + */ + public DubboBootstrapStartedEvent(Object source) { + super(source); + } + + @Override + public DubboBootstrap getSource() { + return (DubboBootstrap) super.getSource(); + } + +} From eea48c73cccb7174bc3f83fe6a36ef79c6d9c90d Mon Sep 17 00:00:00 2001 From: theonefx Date: Tue, 12 Jan 2021 09:47:44 +0800 Subject: [PATCH 3/3] refactor method and class name --- ...oServiceRegistrationAutoConfiguration.java | 22 ++++++------ ...DubboBootstrapStartCommandLineRunner.java} | 13 ++++--- .../DubboBootstrapWrapper.java} | 34 +++++++++++++------ .../event/DubboBootstrapStartedEvent.java | 14 ++++---- 4 files changed, 48 insertions(+), 35 deletions(-) rename spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/{metadata/DubboBootstrapCommandLineRunner.java => bootstrap/DubboBootstrapStartCommandLineRunner.java} (75%) rename spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/{metadata/event/DubboBootstrapPreStartEvent.java => bootstrap/DubboBootstrapWrapper.java} (52%) rename spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/{metadata => bootstrap}/event/DubboBootstrapStartedEvent.java (71%) diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java index 5861fdf06..b0897e6ca 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java @@ -24,8 +24,9 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import com.alibaba.cloud.dubbo.autoconfigure.condition.MissingSpringCloudRegistryConfigPropertyCondition; -import com.alibaba.cloud.dubbo.metadata.DubboBootstrapCommandLineRunner; -import com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapStartedEvent; +import com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapStartCommandLineRunner; +import com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapWrapper; +import com.alibaba.cloud.dubbo.bootstrap.event.DubboBootstrapStartedEvent; import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository; import com.alibaba.cloud.dubbo.registry.DubboServiceRegistrationEventPublishingAspect; import com.alibaba.cloud.dubbo.registry.event.ServiceInstancePreDeregisteredEvent; @@ -60,7 +61,6 @@ import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.event.EventListener; -import org.springframework.core.annotation.Order; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.CONSUL_AUTO_SERVICE_AUTO_CONFIGURATION_CLASS_NAME; import static com.alibaba.cloud.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; @@ -72,10 +72,11 @@ import static org.springframework.util.ObjectUtils.isEmpty; * Dubbo Service Registration Auto-{@link Configuration}. * * @author Mercy + * @author theonefx */ @Configuration(proxyBeanMethods = false) @Import({ DubboServiceRegistrationEventPublishingAspect.class, - DubboBootstrapCommandLineRunner.class }) + DubboBootstrapStartCommandLineRunner.class }) @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) @AutoConfigureAfter(name = { EUREKA_CLIENT_AUTO_CONFIGURATION_CLASS_NAME, @@ -118,10 +119,9 @@ public class DubboServiceRegistrationAutoConfiguration { private Map, Set> registrations = new ConcurrentHashMap<>(); - @Order @EventListener(DubboBootstrapStartedEvent.class) - public void attachDubboMetadataAndRegistAgain(DubboBootstrapStartedEvent event) { - if (!event.getSource().isReady() || !event.getSource().isStarted()) { + public void onDubboBootstrapStarted(DubboBootstrapStartedEvent event) { + if (!event.getSource().isReady()) { return; } registrations.forEach( @@ -181,9 +181,9 @@ public class DubboServiceRegistrationAutoConfiguration { private ObjectProvider> serviceBeans; @EventListener(DubboBootstrapStartedEvent.class) - public void onServiceInstancePreRegistered(DubboBootstrapStartedEvent event) { - DubboBootstrap bootstrap = event.getSource(); - if (!bootstrap.isReady() || !bootstrap.isStarted()) { + public void onDubboBootstrapStarted(DubboBootstrapStartedEvent event) { + DubboBootstrapWrapper wrapper = event.getSource(); + if (!wrapper.isReady()) { return; } registrations.forEach( @@ -263,7 +263,7 @@ public class DubboServiceRegistrationAutoConfiguration { @EventListener(DubboBootstrapStartedEvent.class) public void attachURLsIntoMetadataBeforeReRegist( DubboBootstrapStartedEvent event) { - if (!event.getSource().isReady() || !event.getSource().isStarted()) { + if (!event.getSource().isReady()) { return; } registrations.entrySet().removeIf(entry -> { diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboBootstrapCommandLineRunner.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/DubboBootstrapStartCommandLineRunner.java similarity index 75% rename from spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboBootstrapCommandLineRunner.java rename to spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/DubboBootstrapStartCommandLineRunner.java index dc819d0e0..9f47bb2e8 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DubboBootstrapCommandLineRunner.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/DubboBootstrapStartCommandLineRunner.java @@ -14,10 +14,9 @@ * limitations under the License. */ -package com.alibaba.cloud.dubbo.metadata; +package com.alibaba.cloud.dubbo.bootstrap; -import com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapStartedEvent; -import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import com.alibaba.cloud.dubbo.bootstrap.event.DubboBootstrapStartedEvent; import org.springframework.boot.CommandLineRunner; import org.springframework.context.ApplicationEventPublisher; @@ -25,13 +24,13 @@ import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Component; /** - * @see com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapPreStartEvent - * @see com.alibaba.cloud.dubbo.metadata.event.DubboBootstrapStartedEvent + * publish Dubbo microsystem startup finish event. + * * @author theonefx */ @Component -public class DubboBootstrapCommandLineRunner +public class DubboBootstrapStartCommandLineRunner implements CommandLineRunner, ApplicationEventPublisherAware { private ApplicationEventPublisher applicationEventPublisher; @@ -45,7 +44,7 @@ public class DubboBootstrapCommandLineRunner @Override public void run(String... args) { applicationEventPublisher.publishEvent( - new DubboBootstrapStartedEvent(DubboBootstrap.getInstance())); + new DubboBootstrapStartedEvent(DubboBootstrapWrapper.getInstance())); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapPreStartEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/DubboBootstrapWrapper.java similarity index 52% rename from spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapPreStartEvent.java rename to spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/DubboBootstrapWrapper.java index b38f0c843..60fcaf6a5 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapPreStartEvent.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/DubboBootstrapWrapper.java @@ -14,22 +14,34 @@ * limitations under the License. */ -package com.alibaba.cloud.dubbo.metadata.event; +package com.alibaba.cloud.dubbo.bootstrap; -import org.springframework.context.ApplicationEvent; +import org.apache.dubbo.config.bootstrap.DubboBootstrap; /** + * Wrapper DubboBootstrap operation. + * * @author theonefx */ -public class DubboBootstrapPreStartEvent extends ApplicationEvent { - - /** - * Create a new {@code ApplicationEvent}. - * @param source the object on which the event initially occurred or with which the - * event is associated (never {@code null}) - */ - public DubboBootstrapPreStartEvent(Object source) { - super(source); +public final class DubboBootstrapWrapper { + + private DubboBootstrapWrapper() { + } + + private static final DubboBootstrapWrapper INSTANCE = new DubboBootstrapWrapper(); + + public static DubboBootstrapWrapper getInstance() { + return INSTANCE; + } + + public boolean isReady() { + return DubboBootstrap.getInstance().isStarted() + && DubboBootstrap.getInstance().isReady() + && DubboBootstrap.getInstance().isInitialized(); + } + + public DubboBootstrap getDubboBootstrap() { + return DubboBootstrap.getInstance(); } } diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapStartedEvent.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/event/DubboBootstrapStartedEvent.java similarity index 71% rename from spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapStartedEvent.java rename to spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/event/DubboBootstrapStartedEvent.java index c41996b8f..3f14525c8 100644 --- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/event/DubboBootstrapStartedEvent.java +++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/bootstrap/event/DubboBootstrapStartedEvent.java @@ -14,29 +14,31 @@ * limitations under the License. */ -package com.alibaba.cloud.dubbo.metadata.event; +package com.alibaba.cloud.dubbo.bootstrap.event; -import org.apache.dubbo.config.bootstrap.DubboBootstrap; +import com.alibaba.cloud.dubbo.bootstrap.DubboBootstrapWrapper; import org.springframework.context.ApplicationEvent; /** + * Dubbo microsytem start finish event, every thing is ready. + * * @author theonefx */ public class DubboBootstrapStartedEvent extends ApplicationEvent { /** - * Create a new {@code ApplicationEvent}. + * Create a new {@code DubboBootstrapStartedEvent}. * @param source the object on which the event initially occurred or with which the * event is associated (never {@code null}) */ - public DubboBootstrapStartedEvent(Object source) { + public DubboBootstrapStartedEvent(DubboBootstrapWrapper source) { super(source); } @Override - public DubboBootstrap getSource() { - return (DubboBootstrap) super.getSource(); + public DubboBootstrapWrapper getSource() { + return (DubboBootstrapWrapper) super.getSource(); } }