解决Dubbo 2.7.3版本使用ConfigCenterConfig集成Apollo No Provider found的问题
Dubbo 2.7.3 集成Apollo
问题描述
Dubbo 2.7.3支持配置中心外部化配置, 因此只需要定义一个ConfigCenterConfig的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;
}
}
问题:
- Apollo 找不到 meta。
- Dubbo 找不到 provider
解决方案
1. Apollo 找不到meta
Apollo的jar 的apollo-core的配置文件明明声明了PRO.meta="apollo.xxxxx.com:8080"。
这个问题出现在
apollo.bootstrap.enabled = false
如果要坚持这样配置,需要增加
apollo.meta=apollo.xxxxx.com:8080
更新:此问题还有更深入的分析: Apollo报错找不到apollo.meta的问题解决方案
2. Dubbo 找不到Provider
仔细看日志 Interface: com.xxx.xxx.service,如果后面没有跟着版本号例如: 1.2.0,则说明版本没有定义。
问题是因为定义了占位符,而Dubbo启动的时候,创建ReferenceBean的类是个BeanPostProcessor,启动比较早,而apollo.bootstrap.enabled=false。
则Dubbo创建这个IRExecutionService对应的Bean类的时候,找不到version,但是他catch吃掉异常了。等于没有配置version。
apollo.bootstrap.enabled = false
@Reference(version = "${job.service.version}", retries = 0, lazy = true)
private IRExecutionService executionService;
则原因是Dubbo不能从ConfigCenterConfig读取版本配置,或者太迟了,如果要解决很简单 ,但是太依赖Apollo提前初始化开关。
如果坚持要apollo.bootstrap.enabled = false,强制使用Dubbo自行处理这个变量的解析怎么办?
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);
}
}
}
}
}
则能纠正Dubbo 的ReferenceAnnotationBeanPostProcessor 行为,因为这个时候,已经有ConfigCenterConfig这个Bean了,所以让ConfigCenter提前启动,从而使得@Reference注解的占位符能够被解析。
注意,这个占位符是配置在Namespace("dubbo");内的。
最后一个小问题
Dubbo 会默认读取 dubbo这个 Apollo的namespace,如果用自定义的namespace,他也会读取,因为不存在而启动减慢,所以为了加快启动速度,建议创建Apollo的 一个空dubbo的namespace。
解决Dubbo 2.7.3版本使用ConfigCenterConfig集成Apollo No Provider found的问题的更多相关文章
- Myeclipse解决dubbo标签不识别问题
Myeclipse解决dubbo标签不识别问题,引入dubbo.xsd文件,即可:
- 如何解决pytorch 编译时CUDA版本与运行时CUDA版本不对应
转载请注明: 仰望高端玩家的小清新 http://www.cnblogs.com/luruiyuan/ 如何解决pytorch 编译时CUDA版本与运行时CUDA版本不对应 如果pytorch的编译时 ...
- phalcon: 解决php7/phalcon3.2以上版本,不支持oracle数据库的方法
解决php7/phalcon3.2以上版本,不支持oracle数据库的方法 phalcon3.2(3.0以上)版本不支持oracle的方法. https://github.com/phalcon/in ...
- 解决在安装Fiddler4.6版本后,在手机上安装证书出现的问题解决方法
解决在安装Fiddler4.6版本后,在手机上安装证书出现的问题解决方法 设置fiddler抓手机包后,在手机上访问http://ip:port,出现如下问题: 问题:creation of the ...
- 解决VS+opencv中Debug版本与Release版本lib切换的问题
Author: Maddock Date: 2015-03-26 09:34:48 问题来源:http://bbs.csdn.net/topics/390733725 PS: 按照上述方法做的时候,在 ...
- 解决本机安装多版本jdk导致The type java.lang.Object cannot be resolved It is indirectly referenced ...
本机开始安装了jdk1.6,然后安装了jdk1.8 当在调自动化的时候,发现传入函数传参String类型,报错The type java.lang.Object cannot be resolved ...
- 使用Docker解决同一服务器运行不同版本PHP方案。
前言: 最近公司有两个站点,分别是两种系统进行二次开发,基于LNMP架构的网站.一般想PHP这种非编译型语言想要对外出售源码都会进行加密,加密方法有很多种,大部分都是使用Zend Guard来进行加密 ...
- 解决python2.7.9以下版本requests访问https的问题
在python2.7.9以下版本requests访问https连接后,总会报一些关于SSL warning. 解决法子可以参考:https://urllib3.readthedocs.io/en/la ...
- 解决WebSocket兼容ie浏览器版本问题
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7942323.html 在使用Netty进行WebSocket开发时,测试发现:ie 11系列个别低版本连接W ...
随机推荐
- 第六届蓝桥杯java b组第一题
第一题 三角形面积 图中的所有小方格面积都是1. 那么,图中的三角形面积应该是多少呢? 请填写三角形的面积.不要填写任何多余内容或说明性文字. 填空答案 28 没什么好说的 第一题很水 估计就是为了增 ...
- 环境搭建-Hadoop集群搭建
环境搭建-Hadoop集群搭建 写在前面,前面我们快速搭建好了centos的集群环境,接下来,我们就来开始hadoop的集群的搭建工作 实验环境 Hadoop版本:CDH 5.7.0 这里,我想说一下 ...
- Python学习笔记整理总结【Django】:中间件、CSRF、缓存
一.中间件 中间件是一类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法:在django项目的settings模块中,有一个 MIDDLEWARE 变量,其中每 ...
- python3在word文档中查找多行文字是否存在
工作中碰到这样一个情况:有多个关键词存在文本文档txt中,想查找下在某个较大的word文档中,这些关键词是否都含有,没有关键词的显示出来. 因为关键词比较多,并且这个工作还是经常会有的,这个情况我试着 ...
- MySQL命令窗口出现中文乱码的解决方法
查询表语句的时候,出现了中文乱码,但是用Navicat for MySQL查看的时候却是正常的,字符集都是设置的utf-8,如下图所示: 其实上大学学习java的时候也遇到了中文乱码但是却没有 ...
- Spring boot 梳理 - 在bean中使用命令行参数-自动装配ApplicationArguments
If you need to access the application arguments that were passed to SpringApplication.run(…), you c ...
- FormatMessage将错误代码转换成对应的字符串
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" int _tmain(int argc, _T ...
- layui-table 对表格数据进行处理之后的排序问题
使用layui table过程中,将某一列的数据格式进行转换,或者将0/1状态改为是/否,或者将数字改为星星评分显示的时候都会遇到一个问题,我的表格数据转换成其他形式,同时设置了sort:true,此 ...
- node学习笔记(一)本地文件目录查看器
Node.js 新闻 nw.js 前端开发桌面应用 内容 node.js实战 照例提供百度云链接,本来以为是实战系列的那本,但不是,不过这本也不错 链接:https://pan.baidu.com/s ...
- ng-cli新建项目
tip:所有的命令是红色标签 , 链接为蓝色标签 使用ng-cli创建新的项目一般需要安装一些新的东西后才可以进行创建成功 1.需要先安装node.js 链接: https://nodejs.org ...