(+) (#)
(#)
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
(#)
在大规模服务化之前,应用可能只是通过RMI或Hessian等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过F5等硬件进行负载均衡。
(1) 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
此时需要一个服务注册中心,动态的注册和发现服务,使服务的位置透明。
并通过在消费方获取服务提供方地址列表,实现软负载均衡和Failover,降低对F5硬件负载均衡器的依赖,也能减少部分成本。
(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
这时,需要自动画出应用间的依赖关系图,以帮助架构师理清理关系。
(3) 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
为了解决这些问题,第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。
其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量,再以此访问量乘以机器数反推总容量。
以上是Dubbo最基本的几个需求,更多服务治理问题参见:
http://code.alibabatech.com/blog/experience_1402/service-governance-process.html
(#)
节点角色说明:
调用关系说明:
(1) 连通性:
(2) 健状性:
(3) 伸缩性:
(4) 升级性:
(#)
<beanid=“xxxService” class=“com.xxx.XxxServiceImpl” />
<beanid=“xxxAction” class=“com.xxx.XxxAction”>
<propertyname=“xxxService” ref=“xxxService” />
</bean>
|
在本地服务的基础上,只需做简单配置,即可完成远程化:
如下:
<beanid=“xxxService” class=“com.xxx.XxxServiceImpl” /><!-- 和本地服务一样实现远程服务 -->
<dubbo:serviceinterface=“com.xxx.XxxService” ref=“xxxService” /><!-- 增加暴露远程服务配置 -->
|
<dubbo:referenceid=“xxxService” interface=“com.xxx.XxxService” /><!-- 增加引用远程服务配置 -->
<beanid=“xxxAction” class=“com.xxx.XxxAction”><!-- 和本地服务一样使用远程服务 -->
<propertyname=“xxxService” ref=“xxxService” />
</bean>
|
(+) (#)
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。 |
如果不想使用Spring配置,而希望通过API的方式进行调用(不推荐),请参见:API配置 (+) |
(#)
完整安装步骤,请参见:示例提供者安装 (+) |
定义服务接口: (该接口需单独打包,在服务提供方和消费方共享)
packagecom.alibaba.dubbo.demo;
publicinterfaceDemoService {
String sayHello(String name);
}
|
在服务提供方实现接口:(对服务消费方隐藏实现)
packagecom.alibaba.dubbo.demo.provider;
importcom.alibaba.dubbo.demo.DemoService;
publicclassDemoServiceImplimplementsDemoService {
publicString sayHello(String name) {
return"Hello "+ name;
}
}
|
用Spring配置声明暴露服务:
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:applicationname="hello-world-app" />
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registryaddress="multicast://224.5.6.7:1234"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocolname="dubbo"port="20880"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoService"ref="demoService"/>
<!-- 和本地bean一样实现服务 -->
<beanid="demoService"class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>
</beans>
|
加载Spring配置:
importorg.springframework.context.support.ClassPathXmlApplicationContext;
publicclassProvider {
publicstaticvoidmain(String[] args)throwsException {
ClassPathXmlApplicationContext context =newClassPathXmlApplicationContext(newString[] {"provider.xml"});
context.start();
System.in.read();// 按任意键退出
}
}
|
(#)
完整安装步骤,请参见:示例消费者安装 (+) |
通过Spring配置引用远程服务:
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:applicationname="consumer-of-helloworld-app" />
<!-- 使用multicast广播注册中心暴露发现服务地址 -->
<dubbo:registryaddress="multicast://224.5.6.7:1234"/>
<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:referenceid="demoService"interface="com.alibaba.dubbo.demo.DemoService"/>
</beans>
|
加载Spring配置,并调用远程服务:(也可以使用IoC注入)
importorg.springframework.context.support.ClassPathXmlApplicationContext;
importcom.alibaba.dubbo.demo.DemoService;
publicclassConsumer {
publicstaticvoidmain(String[] args)throwsException {
ClassPathXmlApplicationContext context =newClassPathXmlApplicationContext(newString[] {"consumer.xml"});
context.start();
DemoService demoService = (DemoService)context.getBean("demoService");// 获取远程服务代理
String hello = demoService.sayHello("world");// 执行远程方法
System.out.println( hello );// 显示调用结果
}
}
|
(+) (#)
理论上Dubbo可以只依赖JDK,不依赖于任何三方库运行,只需配置使用JDK相关实现策略。 |
通过mvn dependency:tree > dep.log命令分析,Dubbo缺省依赖以下三方库:
[INFO] +- com.alibaba:dubbo:jar:2.1.2:compile
[INFO] | +- log4j:log4j:jar:1.2.16:compile
[INFO] | +- org.javassist:javassist:jar:3.15.0-GA:compile
[INFO] | +- org.springframework:spring:jar:2.5.6.SEC03:compile
[INFO] | +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] | \- org.jboss.netty:netty:jar:3.2.5.Final:compile
|
这里所有依赖都是换照Dubbo缺省配置选的,这些缺省值是基于稳定性和性能考虑的。
以下依赖,在主动配置使用相应实现策略时用到,需自行加入依赖。
JEE:
(+) (#)
(#)
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
并发控制 | Tested | 并发控制 | 试用 | ||
连接控制 | Tested | 连接数控制 | 试用 | ||
直连提供者 | Tested | 点对点直连服务提供方,用于测试 | 测试环境使用 | Alibaba | |
分组聚合 | Tested | 分组聚合返回值,用于菜单聚合等服务 | 特殊场景使用 | 可用于生产环境 | |
参数验证 | Tested | 参数验证,JSR303验证框架集成 | 对性能有影响 | 试用 | LaiWang |
结果缓存 | Tested | 结果缓存,用于加速请求 | 试用 | ||
泛化引用 | Stable | 泛化调用,无需业务接口类进行远程调用,用于测试平台,开放网关桥接等 | 可用于生产环境 | Alibaba | |
泛化实现 | Stable | 泛化实现,无需业务接口类实现任意接口,用于Mock平台 | 可用于生产环境 | Alibaba | |
回声测试 | Tested | 回声测试 | 试用 | ||
隐式传参 | Stable | 附加参数 | 可用于生产环境 | ||
异步调用 | Tested | 不可靠异步调用 | 试用 | ||
本地调用 | Tested | 本地调用 | 试用 | ||
参数回调 | Tested | 参数回调 | 特殊场景使用 | 试用 | Registry |
事件通知 | Tested | 事件通知,在远程调用执行前后触发 | 试用 | ||
本地存根 | Stable | 在客户端执行部分逻辑 | 可用于生产环境 | Alibaba | |
本地伪装 | Stable | 伪造返回结果,可在失败时执行,或直接执行,用于服务降级 | 需注册中心支持 | 可用于生产环境 | Alibaba |
延迟暴露 | Stable | 延迟暴露服务,用于等待应用加载warmup数据,或等待spring加载完成 | 可用于生产环境 | Alibaba | |
延迟连接 | Tested | 延迟建立连接,调用时建立 | 试用 | Registry | |
粘滞连接 | Tested | 粘滞连接,总是向同一个提供方发起请求,除非此提供方挂掉,再切换到另一台 | 试用 | Registry | |
令牌验证 | Tested | 令牌验证,用于服务授权 | 需注册中心支持 | 试用 | |
路由规则 | Tested | 动态决定调用关系 | 需注册中心支持 | 试用 | |
配置规则 | Tested | 动态下发配置,实现功能的开关 | 需注册中心支持 | 试用 | |
访问日志 | Tested | 访问日志,用于记录调用信息 | 本地存储,影响性能,受磁盘大小限制 | 试用 | |
分布式事务 | Research | JTA/XA三阶段提交事务 | 不稳定 | 不可用 |
(#)
Feature | Maturity | Strength | Problem | Advise | User |
---|---|---|---|---|---|
Zookeeper注册中心 | Stable | 支持基于网络的集群方式,有广泛周边开源产品,建议使用dubbo-2.3.3以上版本(推荐使用) | 依赖于Zookeeper的稳定性 | 可用于生产环境 | |
Redis注册中心 | Stable | 支持基于客户端双写的集群方式,性能高 | 要求服务器时间同步,用于检查心跳过期脏数据 | 可用于生产环境 | |
Multicast注册中心 | Tested | 去中心化,不需要安装注册中心 | 依赖于网络拓普和路由,跨机房有风险 | 小规模应用或开发测试环境 | |
Simple注册中心 | Tested | Dogfooding,注册中心本身也是一个标准的RPC服务 | 没有集群支持,可能单点故障 | 试用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Simple监控中心 | Stable | 支持JFreeChart统计报表 | 没有集群支持,可能单点故障,但故障后不影响RPC运行 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Dubbo协议 | Stable | 采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用) | 在大文件传输时,单一连接会成为瓶颈 | 可用于生产环境 | Alibaba |
Rmi协议 | Stable | 可与原生RMI互操作,基于TCP协议 | 偶尔会连接失败,需重建Stub | 可用于生产环境 | Alibaba |
Hessian协议 | Stable | 可与原生Hessian互操作,基于HTTP协议 | 需hessian.jar支持,http短连接的开销大 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Netty Transporter | Stable | JBoss的NIO框架,性能较好(推荐使用) | 一次请求派发两种事件,需屏蔽无用事件 | 可用于生产环境 | Alibaba |
Mina Transporter | Stable | 老牌NIO框架,稳定 | 待发送消息队列派发不及时,大压力下,会出现FullGC | 可用于生产环境 | Alibaba |
Grizzly Transporter | Tested | Sun的NIO框架,应用于GlassFish服务器中 | 线程池不可扩展,Filter不能拦截下一Filter | 试用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Hessian Serialization | Stable | 性能较好,多语言支持(推荐使用) | Hessian的各版本兼容性不好,可能和应用使用的Hessian冲突,Dubbo内嵌了hessian3.2.1的源码 | 可用于生产环境 | Alibaba |
Dubbo Serialization | Tested | 通过不传送POJO的类元信息,在大量POJO传输时,性能较好 | 当参数对象增加字段时,需外部文件声明 | 试用 | |
Json Serialization | Tested | 纯文本,可跨语言解析,缺省采用FastJson解析 | 性能较差 | 试用 | |
Java Serialization | Stable | Java原生支持 | 性能较差 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Javassist ProxyFactory | Stable | 通过字节码生成代替反射,性能比较好(推荐使用) | 依赖于javassist.jar包,占用JVM的Perm内存,Perm可能要设大一些:java -XX:PermSize=128m | 可用于生产环境 | Alibaba |
Jdk ProxyFactory | Stable | JDK原生支持 | 性能较差 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Failover Cluster | Stable | 失败自动切换,当出现失败,重试其它服务器,通常用于读操作(推荐使用) | 重试会带来更长延迟 | 可用于生产环境 | Alibaba |
Failfast Cluster | Stable | 快速失败,只发起一次调用,失败立即报错,通常用于非幂等性的写操作 | 如果有机器正在重启,可能会出现调用失败 | 可用于生产环境 | Alibaba |
Failsafe Cluster | Stable | 失败安全,出现异常时,直接忽略,通常用于写入审计日志等操作 | 调用信息丢失 | 可用于生产环境 | Monitor |
Failback Cluster | Tested | 失败自动恢复,后台记录失败请求,定时重发,通常用于消息通知操作 | 不可靠,重启丢失 | 可用于生产环境 | Registry |
Forking Cluster | Tested | 并行调用多个服务器,只要一个成功即返回,通常用于实时性要求较高的读操作 | 需要浪费更多服务资源 | 可用于生产环境 | |
Broadcast Cluster | Tested | 广播调用所有提供者,逐个调用,任意一台报错则报错,通常用于更新提供方本地状态 | 速度慢,任意一台报错则报错 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
Random LoadBalance | Stable | 随机,按权重设置随机概率(推荐使用) | 在一个截面上碰撞的概率高,重试时,可能出现瞬间压力不均 | 可用于生产环境 | Alibaba |
RoundRobin LoadBalance | Stable | 轮循,按公约后的权重设置轮循比率 | 存在慢的机器累积请求问题,极端情况可能产生雪崩 | 可用于生产环境 | |
LeastActive LoadBalance | Stable | 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差,使慢的机器收到更少请求 | 不支持权重,在容量规划时,不能通过权重把压力导向一台机器压测容量 | 可用于生产环境 | |
ConsistentHash LoadBalance | Stable | 一致性Hash,相同参数的请求总是发到同一提供者,当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动 | 压力分摊不均 | 可用于生产环境 | |
Feature | Maturity | Strength | Problem | Advise | User |
条件路由规则 | Stable | 基于条件表达式的路由规则,功能简单易用 | 有些复杂多分支条件情况,规则很难描述 | 可用于生产环境 | Alibaba |
脚本路由规则 | Tested | 基于脚本引擎的路由规则,功能强大 | 没有运行沙箱,脚本能力过于强大,可能成为后门 | 试用 | |
Feature | Maturity | Strength | Problem | Advise | User |
Spring Container | Stable | 自动加载META-INF/spring目录下的所有Spring配置 | 可用于生产环境 | Alibaba | |
Jetty Container | Stable | 启动一个内嵌Jetty,用于汇报状态 | 大量访问页面时,会影响服务器的线程和内存 | 可用于生产环境 | Alibaba |
Log4j Container | Stable | 自动配置log4j的配置,在多进程启动时,自动给日志文件按进程分目录 | 用户不能控制log4j的配置,不灵活 | 可用于生产环境 | Alibaba |
(+) (#)
(+) (#)
配置项说明 详细配置项,请参见:配置参考手册 (+) |
API使用说明 如果不想使用Spring配置,而希望通过API的方式进行调用,请参见:API配置 (+) |
配置使用说明 想知道如何使用配置,请参见:快速启动 (+) |
示例:
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:applicationname="hello-world-app" />
<dubbo:registryaddress="multicast://224.5.6.7:1234"/>
<dubbo:protocolname="dubbo"port="20880"/>
<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoService"ref="demoServiceLocal"/>
<dubbo:referenceid="demoServiceRemote"interface="com.alibaba.dubbo.demo.DemoService"/>
</beans>
|
所有标签者支持自定义参数,用于不同扩展点实现的特殊配置。 |
如:
<dubbo:protocolname="jms">
<dubbo:parameterkey="queue"value="10.20.31.22"/>
</dubbo:protocol>
|
或:(2.1.0开始支持)
注意声明:xmlns:p="http://www.springframework.org/schema/p" |
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xmlns:p=" http://www.springframework.org/schema/p"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:protocolname="jms"p:queue="10.20.31.22"/>
</beans>
|
Configuration Relation:
Configuration Override:
(+) (#)
如果公共配置很简单,没有多注册中心,多协议等情况,或者想多个Spring容器想共享配置,可以使用dubbo.properties作为缺省配置。 |
Dubbo将自动加载classpath根目录下的dubbo.properties,可以通过JVM启动参数:-Ddubbo.properties.file=xxx.properties 改变缺省配置位置。 |
如果classpath根目录下存在多个dubbo.properties,比如多个jar包中有dubbo.properties,Dubbo会任意加载,并打印Error日志,后续可能改为抛异常。 |
映射规则:
典型配置如:
dubbo.application.name=foo
dubbo.application.owner=bar
dubbo.registry.address=10.20.153.10:9090
|
覆盖策略:
(+) (#)
2.2.1以上版本支持 |
服务提供方注解:
importcom.alibaba.dubbo.config.annotation.Service;
@Service(version="1.0.0")
publicclassFooServiceImplimplementsFooService {
// ......
}
|
服务提供方配置:
<!-- 公共信息,也可以用dubbo.properties配置 -->
<dubbo:applicationname="annotation-provider"/>
<dubbo:registryaddress="127.0.0.1:4548"/>
<!-- 扫描注解包路径,多个包用逗号分隔,不填pacakge表示扫描当前ApplicationContext中所有的类 -->
<dubbo:annotationpackage="com.foo.bar.service"/>
|
服务消费方注解:
importcom.alibaba.dubbo.config.annotation.Reference;
importorg.springframework.stereotype.Component;
@Component
publicclassBarAction {
@Reference(version="1.0.0")
privateFooService fooService;
}
|
服务消费方配置:
<!-- 公共信息,也可以用dubbo.properties配置 -->
<dubbo:applicationname="annotation-consumer"/>
<dubbo:registryaddress="127.0.0.1:4548"/>
<!-- 扫描注解包路径,多个包用逗号分隔,不填pacakge表示扫描当前ApplicationContext中所有的类 -->
<dubbo:annotationpackage="com.foo.bar.action"/>
|
也可以使用:(等价于前面的:<dubbo:annotation package="com.foo.bar.service" />)
<dubbo:annotation/>
<context:component-scanbase-package="com.foo.bar.service">
<context:include-filtertype="annotation"expression="com.alibaba.dubbo.config.annotation.Service"/>
</context:component-scan>
|
Spring2.5及以后版本支持component-scan,如果用的是Spring2.0及以前版本,需配置:
|
(+) (#)
API使用范围 API仅用于OpenAPI, ESB, Test, Mock等系统集成,普通服务提供方或消费方,请采用配置方式使用Dubbo,请参见:Xml配置 (+) |
API属性含义参考 API属性与配置项一对一,各属性含义,请参见:配置参考手册 (+), 比如:ApplicationConfig.setName("xxx") 对应 <dubbo:application name="xxx" /> |
importcom.alibaba.dubbo.rpc.config.ApplicationConfig;
importcom.alibaba.dubbo.rpc.config.RegistryConfig;
importcom.alibaba.dubbo.rpc.config.ProviderConfig;
importcom.alibaba.dubbo.rpc.config.ServiceConfig;
importcom.xxx.XxxService;
importcom.xxx.XxxServiceImpl;
// 服务实现
XxxService xxxService =newXxxServiceImpl();
// 当前应用配置
ApplicationConfig application =newApplicationConfig();
application.setName("xxx");
// 连接注册中心配置
RegistryConfig registry =newRegistryConfig();
registry.setAddress("10.20.130.230:9090");
registry.setUsername("aaa");
registry.setPassword("bbb");
// 服务提供者协议配置
ProtocolConfig protocol =newProtocolConfig();
protocol.setName("dubbo");
protocol.setPort(12345);
protocol.setThreads(200);
// 注意:ServiceConfig为重对象,内部封装了与注册中心的连接,以及开启服务端口
// 服务提供者暴露服务配置
ServiceConfig<XxxService> service =newServiceConfig<XxxService>();// 此实例很重,封装了与注册中心的连接,请自行缓存,否则可能造成内存和连接泄漏
service.setApplication(application);
service.setRegistry(registry);// 多个注册中心可以用setRegistries()
service.setProtocol(protocol);// 多个协议可以用setProtocols()
service.setInterface(XxxService.class);
service.setRef(xxxService);
service.setVersion("1.0.0");
// 暴露及注册服务
service.export();
|
importcom.alibaba.dubbo.rpc.config.ApplicationConfig;
importcom.alibaba.dubbo.rpc.config.RegistryConfig;
importcom.alibaba.dubbo.rpc.config.ConsumerConfig;
importcom.alibaba.dubbo.rpc.config.ReferenceConfig;
importcom.xxx.XxxService;
// 当前应用配置
ApplicationConfig application =newApplicationConfig();
application.setName("yyy");
// 连接注册中心配置
RegistryConfig registry =newRegistryConfig();
registry.setAddress("10.20.130.230:9090");
registry.setUsername("aaa");
registry.setPassword("bbb");
// 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
// 引用远程服务
ReferenceConfig<XxxService> reference =newReferenceConfig<XxxService>();// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
reference.setApplication(application);
reference.setRegistry(registry);// 多个注册中心可以用setRegistries()
reference.setInterface(XxxService.class);
reference.setVersion("1.0.0");
// 和本地bean一样使用xxxService
XxxService xxxService = reference.get();// 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用
|
注:下面只列出不同的地方,其它参见上面的写法
...
// 方法级配置
List<MethodConfig> methods =newArrayList<MethodConfig>();
MethodConfig method =newMethodConfig();
method.setName("createXxx");
method.setTimeout(10000);
method.setRetries(0);
methods.add(method);
// 引用远程服务
ReferenceConfig<XxxService> reference =newReferenceConfig<XxxService>();// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
...
reference.setMethods(methods);// 设置方法级配置
...
|
...
ReferenceConfig<XxxService> reference =newReferenceConfig<XxxService>();// 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
// 如果点对点直连,可以用reference.setUrl()指定目标地址,设置url后将绕过注册中心,
// 其中,协议对应provider.setProtocol()的值,端口对应provider.setPort()的值,
// 路径对应service.setPath()的值,如果未设置path,缺省path为接口名
reference.setUrl("dubbo://10.20.130.230:20880/com.xxx.XxxService");
...
|
(+) (#)
想完整的运行起来,请参见:快速启动 (+),这里只列出各种场景的配置方式 |
以下示例全部使用基于Spring的Xml配置 (+)作为参考,如果不想使用Spring,而希望通过API的方式进行调用,请参见:API配置 (+) |
(+) (#)
Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。 |
如果你的Spring容器是懒加载的,或者通过API编程延迟引用服务,请关闭check,否则服务临时不可用时,会抛出异常,拿到null引用,如果check=false,总是会返回引用,当服务恢复时,能自动连上。 |
可以通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
关闭某个服务的启动时检查:(没有提供者时报错)
<dubbo:referenceinterface="com.foo.BarService"check="false"/>
|
关闭所有服务的启动时检查:(没有提供者时报错)
<dubbo:consumercheck="false"/>
|
关闭注册中心启动时检查:(注册订阅失败时报错)
<dubbo:registrycheck="false"/>
|
也可以用dubbo.properties配置:
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
|
也可以用-D参数:
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
|
注意区别
|
引用缺省是延迟初始化的,只有引用被注入到其它Bean,或被getBean()获取,才会初始化。
如果需要饥饿加载,即没有人引用也立即生成动态代理,可以配置:
<dubbo:referenceinterface="com.foo.BarService"init="true"/>
|
(+) (#)
在集群调用失败时,Dubbo提供了多种容错方案,缺省为failover重试。 |
各节点关系:
可以自行扩展集群容错策略,参见:集群扩展
Failover Cluster重试次数配置如:(failover集群模式生效)
<dubbo:serviceretries="2"/>
|
或:
<dubbo:referenceretries="2"/>
|
或:
<dubbo:reference>
<dubbo:methodname="findFoo"retries="2"/>
</dubbo:reference>
|
集群模式配置如:
<dubbo:servicecluster="failsafe"/>
|
或:
<dubbo:referencecluster="failsafe"/>
|
(+) (#)
在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。 |
可以自行扩展负载均衡策略,参见:负载均衡扩展
Random LoadBalance配置如:
<dubbo:serviceinterface="..."loadbalance="roundrobin"/>
|
或:
<dubbo:referenceinterface="..."loadbalance="roundrobin"/>
|
或:
<dubbo:serviceinterface="...">
<dubbo:methodname="..."loadbalance="roundrobin"/>
</dubbo:service>
|
或:
<dubbo:referenceinterface="...">
<dubbo:methodname="..."loadbalance="roundrobin"/>
</dubbo:reference>
|
(+) (#)
事件处理线程说明
|
配置如:
<dubbo:protocolname="dubbo"dispatcher="all"threadpool="fixed"threads="100"/>
|
(+) (#)
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,
点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表,
A接口配置点对点,不影响B接口从注册中心获取列表。
(1) 如果是线上需求需要点对点,可在<dubbo:reference>中配置url指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下:(1.0.6及以上版本支持)
<dubbo:reference id="xxxService"interface="com.alibaba.xxx.XxxService"url="dubbo://localhost:20890"/>
|
(2) 在JVM启动参数中加入-D参数映射服务地址,如:
(key为服务名,value为服务提供者url,此配置优先级最高,1.0.15及以上版本支持)
java -Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890
|
注意 为了避免复杂化线上环境,不要在线上使用这个功能,只应在测试阶段使用。 |
(3) 如果服务比较多,也可以用文件映射,如:
(用-Ddubbo.resolve.file指定映射文件路径,此配置优先级高于<dubbo:reference>中的配置,1.0.15及以上版本支持)
(2.0以上版本自动加载${user.home}/dubbo-resolve.properties文件,不需要配置)
java -Ddubbo.resolve.file=xxx.properties
|
然后在映射文件xxx.properties中加入:
(key为服务名,value为服务提供者url)
com.alibaba.xxx.XxxService=dubbo://localhost:20890
|
注意 为了避免复杂化线上环境,不要在线上使用这个功能,只应在测试阶段使用。 |
(+) (#)
问题 为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。 |
解决方案 可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。 |
禁用注册配置:
<dubbo:registryaddress="10.20.153.10:9090"register="false"/>
|
或者:
<dubbo:registryaddress="10.20.153.10:9090?register=false"/>
|
(+) (#)
问题 如果有两个镜像环境,两个注册中心,有一个服务只在其中一个注册中心有部署,另一个注册中心还没来得及部署,而两个注册中心的其它应用都需要依赖此服务,所以需要将服务同时注册到两个注册中心,但却不能让此服务同时依赖两个注册中心的其它服务。 |
解决方案 可以让服务提供者方,只注册服务到另一注册中心,而不从另一注册中心订阅服务。 |
禁用订阅配置:
<dubbo:registryid="hzRegistry"address="10.20.153.10:9090"/>
<dubbo:registryid="qdRegistry"address="10.20.141.150:9090"subscribe="false"/>
|
或者:
<dubbo:registryid="hzRegistry"address="10.20.153.10:9090"/>
<dubbo:registryid="qdRegistry"address="10.20.141.150:9090?subscribe=false"/>
|
(+) (#)
有时候希望人工管理服务提供者的上线和下线,此时需将注册中心标识为非动态管理模式。 |
<dubbo:registryaddress="10.20.141.150:9090"dynamic="false"/>
|
或者:
<dubbo:registryaddress="10.20.141.150:9090?dynamic=false"/>
|
服务提供者初次注册时为禁用状态,需人工启用,断线时,将不会被自动删除,需人工禁用。
如果是一个第三方独立提供者,比如memcached等,可以直接向注册中心写入提供者地址信息,消费者正常使用:
(通常由脚本监控中心页面等调用)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("memcached://10.20.153.11/com.foo.BarService?category=providers&dynamic=false&application=foo"));
|
(+) (#)
可以自行扩展协议,参见:协议扩展
比如:不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议。
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:applicationname="world" />
<dubbo:registryid="registry"address="10.20.141.150:9090"username="admin"password="hello1234"/>
<!-- 多协议配置 -->
<dubbo:protocolname="dubbo"port="20880"/>
<dubbo:protocolname="rmi"port="1099"/>
<!-- 使用dubbo协议暴露服务 -->
<dubbo:serviceinterface="com.alibaba.hello.api.HelloService"version="1.0.0"ref="helloService"protocol="dubbo"/>
<!-- 使用rmi协议暴露服务 -->
<dubbo:serviceinterface="com.alibaba.hello.api.DemoService"version="1.0.0"ref="demoService"protocol="rmi"/>
</beans>
|
比如:需要与http客户端互操作
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:applicationname="world" />
<dubbo:registryid="registry"address="10.20.141.150:9090"username="admin"password="hello1234"/>
<!-- 多协议配置 -->
<dubbo:protocolname="dubbo"port="20880"/>
<dubbo:protocolname="hessian"port="8080"/>
<!-- 使用多个协议暴露服务 -->
<dubbo:serviceid="helloService"interface="com.alibaba.hello.api.HelloService"version="1.0.0"protocol="dubbo,hessian"/>
</beans>
|
(+) (#)
可以自行扩展注册中心,参见:注册中心扩展
比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:applicationname="world" />
<!-- 多注册中心配置 -->
<dubbo:registryid="hangzhouRegistry"address="10.20.141.150:9090"/>
<dubbo:registryid="qingdaoRegistry"address="10.20.141.151:9010"default="false"/>
<!-- 向多个注册中心注册 -->
<dubbo:serviceinterface="com.alibaba.hello.api.HelloService"version="1.0.0"ref="helloService"registry="hangzhouRegistry,qingdaoRegistry"/>
</beans>
|
比如:CRM有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:applicationname="world" />
<!-- 多注册中心配置 -->
<dubbo:registryid="chinaRegistry"address="10.20.141.150:9090"/>
<dubbo:registryid="intlRegistry"address="10.20.154.177:9010"default="false"/>
<!-- 向中文站注册中心注册 -->
<dubbo:serviceinterface="com.alibaba.hello.api.HelloService"version="1.0.0"ref="helloService"registry="chinaRegistry"/>
<!-- 向国际站注册中心注册 -->
<dubbo:serviceinterface="com.alibaba.hello.api.DemoService"version="1.0.0"ref="demoService"registry="intlRegistry"/>
</beans>
|
比如:CRM需同时调用中文站和国际站的PC2服务,PC2在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:applicationname="world" />
<!-- 多注册中心配置 -->
<dubbo:registryid="chinaRegistry"address="10.20.141.150:9090"/>
<dubbo:registryid="intlRegistry"address="10.20.154.177:9010"default="false"/>
<!-- 引用中文站服务 -->
<dubbo:referenceid="chinaHelloService"interface="com.alibaba.hello.api.HelloService"version="1.0.0"registry="chinaRegistry"/>
<!-- 引用国际站站服务 -->
<dubbo:referenceid="intlHelloService"interface="com.alibaba.hello.api.HelloService"version="1.0.0"registry="intlRegistry"/>
</beans>
|
如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址:
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" http://www.springframework.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo=" http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<dubbo:applicationname="world" />
<!-- 多注册中心配置,竖号分隔表示同时连接多个不同注册中心,同一注册中心的多个集群地址用逗号分隔 -->
<dubbo:registryaddress="10.20.141.150:9090|10.20.154.177:9010"/>
<!-- 引用服务 -->
<dubbo:referenceid="helloService"interface="com.alibaba.hello.api.HelloService"version="1.0.0"/>
</beans>
|
(+) (#)
当一个接口有多种实现时,可以用group区分。 |
<dubbo:servicegroup="feedback"interface="com.xxx.IndexService"/>
<dubbo:servicegroup="member"interface="com.xxx.IndexService"/>
|
<dubbo:referenceid="feedbackIndexService"group="feedback"interface="com.xxx.IndexService"/>
<dubbo:referenceid="memberIndexService"group="member"interface="com.xxx.IndexService"/>
|
任意组:(2.2.0以上版本支持,总是只调一个可用组的实现)
<dubbo:referenceid="barService"interface="com.foo.BarService"group="*"/>
|
(+) (#)
当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。 |
<dubbo:serviceinterface="com.foo.BarService"version="1.0.0"/>
|
<dubbo:serviceinterface="com.foo.BarService"version="2.0.0"/>
|
<dubbo:referenceid="barService"interface="com.foo.BarService"version="1.0.0"/>
|
<dubbo:referenceid="barService"interface="com.foo.BarService"version="2.0.0"/>
|
不区分版本:(2.2.0以上版本支持)
<dubbo:referenceid="barService"interface="com.foo.BarService"version="*"/>
|
(+) (#)
按组合并返回结果,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。 |
从2.1.0版本开始支持 |
代码参见:https://github.com/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge
配置如:(搜索所有分组)
<dubbo:referenceinterface="com.xxx.MenuService"group="*"merger="true"/>
|
或:(合并指定分组)
<dubbo:referenceinterface="com.xxx.MenuService"group="aaa,bbb"merger="true"/>
|
或:(指定方法合并结果,其它未指定的方法,将只调用一个Group)
<dubbo:referenceinterface="com.xxx.MenuService"group="*">
<dubbo:methodname="getMenuItems"merger="true"/>
</dubbo:service>
|
或:(某个方法不合并结果,其它都合并结果)
<dubbo:referenceinterface="com.xxx.MenuService"group="*"merger="true">
<dubbo:methodname="getMenuItems"merger="false"/>
</dubbo:service>
|
或:(指定合并策略,缺省根据返回值类型自动匹配,如果同一类型有两个合并器时,需指定合并器的名称)
参见:[合并结果扩展]
<dubbo:referenceinterface="com.xxx.MenuService"group="*">
<dubbo:methodname="getMenuItems"merger="mymerge"/>
</dubbo:service>
|
或:(指定合并方法,将调用返回结果的指定方法进行合并,合并方法的参数类型必须是返回结果类型本身)
<dubbo:referenceinterface="com.xxx.MenuService"group="*">
<dubbo:methodname="getMenuItems"merger=".addAll"/>
</dubbo:service>
|
(+) (#)
参数验证功能是基于JSR303实现的,用户只需标识JSR303标准的验证Annotation,并通过声明filter来实现验证。 |
2.1.0以上版本支持 |
完整示例代码参见:https://github.com/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/validation
验证方式可扩展,参见:Validation扩展点
参数标注示例:
importjava.io.Serializable;
importjava.util.Date;
importjavax.validation.constraints.Future;
importjavax.validation.constraints.Max;
importjavax.validation.constraints.Min;
importjavax.validation.constraints.NotNull;
importjavax.validation.constraints.Past;
importjavax.validation.constraints.Pattern;
importjavax.validation.constraints.Size;
publicclassValidationParameterimplementsSerializable {
privatestaticfinallongserialVersionUID = 7158911668568000392L;
@NotNull// 不允许为空
@Size(min =1, max =20)// 长度或大小范围
privateString name;
@NotNull(groups = ValidationService.Save.class)// 保存时不允许为空,更新时允许为空 ,表示不更新该字段
@Pattern(regexp ="^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
privateString email;
@Min(18)// 最小值
@Max(100)// 最大值
privateintage;
@Past// 必须为一个过去的时间
privateDate loginDate;
@Future// 必须为一个未来的时间
privateDate expiryDate;
publicString getName() {
returnname;
}
publicvoidsetName(String name) {
this.name = name;
}
publicString getEmail() {
returnemail;
}
publicvoidsetEmail(String email) {
this.email = email;
}
publicintgetAge() {
returnage;
}
publicvoidsetAge(intage) {
this.age = age;
}
publicDate getLoginDate() {
returnloginDate;
}
publicvoidsetLoginDate(Date loginDate) {
this.loginDate = loginDate;
}
publicDate getExpiryDate() {
returnexpiryDate;
}
publicvoidsetExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate;
}
}
|
分组验证示例:
publicinterfaceValidationService {// 缺省可按服务接口区分验证场景,如:@NotNull(groups = ValidationService.class)
@interfaceSave{}// 与方法同名接口,首字母大写,用于区分验证场景,如:@NotNull(groups = ValidationService.Save.class),可选
voidsave(ValidationParameter parameter);
voidupdate(ValidationParameter parameter);
}
|
关联验证示例:
importjavax.validation.GroupSequence;
publicinterfaceValidationService {
@GroupSequence(Update.class)// 同时验证Update组规则
@interfaceSave{}
voidsave(ValidationParameter parameter);
@interfaceUpdate{}
voidupdate(ValidationParameter parameter);
}
|
参数验证示例:
importjavax.validation.constraints.Min;
importjavax.validation.constraints.NotNull;
publicinterfaceValidationService {
voidsave(@NotNullValidationParameter parameter);// 验证参数不为空
voiddelete(@Min(1)intid);// 直接对基本类型参数验证
}
|
在客户端验证参数:
<dubbo:referenceid="validationService"interface="com.alibaba.dubbo.examples.validation.api.ValidationService"validation="true"/>
|
在服务器端验证参数:
<dubbo:serviceinterface="com.alibaba.dubbo.examples.validation.api.ValidationService"ref="validationService"validation="true"/>
|
验证异常信息:
importjavax.validation.ConstraintViolationException;
importjavax.validation.ConstraintViolationException;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
importcom.alibaba.dubbo.examples.validation.api.ValidationParameter;
importcom.alibaba.dubbo.examples.validation.api.ValidationService;
importcom.alibaba.dubbo.rpc.RpcException;
publicclassValidationConsumer {
publicstaticvoidmain(String[] args)throwsException {
String config = ValidationConsumer.class.getPackage().getName().replace('.','/') +"/validation-consumer.xml";
ClassPathXmlApplicationContext context =newClassPathXmlApplicationContext(config);
context.start();
ValidationService validationService = (ValidationService)context.getBean("validationService");
// Error
try{
parameter =newValidationParameter();
validationService.save(parameter);
System.out.println("Validation ERROR");
}catch(RpcException e) {// 抛出的是RpcException
ConstraintViolationException ve = (ConstraintViolationException) e.getCause();// 里面嵌了一个ConstraintViolationException
Set<ConstraintViolation<?>> violations = ve.getConstraintViolations();// 可以拿到一个验证错误详细信息的集合
System.out.println(violations);
}
}
}
|
需要加入依赖:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
|
(+) (#)
结果缓存,用于加速热门数据的访问速度,Dubbo提供声明式缓存,以减少用户加缓存的工作量。 |
2.1.0以上版本支持 |
示例代码:https://github.com/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/cache
缓存类型可扩展,参见:CacheFactory扩展点
配置如:
<dubbo:referenceinterface="com.foo.BarService"cache="lru"/>
|
或:
<dubbo:referenceinterface="com.foo.BarService">
<dubbo:methodname="findBar"cache="lru"/>
</dubbo:reference>
|
(+) (#)
泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。 |
<dubbo:referenceid="barService"interface="com.foo.BarService"generic="true"/>
|
GenericService barService = (GenericService) applicationContext.getBean("barService");
Object result = barService.$invoke("sayHello",newString[] {"java.lang.String"},newObject[] {"World"});
|
importcom.alibaba.dubbo.rpc.service.GenericService;
...
// 引用远程服务
ReferenceConfig<GenericService> reference =newReferenceConfig<GenericService>();// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
reference.setInterface("com.xxx.XxxService");// 弱类型接口名
reference.setVersion("1.0.0");
reference.setGeneric(true);// 声明为泛化接口
GenericService genericService = reference.get();// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
// 基本类型以及Date,List,Map等不需要转换,直接调用
Object result = genericService.$invoke("sayHello",newString[] {"java.lang.String"},newObject[] {"world"});
// 用Map表示POJO参数,如果返回值为POJO也将自动转成Map
Map<String, Object> person =newHashMap<String, Object>();
person.put("name","xxx");
person.put("password","yyy");
Object result = genericService.$invoke("findPerson",newString[]{"com.xxx.Person"},newObject[]{person});// 如果返回POJO将自动转成Map
...
|
假设存在POJO如:
packagecom.xxx;
publicclassPersonImplimplementsPerson {
privateString name;
privateString password;
publicString getName() {
returnname;
}
publicvoidsetName(String name) {
this.name = name;
}
publicString getPassword() {
returnpassword;
}
publicvoidsetPassword(String password) {
this.password= password;
}
}
|
则POJO数据:
Person person =newPersonImpl();
person.setName("xxx");
person.setPassword("yyy");
|
可用下面Map表示:
Map<String, Object> map =newHashMap<String, Object>();
map.put("class","com.xxx.PersonImpl");// 注意:如果参数类型是接口,或者List等丢失泛型,可通过class属性指定类型。
map.put("name","xxx");
map.put("password","yyy");
|
(+) (#)
泛接口实现方式主要用于服务器端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的远程服务Mock框架,可通过实现GenericService接口处理所有服务请求。 |
<beanid="genericService"class="com.foo.MyGenericService"/>
<dubbo:serviceinterface="com.foo.BarService"ref="genericService"/>
|
packagecom.foo;
publicclassMyGenericServiceimplementsGenericService {
publicObject $invoke(String methodName, String[] parameterTypes, Object[] args)throwsGenericException {
if("sayHello".equals(methodName)) {
return"Welcome "+ args[0];
}
}
}
|
...
GenericService xxxService =newXxxGenericService();// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口实现
ServiceConfig<GenericService> service =newServiceConfig<GenericService>();// 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
service.setInterface("com.xxx.XxxService");// 弱类型接口名
service.setVersion("1.0.0");
service.setRef(xxxService);// 指向一个通用服务实现
// 暴露及注册服务
service.export();
|
(+) (#)
回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。 |
所有服务自动实现EchoService接口,只需将任意服务引用强制转型为EchoService,即可使用。 |
<dubbo:referenceid="memberService"interface="com.xxx.MemberService"/>
|
MemberService memberService = ctx.getBean("memberService");// 远程服务引用
EchoService echoService = (EchoService) memberService;// 强制转型为EchoService
String status = echoService.$echo("OK");// 回声测试可用性
assert(status.equals("OK"))
|
(+) (#)
上下文中存放的是当前调用过程中所需的环境信息。 |
所有配置信息都将转换为URL的参数,参见《配置项一览表》中的“对应URL参数”一列。 |
注意 RpcContext是一个ThreadLocal的临时状态记录器,当接收到RPC请求,或发起RPC请求时,RpcContext的状态都会变化。 比如:A调B,B再调C,则B机器上,在B调C之前,RpcContext记录的是A调B的信息,在B调C之后,RpcContext记录的是B调C的信息。 |
xxxService.xxx();// 远程调用
booleanisConsumerSide = RpcContext.getContext().isConsumerSide();// 本端是否为消费端,这里会返回true
String serverIP = RpcContext.getContext().getRemoteHost();// 获取最后一次调用的提供方IP地址
String application = RpcContext.getContext().getUrl().getParameter("application");// 获取当前服务配置信息,所有配置信息都将转换为URL的参数
// ...
yyyService.yyy();// 注意:每发起RPC调用,上下文状态会变化
// ...
|
publicclassXxxServiceImplimplementsXxxService {
publicvoidxxx() {// 服务方法实现
booleanisProviderSide = RpcContext.getContext().isProviderSide();// 本端是否为提供端,这里会返回true
String clientIP = RpcContext.getContext().getRemoteHost();// 获取调用方IP地址
String application = RpcContext.getContext().getUrl().getParameter("application");// 获取当前服务配置信息,所有配置信息都将转换为URL的参数
// ...
yyyService.yyy();// 注意:每发起RPC调用,上下文状态会变化
booleanisProviderSide = RpcContext.getContext().isProviderSide();// 此时本端变成消费端,这里会返回false
// ...
}
}
|
(+) (#)
注:path,group,version,dubbo,token,timeout几个key有特殊处理,请使用其它key值。 |
RpcContext.getContext().setAttachment("index","1");// 隐式传参,后面的远程调用都会隐式将这些参数发送到服务器端,类似cookie,用于框架集成,不建议常规业务使用
xxxService.xxx();// 远程调用
// ...
|
【注】 setAttachment设置的KV,在完成下面一次远程调用会被清空。即多次远程调用要多次设置。
publicclassXxxServiceImplimplementsXxxService {
publicvoidxxx() {// 服务方法实现
String index = RpcContext.getContext().getAttachment("index");// 获取客户端隐式传入的参数,用于框架集成,不建议常规业务使用
// ...
}
}
|
(+) (#)
基于NIO的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。 |
2.0.6及其以上版本支持 |
配置声明:
<dubbo:referenceid="fooService"interface="com.alibaba.foo.FooService">
<dubbo:methodname="findFoo"async="true"/>
</dubbo:reference>
<dubbo:referenceid="barService"interface="com.alibaba.bar.BarService">
<dubbo:methodname="findBar"async="true"/>
</dubbo:reference>
|
调用代码:
fooService.findFoo(fooId);// 此调用会立即返回null
Future<Foo> fooFuture = RpcContext.getContext().getFuture();// 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future。
barService.findBar(barId);// 此调用会立即返回null
Future<Bar> barFuture = RpcContext.getContext().getFuture();// 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future。
// 此时findFoo和findBar的请求同时在执行,客户端不需要启动多线程来支持并行,而是借助NIO的非阻塞完成。
Foo foo = fooFuture.get();// 如果foo已返回,直接拿到返回值,否则线程wait住,等待foo返回后,线程会被notify唤醒。
Bar bar = barFuture.get();// 同理等待bar返回。
// 如果foo需要5秒返回,bar需要6秒返回,实际只需等6秒,即可获取到foo和bar,进行接下来的处理。
|
你也可以设置是否等待消息发出:(异步总是不等待返回)
<dubbo:methodname="findFoo"async="true"sent="true"/>
|
如果你只是想异步,完全忽略返回值,可以配置return="false",以减少Future对象的创建和管理成本:
<dubbo:methodname="findFoo"async="true"return="false"/>
|
(+) (#)
本地调用,使用了Injvm协议,是一个伪协议,它不开启端口,不发起远程调用,只在JVM内直接关联,但执行Dubbo的Filter链。 |
Define injvm protocol:
<dubbo:protocolname="injvm"/>
|
Set default protocol:
<dubbo:providerprotocol="injvm"/>
|
Set service protocol:
<dubbo:serviceprotocol="injvm"/>
|
Use injvm first:
<dubbo:consumerinjvm="true".../>
<dubbo:providerinjvm="true".../>
|
或
<dubbo:referenceinjvm="true".../>
<dubbo:serviceinjvm="true".../>
|
注意:服务暴露与服务引用都需要声明injvm="true" |
自动暴露、引用本地服务
从 dubbo 2.2.0 开始,每个服务默认都会在本地暴露;在引用服务的时候,默认优先引用本地服务;如果希望引用远程服务可以使用一下配置强制引用远程服务。
...
<dubbo:reference...scope="remote"/>
...
|
(+) (#)
参数回调方式与调用本地callback或listener相同,只需要在Spring的配置文件中声明哪个参数是callback类型即可,Dubbo将基于长连接生成反向代理,这样就可以从服务器端调用客户端逻辑。 |
2.0.6及其以上版本支持 |
代码参见:https://github.com/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/callback
(1) 共享服务接口:
服务接口示例:
packagecom.callback;
publicinterfaceCallbackService {
voidaddListener(String key, CallbackListener listener);
}
|
packagecom.callback;
publicinterfaceCallbackListener {
voidchanged(String msg);
}
|
(2) 服务提供者:
服务提供者接口实现示例:
packagecom.callback.impl;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Map;
importjava.util.concurrent.ConcurrentHashMap;
importcom.callback.CallbackListener;
importcom.callback.CallbackService;
publicclassCallbackServiceImplimplementsCallbackService {
privatefinalMap<String, CallbackListener> listeners =newConcurrentHashMap<String, CallbackListener>();
publicCallbackServiceImpl() {
Thread t =newThread(newRunnable() {
publicvoidrun() {
while(true) {
try{
for(Map.Entry<String, CallbackListener> entry : listeners.entrySet()){
try{
entry.getValue().changed(getChanged(entry.getKey()));
}catch(Throwable t) {
listeners.remove(entry.getKey());
}
}
Thread.sleep(5000);// 定时触发变更通知
}catch(Throwable t) {// 防御容错
t.printStackTrace();
}
}
}
});
t.setDaemon(true);
t.start();
}
publicvoidaddListener(String key, CallbackListener listener) {
listeners.put(key, listener);
listener.changed(getChanged(key));// 发送变更通知
}
privateString getChanged(String key) {
return"Changed: "+newSimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate());
}
}
|
服务提供者配置示例:
<beanid="callbackService"class="com.callback.impl.CallbackServiceImpl"/>
<dubbo:serviceinterface="com.callback.CallbackService"ref="callbackService"connections="1"callbacks="1000">
<dubbo:methodname="addListener">
<dubbo:argumentindex="1"callback="true"/>
<!--也可以通过指定类型的方式-->
<!--<dubbo:argument type="com.demo.CallbackListener" callback="true" />-->
</dubbo:method>
</dubbo:service>
|
(2) 服务消费者:
服务消费者配置示例:
<dubbo:referenceid="callbackService"interface="com.callback.CallbackService"/>
|
服务消费者调用示例:
ClassPathXmlApplicationContext context =newClassPathXmlApplicationContext("classpath:consumer.xml");
context.start();
CallbackService callbackService = (CallbackService) context.getBean("callbackService");
callbackService.addListener("foo.bar",newCallbackListener(){
publicvoidchanged(String msg) {
System.out.println("callback1:"+ msg);
}
});
|
(+) (#)
在调用之前,调用之后,出现异常时,会触发oninvoke, onreturn, onthrow三个事件,可以配置当事件发生时,通知哪个类的哪个方法。 |
支持版本:2.0.7之后 |
(1) 服务提供者与消费者共享服务接口:
interfaceIDemoService {
publicPerson get(intid);
}
|
(2) 服务提供者实现:
classNormalDemoServiceimplementsIDemoService {
publicPerson get(intid) {
returnnewPerson(id,"charles`son",4);
}
}
|
(3) 服务提供者配置:
<dubbo:applicationname="rpc-callback-demo"/>
<dubbo:registryaddress="10.20.153.186"/>
<beanid="demoService"class="com.alibaba.dubbo.callback.implicit.NormalDemoService"/>
<dubbo:serviceinterface="com.alibaba.dubbo.callback.implicit.IDemoService"ref="demoService"version="1.0.0"group="cn"/>
|
(4) 服务消费者Callback接口及实现:
interfaceNofify {
publicvoidonreturn(Person msg, Integer id);
publicvoidonthrow(Throwable ex, Integer id);
}
|
classNofifyImplimplementsNofify {
publicMap<Integer, Person> ret =newHashMap<Integer, Person>();
publicMap<Integer, Throwable> errors =newHashMap<Integer, Throwable>();
publicvoidonreturn(Person msg, Integer id) {
System.out.println("onreturn:"+ msg);
ret.put(id, msg);
}
publicvoidonthrow(Throwable ex, Integer id) {
errors.put(id, ex);
}
}
|
(5) 服务消费者Callback接口及实现:
<beanid="demoCallback"class="com.alibaba.dubbo.callback.implicit.NofifyImpl"/>
<dubbo:referenceid="demoService"interface="com.alibaba.dubbo.callback.implicit.IDemoService"version="1.0.0"group="cn">
<dubbo:methodname="get"async="true"onreturn="demoCallback.onreturn"onthrow="demoCallback.onthrow"/>
</dubbo:reference>
|
注: callback与async功能正交分解: async=true,表示结果是否马上返回. onreturn 表示是否需要回调. 组合情况:(async=false 默认) |
(6) TEST CASE:
IDemoService demoService = (IDemoService) context.getBean("demoService");
NofifyImpl notify = (NofifyImpl) context.getBean("demoCallback");
intrequestId =2;
Person ret = demoService.get(requestId);
Assert.assertEquals(null, ret);
//for Test:只是用来说明callback正常被调用,业务具体实现自行决定.
for(inti =0; i <10; i++) {
if(!notify.ret.containsKey(requestId)) {
Thread.sleep(200);
}else{
break;
}
}
Assert.assertEquals(requestId, notify.ret.get(requestId).getId());
|
(+) (#)
远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做ThreadLocal缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在API中带上Stub,客户端生成Proxy实,会把Proxy通过构造函数传给Stub,然后把Stub暴露组给用户,Stub可以决定要不要去调Proxy。 |
Stub必须有可传入Proxy的构造函数。 |
<dubbo:serviceinterface="com.foo.BarService"stub="true"/>
|
Or:
<dubbo:serviceinterface="com.foo.BarService"stub="com.foo.BarServiceStub"/>
|
api.jar:
com.foo.BarService
com.foo.BarServiceStub // 在API旁边放一个Stub实现,它实现BarService接口,并有一个传入远程BarService实例的构造函数
|
packagecom.foo
publicclassBarServiceStubimplementsBarService {
privatefinalBarService barService;
// 构造函数传入真正的远程代理对象
public(BarService barService) {
this.barService = barService;
}
publicString sayHello(String name) {
// 此代码在客户端执行
// 你可以在客户端做ThreadLocal本地缓存,或预先验证参数是否合法,等等
try{
returnbarService.sayHello(name);
}catch(Exception e) {
// 你可以容错,可以做任何AOP拦截事项
return"容错数据";
}
}
}
|
(+) (#)
Mock通常用于服务降级,比如某验权服务,当服务提供方全部挂掉后,客户端不抛出异常,而是通过Mock数据返回授权失败。 |
Mock是Stub的一个子集,便于服务提供方在客户端执行容错逻辑,因经常需要在出现RpcException(比如网络失败,超时等)时进行容错,而在出现业务异常(比如登录用户名密码错误)时不需要容错,如果用Stub,可能就需要捕获并依赖RpcException类,而用Mock就可以不依赖RpcException,因为它的约定就是只有出现RpcException时才执行。 |
<dubbo:serviceinterface="com.foo.BarService"mock="true"/>
|
Or:
<dubbo:serviceinterface="com.foo.BarService"mock="com.foo.BarServiceMock"/>
|
api.jar:
com.foo.BarService
com.foo.BarServiceMock // 在API旁边放一个Mock实现,它实现BarService接口,并有一个无参构造函数
|
packagecom.foo
publicclassBarServiceMockimplementsBarService {
publicString sayHello(String name) {
// 你可以伪造容错数据,此方法只在出现RpcException时被执行
return"容错数据";
}
}
|
如果服务的消费方经常需要try-catch捕获异常,如:
Offer offer =null;
try{
offer = offerService.findOffer(offerId);
}catch(RpcException e) {
logger.error(e);
}
|
请考虑改为Mock实现,并在Mock中return null。
如果只是想简单的忽略异常,在2.0.11以上版本可用:
<dubbo:serviceinterface="com.foo.BarService"mock="return null"/>
|
(+) (#)
如果你的服务需要Warmup时间,比如初始化缓存,等待相关资源就位等,可以使用delay进行延迟暴露。 |
延迟5秒暴露服务:
<dubbo:servicedelay="5000"/>
|
延迟到Spring初始化完成后,再暴露服务:(基于Spring的ContextRefreshedEvent事件触发暴露)
<dubbo:servicedelay="-1"/>
|
Spring2.x初始化死锁问题 在Spring解析到<dubbo:service />时,就已经向外暴露了服务,而Spring还在接着初始化其它Bean。 如果这时有请求进来,并且服务的实现类里有调用applicationContext.getBean()的用法。 1. 请求线程的applicationContext.getBean()调用,先同步singletonObjects判断Bean是否存在,不存在就同步beanDefinitionMap进行初始化,并再次同步singletonObjects写入Bean实例缓存。 这样就导致getBean线程,先锁singletonObjects,再锁beanDefinitionMap,再次锁singletonObjects。 |
规避办法 1. 强烈建议不要在服务的实现类中有applicationContext.getBean()的调用,全部采用IoC注入的方式使用Spring的Bean。 2. 如果实在要调getBean(),可以将Dubbo的配置放在Spring的最后加载。 3. 如果不想依赖配置顺序,可以使用<dubbo:provider deplay=”-1” />,使Dubbo在Spring容器初始化完后,再暴露服务。 4. 如果大量使用getBean(),相当于已经把Spring退化为工厂模式在用,可以将Dubbo的服务隔离单独的Spring容器。 |
(+) (#)
限制com.foo.BarService的每个方法,服务器端并发执行(或占用线程池线程数)不能超过10个:
<dubbo:serviceinterface="com.foo.BarService"executes="10"/>
|
限制com.foo.BarService的sayHello方法,服务器端并发执行(或占用线程池线程数)不能超过10个:
<dubbo:serviceinterface="com.foo.BarService">
<dubbo:methodname="sayHello"executes="10"/>
</dubbo:service>
|
限制com.foo.BarService的每个方法,每客户端并发执行(或占用连接的请求数)不能超过10个:
<dubbo:serviceinterface="com.foo.BarService"actives="10"/>
|
Or:
<dubbo:referenceinterface="com.foo.BarService"actives="10"/>
|
限制com.foo.BarService的sayHello方法,每客户端并发执行(或占用连接的请求数)不能超过10个:
<dubbo:serviceinterface="com.foo.BarService">
<dubbo:methodname="sayHello"actives="10"/>
</dubbo:service>
|
Or:
<dubbo:referenceinterface="com.foo.BarService">
<dubbo:methodname="sayHello"actives="10"/>
</dubbo:service>
|
如果<dubbo:service>和<dubbo:reference>都配了actives,<dubbo:reference>优先,参见:配置的覆盖策略。
Load Balance均衡:
配置服务的客户端的loadbalance属性为leastactive,此Loadbalance会调用并发数最小的Provider(Consumer端并发数)。
<dubbo:referenceinterface="com.foo.BarService"loadbalance="leastactive"/>
|
Or:
<dubbo:serviceinterface="com.foo.BarService"loadbalance="leastactive"/>
|
(+) (#)
限制服务器端接受的连接不能超过10个:(以连接在Server上,所以配置在Provider上)
<dubbo:providerprotocol="dubbo"accepts="10"/>
|
<dubbo:protocolname="dubbo"accepts="10"/>
|
限制客户端服务使用连接连接数:(如果是长连接,比如Dubbo协议,connections表示该服务对每个提供者建立的长连接数)
<dubbo:referenceinterface="com.foo.BarService"connections="10"/>
|
Or:
<dubbo:serviceinterface="com.foo.BarService"connections="10"/>
|
如果<dubbo:service>和<dubbo:reference>都配了connections,<dubbo:reference>优先,参见:配置的覆盖策略。
(+) (#)
延迟连接,用于减少长连接数,当有调用发起时,再创建长连接。 |
只对使用长连接的dubbo协议生效。 |
<dubbo:protocolname="dubbo"lazy="true"/>
|
(+) (#)
粘滞连接用于有状态服务,尽可能让客户端总是向同一提供者发起调用,除非该提供者挂了,再连另一台。 |
粘滞连接将自动开启延迟连接,以减少长连接数,参见:延迟连接 (+) |
<dubbo:protocolname="dubbo"sticky="true"/>
|
(+) (#)
可以全局设置开启令牌验证:
<!--随机token令牌,使用UUID生成-->
<dubbo:providerinterface="com.foo.BarService"token="true"/>
|
<!--固定token令牌,相当于密码-->
<dubbo:providerinterface="com.foo.BarService"token="123456"/>
|
也可在服务级别设置:
<!--随机token令牌,使用UUID生成-->
<dubbo:serviceinterface="com.foo.BarService"token="true"/>
|
<!--固定token令牌,相当于密码-->
<dubbo:serviceinterface="com.foo.BarService"token="123456"/>
|
还可在协议级别设置:
<!--随机token令牌,使用UUID生成-->
<dubbo:protocolname="dubbo"token="true"/>
|
<!--固定token令牌,相当于密码-->
<dubbo:protocolname="dubbo"token="123456"/>
|
(+) (#)
2.2.0以上版本支持 |
路由规则扩展点:路由扩展 |
向注册中心写入路由规则:(通常由监控中心或治理中心的页面完成)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("condition://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule="+ URL.encode("host = 10.20.153.10 => host = 10.20.153.11") + "));
|
其中:
(#)
基于条件表达式的路由规则,如:
host =10.20.153.10=> host =10.20.153.11
|
规则:
表达式:
示例:
1. 排除预发布机:
=> host !=172.22.3.91
|
2. 白名单:(注意:一个服务只能有一条白名单规则,否则两条规则交叉,就都被筛选掉了)
host !=10.20.153.10,10.20.153.11=>
|
3. 黑名单:
host =10.20.153.10,10.20.153.11=>
|
4. 服务寄宿在应用上,只暴露一部分的机器,防止整个集群挂掉:
=> host =172.22.3.1*,172.22.3.2*
|
5. 为重要应用提供额外的机器:
application != kylin => host !=172.22.3.95,172.22.3.96
|
6. 读写分离:
method = find*,list*,get*,is* => host =172.22.3.94,172.22.3.95,172.22.3.96
|
method != find*,list*,get*,is* => host =172.22.3.97,172.22.3.98
|
7. 前后台分离:
application = bops => host =172.22.3.91,172.22.3.92,172.22.3.93
|
application != bops => host =172.22.3.94,172.22.3.95,172.22.3.96
|
8. 隔离不同机房网段:
host !=172.22.3.* => host !=172.22.3.*
|
9. 提供者与消费者部署在同集群内,本机只访问本机的服务:
=> host = $host
|
(#)
支持JDK脚本引擎的所有脚本,比如:javascript,jruby,groovy等,通过type=javascript参数设置脚本类型,缺省为javascript。 |
脚本没有沙箱约束,可执行任意代码,存在后门风险 |
"script://0.0.0.0/com.foo.BarService?category=routers&dynamic=false&rule="+ URL.encode("function route(invokers) { ... } (invokers)")
|
基于脚本引擎的路由规则,如:
functionroute(invokers) {
varresult =newjava.util.ArrayList(invokers.size());
for(i = 0; i < invokers.size(); i ++) {
if("10.20.153.10".equals(invokers.get(i).getUrl().getHost())) {
result.add(invokers.get(i));
}
}
returnresult;
} (invokers);// 表示立即执行方法
|
(+) (#)
2.2.0以上版本支持 |
向注册中心写入动态配置覆盖规则:(通常由监控中心或治理中心的页面完成)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&timeout=1000"));
|
其中:
示例:
1. 禁用提供者:(通常用于临时踢除某台提供者机器,相似的,禁止消费者访问请使用路由规则)
override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&disbaled=true
|
2. 调整权重:(通常用于容量评估,缺省权重为100)
override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&weight=200
|
3. 调整负载均衡策略:(缺省负载均衡策略为random)
override://10.20.153.10/com.foo.BarService?category=configurators&dynamic=false&loadbalance=leastactive
|
4. 服务降级:(通常用于临时屏蔽某个出错的非关键服务)
override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null
|
(+) (#)
2.2.0以上版本支持 |
参见:配置规则 |
向注册中心写入动态配置覆盖规则:(通过由监控中心或治理中心的页面完成)
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));
|
其中:
mock=force:return+null
|
还可以改为:
mock=fail:return+null
|
(+) (#)
Dubbo是通过JDK的ShutdownHook来完成优雅停机的,所以如果用户使用"kill -9 PID"等强制关闭指令,是不会执行优雅停机的,只有通过"kill PID"时,才会执行。 |
原理:
设置优雅停机超时时间,缺省超时时间是10秒:(超时则强制关闭)
<dubbo:application...>
<dubbo:parameterkey="shutdown.timeout"value="60000"/><!-- 单位毫秒 -->
</dubbo:application>
|
如果ShutdownHook不能生效,可以自行调用:
ProtocolConfig.destroyAll();
|
(+) (#)
缺省主机IP查找顺序:
注册的地址如果获取不正确,比如需要注册公网地址,可以:
1. 可以在/etc/hosts中加入:机器名 公网IP,比如:
test1205.182.23.201
|
2. 在dubbo.xml中加入主机地址的配置:
<dubbo:protocolhost="205.182.23.201">
|
3. 或在dubbo.properties中加入主机地址的配置:
dubbo.protocol.host=205.182.23.201
|
缺省主机端口与协议相关:
主机端口配置:
1. 在dubbo.xml中加入主机地址的配置:
<dubbo:protocolname="dubbo"port="20880">
|
3. 或在dubbo.properties中加入主机地址的配置:
dubbo.protocol.dubbo.port=20880
|
(+) (#)
2.2.1以上版本支持 |
扩展点:日志适配扩展 |
缺省自动查找:
可以通过以下方式配置日志输出策略:
java -Ddubbo.application.logger=log4j
|
dubbo.application.logger=log4j
|
<dubbo:application logger="log4j"/>
|
(+) (#)
如果你想记录每一次请求信息,可开启访问日志,类似于apache的访问日志。 |
此日志量比较大,请注意磁盘容量。 |
将访问日志输出到当前应用的log4j日志:
<dubbo:protocolaccesslog="true"/>
|
将访问日志输出到指定文件:
<dubbo:protocolaccesslog="foo/bar.log"/>
|
(+) (#)
服务容器是一个standalone的启动程序,因为后台服务不需要Tomcat或JBoss等Web容器的功能,如果硬要用Web容器去加载服务提供方,增加复杂性,也浪费资源。 |
服务容器只是一个简单的Main方法,并加载一个简单的Spring容器,用于暴露服务。 |
服务容器的加载内容可以扩展,内置了spring, jetty, log4j等加载,可通过Container扩展点进行扩展,参见:Container |
容器启动
如:(缺省只加载spring)
java com.alibaba.dubbo.container.Main
|
或:(通过main函数参数传入要加载的容器)
java com.alibaba.dubbo.container.Main spring jetty log4j
|
或:(通过JVM启动参数传入要加载的容器)
java com.alibaba.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j
|
或:(通过classpath下的dubbo.properties配置传入要加载的容器)
dubbo.container=spring,jetty,log4j
|
(+) (#)
ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。API方式编程时,容易忽略此问题。
Dubbo 2.4.0+版本,提供了简单的工具类ReferenceConfigCache用于缓存ReferenceConfig实例。
使用方式如下:
ReferenceConfig<XxxService> reference =newReferenceConfig<XxxService>();
reference.setInterface(XxxService.class);
reference.setVersion("1.0.0");
......
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
XxxService xxxService = cache.get(reference);// cache.get方法中会Cache Reference对象,并且调用ReferenceConfig.get方法启动ReferenceConfig
// 注意! Cache会持有ReferenceConfig,不要在外部再调用ReferenceConfig的destroy方法,导致Cache内的ReferenceConfig失效!
// 使用xxxService对象
xxxService.sayHello();
|
消除Cache中的ReferenceConfig,销毁ReferenceConfig并释放对应的资源。
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
cache.destroy(reference);
|
缺省ReferenceConfigCache把相同服务Group、接口、版本的ReferenceConfig认为是相同,缓存一份。即以服务Group、接口、版本为缓存的Key。
可以修改这个策略,在ReferenceConfigCache.getCache时,传一个KeyGenerator。详见ReferenceConfigCache类的方法。
KeyGenerator keyGenerator =new...
ReferenceConfigCache cache = ReferenceConfigCache.getCache(keyGenerator );
|
(+) (#)
基于JTA/XA规范实现。 |
暂未实现。 |
两阶段提交:
(+) (#)
Dubbo的常规功能,都保持零侵入,但有些功能不得不用API侵入才能实现。 |
Dubbo中除这里声明以外的接口或类,都是内部接口或扩展接口,普通用户请不要直接依赖,否则升级版本可能出现不兼容。 |
API汇总如下:
(+) (#)
这里以Xml配置为准,列举所有配置项,其它配置方式,请参见相应转换关系:属性配置,注解配置,API配置 |
注意:只有group,interface,version是服务的匹配条件,三者决定是不是同一个服务,其它配置项均为调优和治理参数。
所有配置项分为三大类,参见下表中的"作用"一列。
所有配置最终都将转换为URL表示,并由服务提供方生成,经注册中心传递给消费方,各属性对应URL的参数,参见配置项一览表中的"对应URL参数"列。
URL格式:
protocol://username:password@host:port/path?key=value&key=value
Schema: http://code.alibabatech.com/schema/dubbo/dubbo.xsd
(+) (#)
服务提供者暴露服务配置:
配置类:com.alibaba.dubbo.config.ServiceConfig
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:service> | interface | class | 必填 | 服务发现 | 服务接口名 | 1.0.0以上版本 | ||
<dubbo:service> | ref | object | 必填 | 服务发现 | 服务对象实现引用 | 1.0.0以上版本 | ||
<dubbo:service> | version | version | string | 可选 | 0.0.0 | 服务发现 | 服务版本,建议使用两位数字版本,如:1.0,通常在接口不兼容时版本号才需要升级 | 1.0.0以上版本 |
<dubbo:service> | group | group | string | 可选 | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分 | 1.0.7以上版本 | |
<dubbo:service> | path | <path> | string | 可选 | 缺省为接口名 | 服务发现 | 服务路径 (注意:1.0不支持自定义路径,总是使用接口名,如果有1.0调2.0,配置服务路径可能不兼容) | 1.0.12以上版本 |
<dubbo:service> | delay | delay | int | 可选 | 0 | 性能调优 | 延迟注册服务时间(毫秒) ,设为-1时,表示延迟到Spring容器初始化完成时暴露服务 | 1.0.14以上版本 |
<dubbo:service> | timeout | timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 2.0.0以上版本 |
<dubbo:service> | retries | retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 |
<dubbo:service> | connections | connections | int | 可选 | 100 | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.0以上版本 |
<dubbo:service> | loadbalance | loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用 | 2.0.0以上版本 |
<dubbo:service> | async | async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 |
<dubbo:service> | stub | stub | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Local后缀,服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceLocal(XxxService xxxService) | 2.0.0以上版本 |
<dubbo:service> | mock | mock | class/boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省Mock类名,即:接口名 + Mock后缀,服务接口调用失败Mock实现类,该Mock类必须有一个无参构造函数,与Local的区别在于,Local总是被执行,而Mock只在出现非业务异常(比如超时,网络异常等)时执行,Local在远程调用之前执行,Mock在远程调用后执行。 | 2.0.0以上版本 |
<dubbo:service> | token | token | string/boolean | 可选 | false | 服务治理 | 令牌验证,为空表示不开启,如果为true,表示随机生成动态令牌,否则使用静态令牌,令牌的作用是防止消费者绕过注册中心直接访问,保证注册中心的授权功能有效,如果使用点对点调用,需关闭令牌功能 | 2.0.0以上版本 |
<dubbo:service> | registry | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.0以上版本 | |
<dubbo:service> | provider | string | 可选 | 缺使用第一个provider配置 | 配置关联 | 指定provider,值为<dubbo:provider>的id属性 | 2.0.0以上版本 | |
<dubbo:service> | deprecated | deprecated | boolean | 可选 | false | 服务治理 | 服务是否过时,如果设为true,消费方引用时将打印服务过时警告error日志 | 2.0.5以上版本 |
<dubbo:service> | dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示后disable状态,需人工启用,并且服务提供者停止时,也不会自动取消册,需人工禁用。 | 2.0.5以上版本 |
<dubbo:service> | accesslog | accesslog | string/boolean | 可选 | false | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 |
<dubbo:service> | owner | owner | string | 可选 | 服务治理 | 服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | |
<dubbo:service> | document | document | string | 可选 | 服务治理 | 服务文档URL | 2.0.5以上版本 | |
<dubbo:service> | weight | weight | int | 可选 | 性能调优 | 服务权重 | 2.0.5以上版本 | |
<dubbo:service> | executes | executes | int | 可选 | 0 | 性能调优 | 服务提供者每服务每方法最大可并行执行请求数 | 2.0.5以上版本 |
<dubbo:service> | actives | actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 |
<dubbo:service> | proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 |
<dubbo:service> | cluster | cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:service> | filter | service.filter | string | 可选 | default | 性能调优 | 服务提供方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 |
<dubbo:service> | listener | exporter.listener | string | 可选 | default | 性能调优 | 服务提供方导出服务监听器名称,多个名称用逗号分隔 | |
<dubbo:service> | protocol | string | 可选 | 配置关联 | 使用指定的协议暴露服务,在多协议时使用,值为<dubbo:protocol>的id属性,多个协议ID用逗号分隔 | 2.0.5以上版本 | ||
<dubbo:service> | layer | layer | string | 可选 | 服务治理 | 服务提供者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | |
<dubbo:service> | register | register | boolean | 可选 | true | 服务治理 | 该协议的服务是否注册到注册中心 | 2.0.8以上版本 |
(+) (#)
服务消费者引用服务配置:
配置类:com.alibaba.dubbo.config.ReferenceConfig
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:reference> | id | string | 必填 | 配置关联 | 服务引用BeanId | 1.0.0以上版本 | ||
<dubbo:reference> | interface | class | 必填 | 服务发现 | 服务接口名 | 1.0.0以上版本 | ||
<dubbo:reference> | version | version | string | 可选 | 服务发现 | 服务版本,与服务提供者的版本一致 | 1.0.0以上版本 | |
<dubbo:reference> | group | group | string | 可选 | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分,必需和服务提供方一致 | 1.0.7以上版本 | |
<dubbo:reference> | timeout | timeout | long | 可选 | 缺省使用<dubbo:consumer>的timeout | 性能调优 | 服务方法调用超时时间(毫秒) | 1.0.5以上版本 |
<dubbo:reference> | retries | retries | int | 可选 | 缺省使用<dubbo:consumer>的retries | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 |
<dubbo:reference> | connections | connections | int | 可选 | 缺省使用<dubbo:consumer>的connections | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.0以上版本 |
<dubbo:reference> | loadbalance | loadbalance | string | 可选 | 缺省使用<dubbo:consumer>的loadbalance | 性能调优 | 负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用 | 2.0.0以上版本 |
<dubbo:reference> | async | async | boolean | 可选 | 缺省使用<dubbo:consumer>的async | 性能调优 | 是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 |
<dubbo:reference> | generic | generic | boolean | 可选 | 缺省使用<dubbo:consumer>的generic | 服务治理 | 是否缺省泛化接口,如果为泛化接口,将返回GenericService | 2.0.0以上版本 |
<dubbo:reference> | check | check | boolean | 可选 | 缺省使用<dubbo:consumer>的check | 服务治理 | 启动时检查提供者是否存在,true报错,false忽略 | 2.0.0以上版本 |
<dubbo:reference> | url | <url> | string | 可选 | 服务治理 | 点对点直连服务提供者地址,将绕过注册中心 | 1.0.6以上版本 | |
<dubbo:reference> | stub | stub | class/boolean | 可选 | 服务治理 | 服务接口客户端本地代理类名,用于在客户端执行本地逻辑,如本地缓存等,该本地代理类的构造函数必须允许传入远程代理对象,构造函数如:public XxxServiceLocal(XxxService xxxService) | 2.0.0以上版本 | |
<dubbo:reference> | mock | mock | class/boolean | 可选 | 服务治理 | 服务接口调用失败Mock实现类名,该Mock类必须有一个无参构造函数,与Local的区别在于,Local总是被执行,而Mock只在出现非业务异常(比如超时,网络异常等)时执行,Local在远程调用之前执行,Mock在远程调用后执行。 | Dubbo1.0.13及其以上版本支持 | |
<dubbo:reference> | cache | cache | string/boolean | 可选 | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:reference> | validation | validation | boolean | 可选 | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:reference> | proxy | proxy | boolean | 可选 | javassist | 性能调优 | 选择动态代理实现策略,可选:javassist, jdk | 2.0.2以上版本 |
<dubbo:reference> | client | client | string | 可选 | 性能调优 | 客户端传输类型设置,如Dubbo协议的netty或mina。 | Dubbo2.0.0以上版本支持 | |
<dubbo:reference> | registry | string | 可选 | 缺省将从所有注册中心获服务列表后合并结果 | 配置关联 | 从指定注册中心注册获取服务列表,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔 | 2.0.0以上版本 | |
<dubbo:reference> | owner | owner | string | 可选 | 服务治理 | 调用服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | |
<dubbo:reference> | actives | actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 |
<dubbo:reference> | cluster | cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:reference> | filter | reference.filter | string | 可选 | default | 性能调优 | 服务消费方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 |
<dubbo:reference> | listener | invoker.listener | string | 可选 | default | 性能调优 | 服务消费方引用服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 |
<dubbo:reference> | layer | layer | string | 可选 | 服务治理 | 服务调用者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | |
<dubbo:reference> | init | init | boolean | 可选 | false | 性能调优 | 是否在afterPropertiesSet()时饥饿初始化引用,否则等到有人注入或引用该实例时再初始化。 | 2.0.10以上版本 |
<dubbo:reference> | protocol | protocol | string | 可选 | 服力治理 | 只调用指定协议的服务提供方,其它协议忽略。 | 2.2.0以上版本 |
(+) (#)
服务提供者协议配置:
配置类:com.alibaba.dubbo.config.ProtocolConfig
说明:如果需要支持多协议,可以声明多个<dubbo:protocol>标签,并在<dubbo:service>中通过protocol属性指定使用的协议。
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:protocol> | id | string | 可选 | dubbo | 配置关联 | 协议BeanId,可以在<dubbo:service protocol="">中引用此ID,如果ID不填,缺省和name属性值一样,重复则在name后加序号。 | 2.0.5以上版本 | |
<dubbo:protocol> | name | <protocol> | string | 必填 | dubbo | 性能调优 | 协议名称 | 2.0.5以上版本 |
<dubbo:protocol> | port | <port> | int | 可选 | dubbo协议缺省端口为20880,rmi协议缺省端口为1099,http和hessian协议缺省端口为80 如果配置为-1 或者 没有配置port,则会分配一个没有被占用的端口。Dubbo 2.4.0+,分配的端口在协议缺省端口的基础上增长,确保端口段可控。 |
服务发现 | 服务端口 | 2.0.5以上版本 |
<dubbo:protocol> | host | <host> | string | 可选 | 自动查找本机IP | 服务发现 | -服务主机名,多网卡选择或指定VIP及域名时使用,为空则自动查找本机IP,-建议不要配置,让Dubbo自动获取本机IP | 2.0.5以上版本 |
<dubbo:protocol> | threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached | 2.0.5以上版本 |
<dubbo:protocol> | threads | threads | int | 可选 | 100 | 性能调优 | 服务线程池大小(固定大小) | 2.0.5以上版本 |
<dubbo:protocol> | iothreads | threads | int | 可选 | cpu个数+1 | 性能调优 | io线程池大小(固定大小) | 2.0.5以上版本 |
<dubbo:protocol> | accepts | accepts | int | 可选 | 0 | 性能调优 | 服务提供方最大可接受连接数 | 2.0.5以上版本 |
<dubbo:protocol> | payload | payload | int | 可选 | 88388608(=8M) | 性能调优 | 请求及响应数据包大小限制,单位:字节 | 2.0.5以上版本 |
<dubbo:protocol> | codec | codec | string | 可选 | dubbo | 性能调优 | 协议编码方式 | 2.0.5以上版本 |
<dubbo:protocol> | serialization | serialization | string | 可选 | dubbo协议缺省为hessian2,rmi协议缺省为java,http协议缺省为json | 性能调优 | 协议序列化方式,当协议支持多种序列化方式时使用,比如:dubbo协议的dubbo,hessian2,java,compactedjava,以及http协议的json等 | 2.0.5以上版本 |
<dubbo:protocol> | accesslog | accesslog | string/boolean | 可选 | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 | |
<dubbo:protocol> | path | <path> | string | 可选 | 服务发现 | 提供者上下文路径,为服务path的前缀 | 2.0.5以上版本 | |
<dubbo:protocol> | transporter | transporter | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的服务端和客户端实现类型,比如:dubbo协议的mina,netty等,可以分拆为server和client配置 | 2.0.5以上版本 |
<dubbo:protocol> | server | server | string | 可选 | dubbo协议缺省为netty,http协议缺省为servlet | 性能调优 | 协议的服务器端实现类型,比如:dubbo协议的mina,netty等,http协议的jetty,servlet等 | 2.0.5以上版本 |
<dubbo:protocol> | client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.5以上版本 |
<dubbo:protocol> | dispatcher | dispatcher | string | 可选 | dubbo协议缺省为all | 性能调优 | 协议的消息派发方式,用于指定线程模型,比如:dubbo协议的all, direct, message, execution, connection等 | 2.1.0以上版本 |
<dubbo:protocol> | queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程程池时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 |
<dubbo:protocol> | charset | charset | string | 可选 | UTF-8 | 性能调优 | 序列化编码 | 2.0.5以上版本 |
<dubbo:protocol> | buffer | buffer | int | 可选 | 8192 | 性能调优 | 网络读写缓冲区大小 | 2.0.5以上版本 |
<dubbo:protocol> | heartbeat | heartbeat | int | 可选 | 0 | 性能调优 | 心跳间隔,对于长连接,当物理层断开时,比如拔网线,TCP的FIN消息来不及发送,对方收不到断开事件,此时需要心跳来帮助检查连接是否已断开 | 2.0.10以上版本 |
<dubbo:protocol> | telnet | telnet | string | 可选 | 服务治理 | 所支持的telnet命令,多个命令用逗号分隔 | 2.0.5以上版本 | |
<dubbo:protocol> | register | register | boolean | 可选 | true | 服务治理 | 该协议的服务是否注册到注册中心 | 2.0.8以上版本 |
<dubbo:protocol> | contextpath | contextpath | String | 可选 | 缺省为空串 | 服务治理 | 2.0.6以上版本 |
(+) (#)
注册中心配置:
配置类:com.alibaba.dubbo.config.RegistryConfig
说明:如果有多个不同的注册中心,可以声明多个<dubbo:registry>标签,并在<dubbo:service>或<dubbo:reference>的registry属性指定使用的注册中心。
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:registry> | id | string | 可选 | 配置关联 | 注册中心引用BeanId,可以在<dubbo:service registry="">或<dubbo:reference registry="">中引用此ID | 1.0.16以上版本 | ||
<dubbo:registry> | address | <host:port> | string | 必填 | 服务发现 | 注册中心服务器地址,如果地址没有端口缺省为9090,同一集群内的多个地址用逗号分隔,如:ip:port,ip:port,不同集群的注册中心,请配置多个<dubbo:registry>标签 | 1.0.16以上版本 | |
<dubbo:registry> | protocol | <protocol> | string | 可选 | dubbo | 服务发现 | 注同中心地址协议,支持dubbo, http, local三种协议,分别表示,dubbo地址,http地址,本地注册中心 | 2.0.0以上版本 |
<dubbo:registry> | port | <port> | int | 可选 | 9090 | 服务发现 | 注册中心缺省端口,当address没有带端口时使用此端口做为缺省值 | 2.0.0以上版本 |
<dubbo:registry> | username | <username> | string | 可选 | 服务治理 | 登录注册中心用户名,如果注册中心不需要验证可不填 | 2.0.0以上版本 | |
<dubbo:registry> | password | <password> | string | 可选 | 服务治理 | 登录注册中心密码,如果注册中心不需要验证可不填 | 2.0.0以上版本 | |
<dubbo:registry> | transport | registry.transporter | string | 可选 | netty | 性能调优 | 网络传输方式,可选mina,netty | 2.0.0以上版本 |
<dubbo:registry> | timeout | registry.timeout | int | 可选 | 5000 | 性能调优 | 注册中心请求超时时间(毫秒) | 2.0.0以上版本 |
<dubbo:registry> | session | registry.session | int | 可选 | 60000 | 性能调优 | 注册中心会话超时时间(毫秒),用于检测提供者非正常断线后的脏数据,比如用心跳检测的实现,此时间就是心跳间隔,不同注册中心实现不一样。 | 2.1.0以上版本 |
<dubbo:registry> | file | registry.file | string | 可选 | 服务治理 | 使用文件缓存注册中心地址列表及服务提供者列表,应用重启时将基于此文件恢复,注意:两个注册中心不能使用同一文件存储 | 2.0.0以上版本 | |
<dubbo:registry> | wait | registry.wait | int | 可选 | 0 | 性能调优 | 停止时等待通知完成时间(毫秒) | 2.0.0以上版本 |
<dubbo:registry> | check | check | boolean | 可选 | true | 服务治理 | 注册中心不存在时,是否报错 | 2.0.0以上版本 |
<dubbo:registry> | register | register | boolean | 可选 | true | 服务治理 | 是否向此注册中心注册服务,如果设为false,将只订阅,不注册 | 2.0.5以上版本 |
<dubbo:registry> | subscribe | subscribe | boolean | 可选 | true | 服务治理 | 是否向此注册中心订阅服务,如果设为false,将只注册,不订阅 | 2.0.5以上版本 |
<dubbo:registry> | dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示后disable状态,需人工启用,并且服务提供者停止时,也不会自动取消册,需人工禁用。 | 2.0.5以上版本 |
(+) (#)
监控中心配置:
配置类:com.alibaba.dubbo.config.MonitorConfig
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:monitor> | protocol | protocol | string | 可选 | dubbo | 服务治理 | 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心。 | 2.0.9以上版本 |
<dubbo:monitor> | address | <url> | string | 可选 | N/A | 服务治理 | 直连监控中心服务器地址,address="10.20.130.230:12080" | 1.0.16以上版本 |
(+) (#)
应用信息配置:
配置类:com.alibaba.dubbo.config.ApplicationConfig
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:application> | name | application | string | 必填 | 服务治理 | 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样,此参数不是匹配条件,你当前项目叫什么名字就填什么,和提供者消费者角色无关,比如:kylin应用调用了morgan应用的服务,则kylin项目配成kylin,morgan项目配成morgan,可能kylin也提供其它服务给别人使用,但kylin项目永远配成kylin,这样注册中心将显示kylin依赖于morgan | 1.0.16以上版本 | |
<dubbo:application> | version | application.version | string | 可选 | 服务治理 | 当前应用的版本 | 2.2.0以上版本 | |
<dubbo:application> | owner | owner | string | 可选 | 服务治理 | 应用负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | |
<dubbo:application> | organization | organization | string | 可选 | 服务治理 | 组织名称(BU或部门),用于注册中心区分服务来源,此配置项建议不要使用autoconfig,直接写死在配置中,比如china,intl,itu,crm,asc,dw,aliexpress等 | 2.0.0以上版本 | |
<dubbo:application> | architecture |
architecture |
string | 可选 | 服务治理 | 用于服务分层对应的架构。如,intl、china。不同的架构使用不同的分层。 | 2.0.7以上版本 | |
<dubbo:application> | environment | environment | string | 可选 | 服务治理 | 应用环境,如:develop/test/product,不同环境使用不同的缺省值,以及作为只用于开发测试功能的限制条件 | 2.0.0以上版本 | |
<dubbo:application> | compiler | compiler | string | 可选 | javassist | 性能优化 | Java字节码编译器,用于动态类的生成,可选:jdk或javassist | 2.1.0以上版本 |
<dubbo:application> | logger | logger | string | 可选 | slf4j | 性能优化 | 日志输出方式,可选:slf4j,jcl,log4j,jdk | 2.2.0以上版本 |
(+) (#)
模块信息配置:
配置类:com.alibaba.dubbo.config.ModuleConfig
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:module> | name | module | string | 必填 | 服务治理 | 当前模块名称,用于注册中心计算模块间依赖关系 | 2.2.0以上版本 | |
<dubbo:module> | version | module.version | string | 可选 | 服务治理 | 当前模块的版本 | 2.2.0以上版本 | |
<dubbo:module> | owner | owner | string | 可选 | 服务治理 | 模块负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.2.0以上版本 | |
<dubbo:module> | organization | organization | string | 可选 | 服务治理 | 组织名称(BU或部门),用于注册中心区分服务来源,此配置项建议不要使用autoconfig,直接写死在配置中,比如china,intl,itu,crm,asc,dw,aliexpress等 | 2.2.0以上版本 |
(+) (#)
服务提供者缺省值配置:
配置类:com.alibaba.dubbo.config.ProviderConfig
说明:该标签为<dubbo:service>和<dubbo:protocol>标签的缺省值设置。
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:provider> | id | string | 可选 | dubbo | 配置关联 | 协议BeanId,可以在<dubbo:service proivder="">中引用此ID | 1.0.16以上版本 | |
<dubbo:provider> | protocol | <protocol> | string | 可选 | dubbo | 性能调优 | 协议名称 | 1.0.16以上版本 |
<dubbo:provider> | host | <host> | string | 可选 | 自动查找本机IP | 服务发现 | 服务主机名,多网卡选择或指定VIP及域名时使用,为空则自动查找本机IP,建议不要配置,让Dubbo自动获取本机IP | 1.0.16以上版本 |
<dubbo:provider> | threads | threads | int | 可选 | 100 | 性能调优 | 服务线程池大小(固定大小) | 1.0.16以上版本 |
<dubbo:provider> | payload | payload | int | 可选 | 88388608(=8M) | 性能调优 | 请求及响应数据包大小限制,单位:字节 | 2.0.0以上版本 |
<dubbo:provider> | path | <path> | string | 可选 | 服务发现 | 提供者上下文路径,为服务path的前缀 | 2.0.0以上版本 | |
<dubbo:provider> | server | server | string | 可选 | dubbo协议缺省为netty,http协议缺省为servlet | 性能调优 | 协议的服务器端实现类型,比如:dubbo协议的mina,netty等,http协议的jetty,servlet等 | 2.0.0以上版本 |
<dubbo:provider> | client | client | string | 可选 | dubbo协议缺省为netty | 性能调优 | 协议的客户端实现类型,比如:dubbo协议的mina,netty等 | 2.0.0以上版本 |
<dubbo:provider> | codec | codec | string | 可选 | dubbo | 性能调优 | 协议编码方式 | 2.0.0以上版本 |
<dubbo:provider> | serialization | serialization | string | 可选 | dubbo协议缺省为hessian2,rmi协议缺省为java,http协议缺省为json | 性能调优 | 协议序列化方式,当协议支持多种序列化方式时使用,比如:dubbo协议的dubbo,hessian2,java,compactedjava,以及http协议的json,xml等 | 2.0.5以上版本 |
<dubbo:provider> | default | boolean | 可选 | false | 配置关联 | 是否为缺省协议,用于多协议 | 1.0.16以上版本 | |
<dubbo:provider> | filter | service.filter | string | 可选 | 性能调优 | 服务提供方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | |
<dubbo:provider> | listener | exporter.listener | string | 可选 | 性能调优 | 服务提供方导出服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | |
<dubbo:provider> | threadpool | threadpool | string | 可选 | fixed | 性能调优 | 线程池类型,可选:fixed/cached | 2.0.5以上版本 |
<dubbo:provider> | accepts | accepts | int | 可选 | 0 | 性能调优 | 服务提供者最大可接受连接数 | 2.0.5以上版本 |
<dubbo:provider> | version | version | string | 可选 | 0.0.0 | 服务发现 | 服务版本,建议使用两位数字版本,如:1.0,通常在接口不兼容时版本号才需要升级 | 2.0.5以上版本 |
<dubbo:provider> | group | group | string | 可选 | 服务发现 | 服务分组,当一个接口有多个实现,可以用分组区分 | 2.0.5以上版本 | |
<dubbo:provider> | delay | delay | int | 可选 | 0 | 性能调优 | 延迟注册服务时间(毫秒)- ,设为-1时,表示延迟到Spring容器初始化完成时暴露服务 | 2.0.5以上版本 |
<dubbo:provider> | timeout | default.timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 2.0.5以上版本 |
<dubbo:provider> | retries | default.retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.5以上版本 |
<dubbo:provider> | connections | default.connections | int | 可选 | 0 | 性能调优 | 对每个提供者的最大连接数,rmi、http、hessian等短连接协议表示限制连接数,dubbo等长连接协表示建立的长连接个数 | 2.0.5以上版本 |
<dubbo:provider> | loadbalance | default.loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用 | 2.0.5以上版本 |
<dubbo:provider> | async | default.async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.5以上版本 |
<dubbo:provider> | stub | stub | boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省代理类名,即:接口名 + Local后缀。 | 2.0.5以上版本 |
<dubbo:provider> | mock | mock | boolean | 可选 | false | 服务治理 | 设为true,表示使用缺省Mock类名,即:接口名 + Mock后缀。 | 2.0.5以上版本 |
<dubbo:provider> | token | token | boolean | 可选 | false | 服务治理 | 令牌验证,为空表示不开启,如果为true,表示随机生成动态令牌 | 2.0.5以上版本 |
<dubbo:provider> | registry | registry | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.5以上版本 |
<dubbo:provider> | dynamic | dynamic | boolean | 可选 | true | 服务治理 | 服务是否动态注册,如果设为false,注册后将显示后disable状态,需人工启用,并且服务提供者停止时,也不会自动取消册,需人工禁用。 | 2.0.5以上版本 |
<dubbo:provider> | accesslog | accesslog | string/boolean | 可选 | false | 服务治理 | 设为true,将向logger中输出访问日志,也可填写访问日志文件路径,直接把访问日志输出到指定文件 | 2.0.5以上版本 |
<dubbo:provider> | owner | owner | string | 可选 | 服务治理 | 服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | |
<dubbo:provider> | document | document | string | 可选 | 服务治理 | 服务文档URL | 2.0.5以上版本 | |
<dubbo:provider> | weight | weight | int | 可选 | 性能调优 | 服务权重 | 2.0.5以上版本 | |
<dubbo:provider> | executes | executes | int | 可选 | 0 | 性能调优 | 服务提供者每服务每方法最大可并行执行请求数 | 2.0.5以上版本 |
<dubbo:provider> | actives | default.actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 |
<dubbo:provider> | proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 |
<dubbo:provider> | cluster | default.cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:provider> | deprecated | deprecated | boolean | 可选 | false | 服务治理 | 服务是否过时,如果设为true,消费方引用时将打印服务过时警告error日志 | 2.0.5以上版本 |
<dubbo:provider> | queues | queues | int | 可选 | 0 | 性能调优 | 线程池队列大小,当线程池满时,排队等待执行的队列大小,建议不要设置,当线程程池时应立即失败,重试其它服务提供机器,而不是排队,除非有特殊需求。 | 2.0.5以上版本 |
<dubbo:provider> | charset | charset | string | 可选 | UTF-8 | 性能调优 | 序列化编码 | 2.0.5以上版本 |
<dubbo:provider> | buffer | buffer | int | 可选 | 8192 | 性能调优 | 网络读写缓冲区大小 | 2.0.5以上版本 |
<dubbo:provider> | iothreads | iothreads | int | 可选 | CPU + 1 | 性能调优 | IO线程池,接收网络读写中断,以及序列化和反序列化,不处理业务,业务线程池参见threads配置,此线程池和CPU相关,不建议配置。 | 2.0.5以上版本 |
<dubbo:provider> | telnet | telnet | string | 可选 | 服务治理 | 所支持的telnet命令,多个命令用逗号分隔 | 2.0.5以上版本 | |
<dubbo:service> | contextpath | contextpath | String | 可选 | 缺省为空串 | 服务治理 | 2.0.6以上版本 | |
<dubbo:provider> | layer | layer | string | 可选 | 服务治理 | 服务提供者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 |
(+) (#)
服务消费者缺省值配置:
配置类:com.alibaba.dubbo.config.ConsumerConfig
说明:该标签为<dubbo:reference>标签的缺省值设置。
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:consumer> | timeout | default.timeout | int | 可选 | 1000 | 性能调优 | 远程服务调用超时时间(毫秒) | 1.0.16以上版本 |
<dubbo:consumer> | retries | default.retries | int | 可选 | 2 | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 1.0.16以上版本 |
<dubbo:consumer> | loadbalance | default.loadbalance | string | 可选 | random | 性能调优 | 负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用 | 1.0.16以上版本 |
<dubbo:consumer> | async | default.async | boolean | 可选 | false | 性能调优 | 是否缺省异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 2.0.0以上版本 |
<dubbo:consumer> | connections | default.connections | int | 可选 | 100 | 性能调优 | 每个服务对每个提供者的最大连接数,rmi、http、hessian等短连接协议支持此配置,dubbo协议长连接不支持此配置 | 1.0.16以上版本 |
<dubbo:consumer> | generic | generic | boolean | 可选 | false | 服务治理 | 是否缺省泛化接口,如果为泛化接口,将返回GenericService | 2.0.0以上版本 |
<dubbo:consumer> | check | check | boolean | 可选 | true | 服务治理 | 启动时检查提供者是否存在,true报错,false忽略 | 1.0.16以上版本 |
<dubbo:consumer> | proxy | proxy | string | 可选 | javassist | 性能调优 | 生成动态代理方式,可选:jdk/javassist | 2.0.5以上版本 |
<dubbo:consumer> | owner | owner | string | 可选 | 服务治理 | 调用服务负责人,用于服务治理,请填写负责人公司邮箱前缀 | 2.0.5以上版本 | |
<dubbo:consumer> | actives | default.actives | int | 可选 | 0 | 性能调优 | 每服务消费者每服务每方法最大并发调用数 | 2.0.5以上版本 |
<dubbo:consumer> | cluster | default.cluster | string | 可选 | failover | 性能调优 | 集群方式,可选:failover/failfast/failsafe/failback/forking | 2.0.5以上版本 |
<dubbo:consumer> | filter | reference.filter | string | 可选 | 性能调优 | 服务消费方远程调用过程拦截器名称,多个名称用逗号分隔 | 2.0.5以上版本 | |
<dubbo:consumer> | listener | invoker.listener | string | 可选 | 性能调优 | 服务消费方引用服务监听器名称,多个名称用逗号分隔 | 2.0.5以上版本 | |
<dubbo:consumer> | registry | string | 可选 | 缺省向所有registry注册 | 配置关联 | 向指定注册中心注册,在多个注册中心时使用,值为<dubbo:registry>的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A | 2.0.5以上版本 | |
<dubbo:consumer> | layer | layer | string | 可选 | 服务治理 | 服务调用者所在的分层。如:biz、dao、intl:web、china:acton。 | 2.0.7以上版本 | |
<dubbo:consumer> | init | init | boolean | 可选 | false | 性能调优 | 是否在afterPropertiesSet()时饥饿初始化引用,否则等到有人注入或引用该实例时再初始化。 | 2.0.10以上版本 |
<dubbo:consumer> | cache | cache | string/boolean | 可选 | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:consumer> | validation | validation | boolean | 可选 | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | Dubbo2.1.0及其以上版本支持 |
(+) (#)
方法级配置:
配置类:com.alibaba.dubbo.config.MethodConfig
说明:该标签为<dubbo:service>或<dubbo:reference>的子标签,用于控制到方法级,
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:method> | name | string | 必填 | 标识 | 方法名 | 1.0.8以上版本 | ||
<dubbo:method> | timeout | <metodName>.timeout | int | 可选 | 缺省为的timeout | 性能调优 | 方法调用超时时间(毫秒) | 1.0.8以上版本 |
<dubbo:method> | retries | <metodName>.retries | int | 可选 | 缺省为<dubbo:reference>的retries | 性能调优 | 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0 | 2.0.0以上版本 |
<dubbo:method> | loadbalance | <metodName>.loadbalance | string | 可选 | 缺省为的loadbalance | 性能调优 | 负载均衡策略,可选值:random,roundrobin,leastactive,分别表示:随机,轮循,最少活跃调用 | 2.0.0以上版本 |
<dubbo:method> | async | <metodName>.async | boolean | 可选 | 缺省为<dubbo:reference>的async | 性能调优 | 是否异步执行,不可靠异步,只是忽略返回值,不阻塞执行线程 | 1.0.9以上版本 |
<dubbo:method> | sent | <methodName>.sent | boolean | 可选 | true | 性能调优 | 异步调用时,标记sent=true时,表示网络已发出数据 | 2.0.6以上版本 |
<dubbo:method> | actives | <metodName>.actives | int | 可选 | 0 | 性能调优 | 每服务消费者最大并发调用限制 | 2.0.5以上版本 |
<dubbo:method> | executes | <metodName>.executes | int | 可选 | 0 | 性能调优 | 每服务每方法最大使用线程数限制- -,此属性只在<dubbo:method>作为<dubbo:service>子标签时有效 | 2.0.5以上版本 |
<dubbo:method> | deprecated | <methodName>.deprecated | boolean | 可选 | false | 服务治理 | 服务方法是否过时,此属性只在<dubbo:method>作为<dubbo:service>子标签时有效 | 2.0.5以上版本 |
<dubbo:method> | sticky | <methodName>.sticky | boolean | 可选 | false | 服务治理 | 设置true 该接口上的所有方法使用同一个provider.如果需要更复杂的规则,请使用用路由 | 2.0.6以上版本 |
<dubbo:method> | return | <methodName>.return | boolean | 可选 | true | 性能调优 | 方法调用是否需要返回值,async设置为true时才生效,如果设置为true,则返回future,或回调onreturn等方法,如果设置为false,则请求发送成功后直接返回Null | 2.0.6以上版本 |
<dubbo:method> | oninvoke | attribute属性,不在URL中体现 | String | 可选 | 性能调优 | 方法执行前拦截 | 2.0.6以上版本 | |
<dubbo:method> | onreturn | attribute属性,不在URL中体现 | String | 可选 | 性能调优 | 方法执行返回后拦截 | 2.0.6以上版本 | |
<dubbo:method> | onthrow | attribute属性,不在URL中体现 | String | 可选 | 性能调优 | 方法执行有异常拦截 | 2.0.6以上版本 | |
<dubbo:method> | cache | <methodName>.cache | string/boolean | 可选 | 服务治理 | 以调用参数为key,缓存返回结果,可选:lru, threadlocal, jcache等 | Dubbo2.1.0及其以上版本支持 | |
<dubbo:method> | validation | <methodName>.validation | boolean | 可选 | 服务治理 | 是否启用JSR303标准注解验证,如果启用,将对方法参数上的注解进行校验 | Dubbo2.1.0及其以上版本支持 |
比如:
<dubbo:referenceinterface="com.xxx.XxxService">
<dubbo:methodname="findXxx"timeout="3000"retries="2"/>
</dubbo:reference>
|
(+) (#)
方法参数配置:
配置类:com.alibaba.dubbo.config.ArgumentConfig
说明:该标签为<dubbo:method>的子标签,用于方法参数的特征描述,比如:
<dubbo:methodname="findXxx"timeout="3000"retries="2">
<dubbo:argumentindex="0"callback="true"/>
<dubbo:method>
|
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:argument> | index | int | 必填 | 标识 | 方法名 | 2.0.6以上版本 | ||
<dubbo:argument> | type | String | 与index二选一 | 标识 | 通过参数类型查找参数的index | 2.0.6以上版本 | ||
<dubbo:argument> | callback | <metodName><index>.retries | boolean | 可选 | 服务治理 | 参数是否为callback接口,如果为callback,服务提供方将生成反向代理,可以从服务提供方反向调用消费方,通常用于事件推送. | 2.0.6以上版本 |
(+) (#)
选项参数配置:
配置类:java.util.Map
说明:该标签为<dubbo:protocol>或<dubbo:service>或<dubbo:provider>或<dubbo:reference>或<dubbo:consumer>的子标签,用于配置自定义参数,该配置项将作为扩展点设置自定义参数使用。
标签 | 属性 | 对应URL参数 | 类型 | 是否必填 | 缺省值 | 作用 | 描述 | 兼容性 |
---|---|---|---|---|---|---|---|---|
<dubbo:parameter> | key | key | string | 必填 | 服务治理 | 路由参数键 | 2.0.0以上版本 | |
<dubbo:parameter> | value | value | string | 必填 | 服务治理 | 路由参数值 | 2.0.0以上版本 |
比如:
<dubbo:protocolname="napoli">
<dubbo:parameterkey="napoli.queue.name"value="xxx"/>
</dubbo:protocol>
|
也可以:
<dubbo:protocolname="jms"p:queue="xxx"/>
|
详细参见:自定义参数
(+) (#)
推荐使用Dubbo协议 |
性能测试报告 各协议的性能情况,请参见:性能测试报告 (+) |
(+) (#)
Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 |
Dubbo缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。 |
<dubbo:protocolname="dubbo"port="20880"/>
|
Set default protocol:
<dubbo:providerprotocol="dubbo"/>
|
Set service protocol:
<dubbo:serviceprotocol="dubbo"/>
|
Multi port:
<dubbo:protocolid="dubbo1"name="dubbo"port="20880"/>
<dubbo:protocolid="dubbo2"name="dubbo"port="20881"/>
|
Dubbo protocol options:
<dubbo:protocolname=“dubbo” port=“9090” server=“netty” client=“netty” codec=“dubbo” serialization=“hessian2” charset=“UTF-8” threadpool=“fixed” threads=“100” queues=“0” iothreads=“9” buffer=“8192” accepts=“1000” payload=“8388608” />
|
Dubbo协议缺省每服务每提供者每消费者使用单一长连接,如果数据量较大,可以使用多个连接。 |
<dubbo:protocolname="dubbo"connections="2"/>
|
为防止被大量连接撑挂,可在服务提供方限制大接收连接数,以实现服务提供方自我保护。 |
<dubbo:protocolname="dubbo"accepts="1000"/>
|
缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。
为什么要消费者比提供者个数多:
因dubbo协议采用单一长连接,
假设网络为千兆网卡(1024Mbit=128MByte),
根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考),
理论上1个服务提供者需要20个服务消费者才能压满网卡。
为什么不能传大包:
因dubbo协议采用单一长连接,
如果每次请求的数据包大小为500KByte,假设网络为千兆网卡(1024Mbit=128MByte),每条连接最大7MByte(不同的环境可能不一样,供参考),
单个服务提供者的TPS(每秒处理事务数)最大为:128MByte / 500KByte = 262。
单个消费者调用单个服务提供者的TPS(每秒处理事务数)最大为:7MByte / 500KByte = 14。
如果能接受,可以考虑使用,否则网络将成为瓶颈。
为什么采用异步单一长连接:
因为服务的现状大都是服务提供者少,通常只有几台机器,
而服务的消费者多,可能整个网站都在访问该服务,
比如Morgan的提供者只有6台提供者,却有上百台消费者,每天有1.5亿次调用,
如果采用常规的hessian服务,服务提供者很容易就被压跨,
通过单一连接,保证单一消费者不会压死提供者,
长连接,减少连接握手验证等,
并使用异步IO,复用线程池,防止C10K问题。
(1) 约束:
数据通讯 | 情况 | 结果 |
---|---|---|
A->B | 类A多一种 属性(或者说类B少一种 属性) | 不抛异常,A多的那 个属性的值,B没有, 其他正常 |
A->B | 枚举A多一种 枚举(或者说B少一种 枚举),A使用多 出来的枚举进行传输 | 抛异常 |
A->B | 枚举A多一种 枚举(或者说B少一种 枚举),A不使用 多出来的枚举进行传输 | 不抛异常,B正常接 收数据 |
A->B | A和B的属性 名相同,但类型不相同 | 抛异常 |
A->B | serialId 不相同 | 正常传输 |
总结:会抛异常的情况:枚 举值一边多一种,一边少一种,正好使用了差别的那种,或者属性名相同,类型不同
接口增加方法,对客户端无影响,如果该方法不是客户端需要的,客户端不需要重新部署;
输入参数和结果集中增加属性,对客户端无影响,如果客户端并不需要新属性,不用重新
部署;
输入参数和结果集属性名变化,对客户端序列化无影响,但是如果客户端不重新部署,不管输入还是输出,属性名变化的属性值是获取不到的。
总结:服务器端和客户端对领域对象并不需要完全一致,而是按照最大匹配原则。
(2) 配置:
dubbo.properties:
dubbo.service.protocol=dubbo
|
(+) (#)
RMI协议采用JDK标准的java.rmi.*实现,采用阻塞式短连接和JDK标准序列化方式。 |
Define rmi protocol:
<dubbo:protocolname="rmi"port="1099"/>
|
Set default protocol:<