启动时检查
Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。
如果你的Spring容器是懒加载的,或者通过API编程延迟引用服务,请关闭check,否则服务临时不可用时,会抛出异常,拿到null引用,如果check=false,总是会返回引用,当服务恢复时,能自动连上。
可以通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
关闭某个服务的启动时检查:(没有提供者时报错)
<dubbo:reference interface="com.foo.BarService" check="false"/>
关闭所有服务的启动时检查:(没有提供者时报错)
<dubbo:consumer check="false" />
关闭注册中心启动时检查:(注册订阅失败时报错)
也可以用dubbo.properties配置:
dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false
java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false
也可以用-D参数:
注意区别
dubbo.reference.check=false,强制改变所有reference的check值,就算配置中有声明,也会被覆盖。
dubbo.consumer.check=false,是设置check的缺省值,如果配置中有显式的声明,如:<dubbo:reference check="true"/>,不会受影响。
dubbo.registry.check=false,前面两个都是指订阅成功,但提供者列表是否为空是否报错,如果注册订阅失败时,也允许启动,需使用此选项,将在后台定时重试。
引用缺省是延迟初始化的,只有引用被注入到其它Bean,或被getBean()获取,才会初始化。
如果需要饥饿加载,即没有人引用也立即生成动态代理,可以配置:
<dubbo:reference interface="com.foo.BarService" init="true"/>
服务只订阅与只注册
1)只订阅
使用场景:我们在本地笔记本开发的时候,不能把自己笔记本的服务注册到开发环境,但是可以使用注册中心的服务
服务提供者配置 register="false"
<dubbo:registry protocol="zookeeper" address="192.168.98.165:2181,192.168.98.166:2181,192.168.98.167:2181" register="false"/>
1)只注册
如果有两个镜像环境,两个注册中心,有一个服务只在其中一个注册中心有部署,另一个注册中心还没来得及部署,而两个注册中心的其它应用都需要依赖此服务。
这个时候,可以让服务提供者方只注册服务到另一注册中心,而不从另一注册中心订阅服务。
就是说这个服务只能在一台服务器上订阅,其他服务器都不能订阅当消费者?
服务提供者配置 subscribe="false"
<dubbo:registry protocol="zookeeper" address="192.168.98.165:2181,192.168.98.166:2181,192.168.98.167:2181" subscribe="false"/>
多注册中心支持
使用场景比较少
1)注册中心配置
<dubbo:registry id="zkOne" protocol="zookeeper" address="192.168.98.165:2181,192.168.98.166:2181,192.168.98.167:2181"/>
<dubbo:registry id="zkTwo" protocol="zookeeper" address="192.168.98.169:2181"/>
2)服务选择配置中心
<dubbo:service interface="com.charjay.order.IOrderServices" ref="orderService" protocol="hessian" registry="zkTwo"/>
连接超时timeout
必须要设置服务的处理的超时时间,超时后报错
<dubbo:service interface="com.charjay.order.IOrderServices" ref="orderService" timeout="2000"/>
消费者与提供者同时设置了timeout,那么哪个优先级高?消费端优先级高
直连提供者
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表,A接口配置点对点,不影响B接口从注册中心获取列表。
(1) 如果是线上需求需要点对点,可在<dubbo:reference>中配置url指向提供者,将绕过注册中心,多个地址用分号隔开,配置如下:(1.0.6及以上版本支持)
<dubbo:reference id="xxxService" interface="com.alibaba.xxx.XxxService" url="dubbo://localhost:20890" />
(key为服务名,value为服务提供者url,此配置优先级最高,1.0.15及以上版本支持)(2) 在JVM启动参数中加入-D参数映射服务地址,如:
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
com.alibaba.xxx.XxxService=dubbo://localhost:20890
注意然后在映射文件xxx.properties中加入:(key为服务名,value为服务提供者url)
为了避免复杂化线上环境,不要在线上使用这个功能,只应在测试阶段使用。
结果缓存
结果缓存,用于加速热门数据的访问速度,Dubbo提供声明式缓存,以减少用户加缓存的工作量。
2.1.0以上版本支持
示例代码:https://github.com/alibaba/dubbo/tree/master/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/cache
lru 基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。
threadlocal 当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。
jcache 与JSR107集成,可以桥接各种缓存实现。
缓存类型可扩展,参见:CacheFactory扩展点
配置如:
<dubbo:reference interface="com.foo.BarService" cache="lru" />
<dubbo:reference interface="com.foo.BarService">
<dubbo:method name="findBar" cache="lru" />
</dubbo:reference>
本地调用
本地调用,使用了Injvm协议,是一个伪协议,它不开启端口,不发起远程调用,只在JVM内直接关联,但执行Dubbo的Filter链。
Define injvm protocol:
<dubbo:protocol name="injvm" />
<dubbo:provider protocol="injvm" />
Set service protocol:
<dubbo:service protocol="injvm" />
<dubbo:consumer injvm="true" .../>
<dubbo:provider injvm="true" .../>
或Use injvm first:
<dubbo:reference injvm="true" .../>
<dubbo:service injvm="true" .../>
注意:服务暴露与服务引用都需要声明injvm="true"
事件通知
在调用之前,调用之后,出现异常时,会触发oninvoke, onreturn, onthrow三个事件,可以配置当事件发生时,通知哪个类的哪个方法。
支持版本:2.0.7之后
<bean id ="demoCallback" class = "com.alibaba.dubbo.callback.implicit.NofifyImpl"/>
<dubbo:reference id="demoService" interface="com.alibaba.dubbo.callback.implicit.IDemoService" version="1.0.0" group="cn">
<dubbo:method name="get" async="true" onreturn = "demoCallback.onreturn"
onthrow="demoCallback.onthrow"/>
</dubbo:reference>
注:
callback与async功能正交分解:
async=true,表示结果是否马上返回.
onreturn 表示是否需要回调.
组合情况:(async=false 默认)
异步回调模式:async=true onreturn="xxx"
同步回调模式:async=false onreturn="xxx"
异步无回调 :async=true
同步无回调 :async=false
异步调用
基于NIO的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。
2.0.6及其以上版本支持
接口延迟暴露
dubbo的provider在启动时可能会遇到这样的问题:
在service中需要spring注入的bean还没有初始化完全,service就已经注册到了zookeeper了,请求就可以进到这个service,在内部的bean没注入的情况下,会报空指针的异常。
service注册到zookeeper的节点是:
spring解析到<dubbo:service>的时候。这个时候该service下的资源可能还没有注入完成。
解决方案是:配置dubbo的延迟暴露时间
比如:
延迟5秒暴露接口 <dubbo:service delay="5000" />
等spring初始化完成后暴露接口 <dubbo:service delay="-1" />