在dubbo的provider和consumer的配置文件中,若是都配置了timeout的超时时间,dubbo默认以consumer中配置的时间为准java
provider.xml的配置:算法
<dubbo:service timeout="4000" retries="0" interface="com.dingding.tms.bms.service.BillingZfbCodOrderService" ref="billingZfbCodOrderService" registry="globalRegistry"/>
spring
conusmer中的配置:数据库
<dubbo:reference id="billingInterService" interface="com.dingding.tms.bms.service.BillingInterService" protocol="dubbo" check="false" registry="globalRegistry" timeout="3000"/>
api
最后这个service在调用时的超时时间就是3秒。并发
另外,负载均衡
1,consumer会在超过3秒时获得一个调用超时的异常。dom
2,provider中代码的执行不会由于超时而中断,在执行完毕后,会获得一个dubbo的警告。ide
在Provider上尽可能多配置Consumer端属性
缘由以下:
性能
做服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等
在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置能够做为Consumer的缺省值。不然,Consumer会使用Consumer端的全局设置,这对于Provider不可控的,而且每每是不合理的
PS: 配置的覆盖规则:1) 方法级配置别优于接口级别,即小Scope优先 2) Consumer端配置 优于 Provider配置 优于 全局配置,最后是Dubbo Hard Code的配置值(见配置文档)
好比:
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService"
timeout="300" retry="2" loadbalance="random" actives="0"/>
< dubbo:service interface="com.alibaba.hello.api.WorldService" version="1.0.0" ref="helloService"
timeout="300" retry="2" loadbalance="random" actives="0" >
<dubbo:method name="findAllPerson" timeout="10000" retries="9" loadbalance="leastactive" actives="5" />
< dubbo:service/>
在Provider能够配置的Consumer端属性有:
timeout,方法调用超时
retries,失败重试次数,缺省是2(表示加上第一次调用,会调用3次)
loadbalance,负载均衡算法(有多个Provider时,如何挑选Provider调用),缺省是随机(random)。还能够有轮训(roundrobin)、最不活跃优先(leastactive,指从Consumer端并发调用最好的Provider,能够减小的反应慢的Provider的调用,由于反应更容易累积并发的调用)
actives,消费者端,最大并发调用限制,即当Consumer对一个服务的并发调用到上限后,新调用会Wait直到超时。在方法上配置(dubbo:method )则并发限制针对方法,在接口上配置(dubbo:service),则并发限制针对服务。
Provider上配置合理的Provider端属性
好比:
<dubbo:protocol threads="200" />
< dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService"
executes="200" >
<dubbo:method name="findAllPerson" executes="50" />
< /dubbo:service>
Provider上能够配置的Provider端属性有:
threads,服务线程池大小
executes,一个服务提供者并行执行请求上限,即当Provider对一个服务的并发调用到上限后,新调用会Wait(Consumer可能到超时)。在方法上配置(dubbo:method )则并发限制针对方法,在接口上配置(dubbo:service),则并发限制针对服务。
以上为网上的定义,在实际使用中当服务的消费方调用服务的提供方超时时,会抛出以下异常:
Caused by: com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2016-07-20 16:27:34.873, end time: 2016-07-20 16:27:39.895, client elapsed: 0 ms, server elapsed: 5022 ms, timeout: 5000 ms, request: Request [id=438870, version=2.0.0, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=querySeatByCode, parameterTypes=[class java.lang.String, class java.lang.String], arguments=[×××5788, A1], p_w_uploads={input=356, path=com.dfire.soa.turtle.service.ISeatService, interface=com.dfire.soa.turtle.service.ISeatService, timeout=5000, version=1.0.0H5_pressuretest}]], channel: /10.1.5.128:34443 -> /10.1.5.172:20880
网上一般的解决办法是调大超时时间,可是也多是由于代码自己有潜在问题而形成dubbo超时。
好比:在dubbo消费方,调用了dubbo的提供方,此时事务是分部的,但若是本身的service方法中会用到一张表并去作update操做致使产生了行锁时,若是恰巧你又在以后调用了另外一个会操做此表的dubbo服务,那么问题就产生了,你会在调dubbo服务的时候发生如上的超时异常,就是由于用spring aop声明式事务,在你service没有执行完时产生的行锁并无释放,而你又在service里放入了须要操做此表的dubbo服务,这样当数据库的死锁尚未抛异常的时候,dubbo就已经抛异常了,所以这个超时异常其实坑很深。