Solve problems Dubbo 2.7.3 version ConfigCenterConfig integrated Apollo No Provider found the

Dubbo 2.7.3 Integrated Apollo

Problem Description

Dubbo 2.7.3 supports the configuration of the central external configuration, and therefore only need to define a ConfigCenterConfig of Bean.

@EnableDubbo(scanBasePackages = {"com.slankka.cloud.dubbo"})
@Configuration
public class DubboConfig {
    @Bean
    public ConfigCenterConfig configCenterConfig() {
        ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
        configCenterConfig.setAddress("apollo.xxxxx.com:8080");
        configCenterConfig.setProtocol("apollo");
        configCenterConfig.setNamespace("dubbo");
        configCenterConfig.setGroup(null);
        return configCenterConfig;
    }
}

problem:

  1. Apollo can not find the meta.
  2. Dubbo provider can not be found

solution

  1. Apollo can not find the meta, jar of Apollo, apollo-core configuration file clearly declares PRO.meta = "apollo.xxxxx.com:8080". This problem occurs in
apollo.bootstrap.enabled = false

If you want to adhere to this configuration, the need to increase

apollo.meta=apollo.xxxxx.com:8080
  1. Dubbo can not find the Provider, a closer look at the log Interface: com.xxx.xxx.service, if the latter did not follow the version number, for example: 1.2.0, then the version is not defined.
    The problem is that because the definition of a placeholder, while Dubbo start when the class is created ReferenceBean BeanPostProcessor, start early, and apollo.bootstrap.enabled = false.
    Dubbo create this IRExecutionService the corresponding Bean class, you can not find the version, but he ate abnormal catch up. Is equal to is not configured version.
apollo.bootstrap.enabled = false

@Reference(version = "${job.service.version}", retries = 0, lazy = true)
private IRExecutionService executionService;

The reason is not available from Dubbo ConfigCenterConfig read version, or too late, if you want to solve very simple, but too dependent on Apollo ahead of the initialization switch.

If you insist on apollo.bootstrap.enabled = false, correct behavior Dubbo how to do?

package io.github.slankka.dubbo-apollo.server.config;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.common.config.Environment;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConfigCenterConfig;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.bind.PropertySourcesPlaceholdersResolver;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.PropertySource;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.apache.dubbo.common.config.ConfigurationUtils.parseProperties;

/**
 * Project: dubbo-apollo
 *
 * @author slankka on 2019/8/29.
 */
@ConditionalOnProperty(name = "apollo.bootstrap.enabled", havingValue = "false", matchIfMissing = true)
@Component(value = ReferenceAnnotationBeanPostProcessor.BEAN_NAME)
public class ReferencedAnnotationPatch extends ReferenceAnnotationBeanPostProcessor {

    private ApplicationContext myContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        myContext = applicationContext;
        super.setApplicationContext(applicationContext);
    }

    @Override
    protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName,
                                       Class<?> injectedType,
                                       InjectionMetadata.InjectedElement injectedElement) throws Exception {
        eagerInitConfigCenter();
        Configuration configuration = Environment.getInstance().getConfiguration();

        List<PropertySource<?>> propertySources = new ArrayList<>();
        propertySources.add(new PropertySource<Configuration>("dubboConfigCenter", configuration) {
            @Override
            public Object getProperty(String name) {
                return configuration.getProperty(name);
            }
        });
        PropertySourcesPlaceholdersResolver propertySourcesPlaceholdersResolver = new PropertySourcesPlaceholdersResolver(propertySources);

        for (String attribute : attributes.keySet()) {
            Object stringAttr = attributes.get(attribute);
            if (stringAttr instanceof String) {
                Object value = propertySourcesPlaceholdersResolver.resolvePlaceholders(attributes.getString(attribute));
                attributes.put(attribute, value);
            }
        }

        return super.doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement);
    }

    private void eagerInitConfigCenter() {
        ConfigCenterConfig configCenter = myContext.getBean(ConfigCenterConfig.class);
        if (configCenter.isValid()) {
            if (configCenter.checkOrUpdateInited()) {
                configCenter.refresh();

                URL url = configCenter.toUrl();
                DynamicConfigurationFactory factories = ExtensionLoader
                        .getExtensionLoader(DynamicConfigurationFactory.class)
                        .getExtension(url.getProtocol());
                DynamicConfiguration dynamicConfiguration = factories.getDynamicConfiguration(url);
                String configContent = dynamicConfiguration.getProperties(configCenter.getConfigFile(), configCenter.getGroup());

                ApplicationConfig application = myContext.getBean(ApplicationConfig.class);
                String appGroup = application.getName();
                String appConfigContent = null;
                if (StringUtils.isNotEmpty(appGroup)) {
                    appConfigContent = dynamicConfiguration.getProperties
                            (StringUtils.isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile(),
                                    appGroup
                            );
                }
                try {
                    Environment.getInstance().setConfigCenterFirst(configCenter.isHighestPriority());
                    Environment.getInstance().updateExternalConfigurationMap(parseProperties(configContent));
                    Environment.getInstance().updateAppExternalConfigurationMap(parseProperties(appConfigContent));
                } catch (IOException e) {
                    throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
                }
            }
        }
    }
}

ReferenceAnnotationBeanPostProcessor is able to correct the behavior of Dubbo, because this time, there have been ConfigCenterConfig the Bean, so let ConfigCenter early start, so that @Reference comment placeholder can be resolved.
Note that this placeholder is disposed Namespace ( "dubbo"); inside.

Finally, a small problem

Dubbo will default read dubbo this Apollo's namespace, if a custom namespace, he would read, because they do not exist and start to slow down, so in order to speed up the startup speed, suggests an empty dubbo the namespace creation of Apollo.

Guess you like

Origin www.cnblogs.com/slankka/p/11431324.html