dubbo超時的深思

在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端屬性
緣由以下:
性能

  1. 做服務的提供者,比服務使用方更清楚服務性能參數,如調用的超時時間,合理的重試次數,等等

  2. 在Provider配置後,Consumer不配置則會使用Provider的配置值,即Provider配置能夠做爲Consumer的缺省值。不然,Consumer會使用Consumer端的全局設置,這對於Provider不可控的,而且每每是不合理的

  3. 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端屬性有:

  1. timeout,方法調用超時

  2. retries,失敗重試次數,缺省是2(表示加上第一次調用,會調用3次)

  3. loadbalance,負載均衡算法(有多個Provider時,如何挑選Provider調用),缺省是隨機(random)。還能夠有輪訓(roundrobin)、最不活躍優先(leastactive,指從Consumer端併發調用最好的Provider,能夠減小的反應慢的Provider的調用,由於反應更容易累積併發的調用)

  4. 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端屬性有:

  1. threads,服務線程池大小

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

相關文章
相關標籤/搜索