在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就已經拋異常了,所以這個超時異常其實坑很深。