Dubbo配置完全外部化实践,使用动态配置中心的注意事项
问题描述
近期开发项目,将Dubbo的配置全部外部化到动态配置中心。这里配置中心我使用的是Apollo。
@Configuration
public class DubboConfig {
@Bean
public ConfigCenterConfig configCenterConfig() {
ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
configCenterConfig.setAddress("apollo.xxxxx.com");
configCenterConfig.setProtocol("apollo");
configCenterConfig.setNamespace("dubbo");
configCenterConfig.setGroup(null);
return configCenterConfig;
}
}
这里使用dubbo这个namespace。
其余配置全部配置在这个里面。
然后遇到一个大坑:
这里项目中定义了一个Service,也就是作为Provider提供了版本为provider.auth.version的服务。
package io.github.slankka.provider;
@Service(version = "${provider.auth.version:1.0}")
@Slf4j
public class AuthApiService implements IAuthApi
项目启动之后,注册到注册中心的版本是1.0。
在dubbo命名空间中定义了provider.auth.version=20000,但是启动还是1.0
问题分析
Apollo启动模式分为两种,一种是在 BeanDefinition阶段就将配置注入Spring容器内的Environment。另一种是在PostBeanFactory的时候启动。
而Dubbo启动的时候,所有的Service是ServiceBean的实例对应生成的代理类,所有的Reference是ReferenceBean的实例对应生成的代理类。
因此如果这里使用placeholder要被Spring识别,那么将必须选用第一种启动方式。
问题解决
在本地项目的application.properties中配置:
apollo.bootstrap.enabled = true
apollo.bootstrap.namespaces = application,dubbo
注意,这里apollo.bootstrap.namespaces 中加入了dubbo,这里有一个疑问:
之前配置Dubbo的时候不是定义了ConfigCenterConfig的namespace了吗,为什么还要定义一次。
configCenterConfig.setNamespace("dubbo");
原因是:
Dubbo的ServiceBean在被Spring工厂构建出来的时候,就需要这个变量。但如果没有配置dubbo到apollo.bootstrap.namespaces,Spring会报错。
如果接口上写了默认版本,上例是1.0,则Spring不会报错,但是构建出来的对应ServiceBean中的版本将会是1.0,而Dubbo启动之后依然不会修改这个版本。
新的问题
为什么Dubbo的namespace中配置了这个变量,而且Dubbo在启动早起阶段就已经拉到了这些变量,但版本仍旧没有发生改变?
看一下Dubbo代码:
//package org.apache.dubbo.common.config;
public abstract class AbstractPrefixConfiguration implements Configuration {
protected String id;
protected String prefix;
public AbstractPrefixConfiguration(String prefix, String id) {
if (StringUtils.isNotEmpty(prefix) && !prefix.endsWith(".")) {
this.prefix = prefix + ".";
} else {
this.prefix = prefix;
}
this.id = id;
}
@Override
public Object getProperty(String key, Object defaultValue) {
Object value = null;
if (StringUtils.isNotEmpty(prefix)) {
if (StringUtils.isNotEmpty(id)) {
value = getInternalProperty(prefix + id + "." + key);
}
if (value == null) {
value = getInternalProperty(prefix + key);
}
} else {
value = getInternalProperty(key);
}
return value != null ? value : defaultValue;
}
}
已知Dubbo是通过Configuration 的getProperty获取version等等这些属性,
这里可以看到用prefix + key的方式作为 property的名字来获取变量的值。
经过Debug发现,Dubbo的 AbstractPrefixConfiguration类的prefix正好是接口的FQCN,在本例中为:
AbstractPrefixConfiguration.prefix=dubbo.service.io.github.slankka.provider.IAuthApi.
那么key=version
因此可以推断出,Dubbo的外部化配置指定的Namespace中,如果要指定版本,且希望经过Dubbo的Environment处理,那么一定要用这种形式:
dubbo.service.io.github.slankka.provider.IAuthApi.version=20000
总结
- 如果使用placeholder的方式定义Service版本,那么根据习惯,要确保这些变量放在Spring启动阶段就能读到的地方。
- 如果要在Dubbo的namespace中定义,被Dubbo处理,那么要符合Dubbo的命令规则。dubbo.service.xxxxxxx.version等等这种形式。
- 如果使用placeholder的方式定义,但希望被Apollo直接处理,那么需要配置:
apollo.bootstrap.enabled = true
apollo.bootstrap.namespaces = application,dubbo
那么什么时候使用 placeholder什么时候使用 dubbo.service..version方式定义呢?
答案很显然是,如果多个接口都用共用同一个版本变量进行设置,用Apollo+Spring的方式进行处理。如果每一个接口都配置不同的版本,可以用Dubbo的方式定义。
进一步了解Dubbo和Apollo集成的遇到的有趣问题
解决Dubbo 2.7.3版本使用ConfigCenterConfig集成Apollo No Provider found的问题
Dubbo配置完全外部化实践,使用动态配置中心的注意事项的更多相关文章
- 玩转Spring Boot 自定义配置、导入XML配置与外部化配置
玩转Spring Boot 自定义配置.导入XML配置与外部化配置 在这里我会全面介绍在Spring Boot里面如何自定义配置,更改Spring Boot默认的配置,以及介绍各配置的优先 ...
- 微信小程序动态修改title,动态配置title,动态配置头部,微信小程序动态配置头部
微信小程序的title是在json里面配置的 "navigationBarTitleText": "title名称" 这种title是固定死的不灵活处理一些页面 ...
- Spring 配置内容外部化
- 基于Apache Zookeeper手写实现动态配置中心(纯代码实践)
相信大家都知道,每个项目中会有一些配置信息放在一个独立的properties文件中,比如application.properties.这个文件中会放一些常量的配置,比如数据库连接信息.线程池大小.限流 ...
- Kafka动态配置实现原理解析
问题导读 Apache Kafka在全球各个领域各大公司获得广泛使用,得益于它强大的功能和不断完善的生态.其中Kafka动态配置是一个比较高频好用的功能,下面我们就来一探究竟. 动态配置是如何设计的? ...
- hystrix(一) 简单使用, 以及动态配置更新
本文转载自https://my.oschina.net/u/1169457/blog/1787414 hystrix 简单使用, 以及动态配置更新 概述 只介绍同步模式下简单的使用, 有助于快速接入, ...
- Dubbo 新编程模型之外部化配置
外部化配置(External Configuration) 在Dubbo 注解驱动例子中,无论是服务提供方,还是服务消费方,均需要转配相关配置Bean: @Bean public Applicatio ...
- SpringBoot 正式环境必不可少的外部化配置
前言 <[源码解析]凭什么?spring boot 一个 jar 就能开发 web 项目> 中有读者反应: 部署后运维很不方便,比较修改一个 IP 配置,需要重新打包. 这一点我是深有体会 ...
- SpringBoot官方文档学习(二)Externalized Configuration(外部化配置)
Spring Boot允许您将配置外部化,以便可以在不同的环境中使用相同的应用程序代码.您可以使用属性文件.YAML文件.环境变量和命令行参数来具体化配置.属性值可以通过使用@Value注释直接注入b ...
随机推荐
- Mach-O在内存中符号表地址、字符串表地址的计算
KSCrash 是一个用于 iOS 平台的崩溃捕捉框架,最近读了其部分源码,在 KSDynamicLinker 文件中有一个函数,代码如下: /** Get the segment base addr ...
- Python基础(十二)
今日主要内容 推导式 生成器表达式 lambda匿名函数 内置函数介绍 一.推导式 (一)列表推导式 先来看一段代码 建立一个空列表,向空列表中添加元素 lst = list() for i in r ...
- FILETIME类型到LARGE_INTEGER类型的转换
核心编程第5版 245页到247页的讲到SetWaitableTimer函数的使用 其中提到 FILETIME类型到LARGE_INTEGER类型的转换问题,如下代码 //我们声明的局部变量 HAND ...
- Fork/Join 框架框架使用
1.介绍 Fork/Join 框架是 Java7 提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.在多核计算机中正确使用可以很好的 ...
- javaweb技术入门
JavaWeb巩固和进阶 1.如何配置外部应用? 方法一: server.xml 在<Host>中添加如下配置 <Context path="/xxx" docB ...
- MySQL InnoDB如何保证事务特性
如果有人问你"数据库事务有哪些特性"?你可能会很快回答出原子性.一致性.隔离性.持久性即ACID特性.那么你知道InnoDB如何保证这些事务特性的吗?如果知道的话这篇文章就可以直接 ...
- ActiveMQ学习总结------入门篇01
注:*这篇博文文章主要介绍ActiveMQ是什么原理性的内容和如何安装和简易操作 一. ActiveMQ 简介 1 ActiveMQ是什么呢?看起来好碉堡的东西哇! ActiveMQ 是 Apach ...
- springmvc中重定向该如何处理?
如果登录成功,会重定向到系统首页 response.sendRedirect("jsp/frame.jsp"); 在springmvc中,应该如何处理?是否可以直接使用 retur ...
- 网络请求中的cookie与set-Cookie的交互模式的一些问题解析
首先我们需要思考,很多问题. 1.当很多人访问统一个网服务器,服务器如何来区分不同的用户呢? 答:sessionid,sessionid保证了浏览器和服务器唯一性的通信凭证号码,session保存在服 ...
- e课表项目第二次冲刺周期第十天
昨天完成了什么? 昨天还有一天第一次冲刺周期就结束了,我们的工作也接近尾声了,所以今天我利用之前的方法,完成了对监听的设置,以及对修改界面的编写,可以实现相应的删除和修改的功能,然后我和我们组的成员商 ...