天天看點

dubbo逾時異常捕獲_dubbo逾時的深思

dubbo逾時異常捕獲_dubbo逾時的深思

在dubbo的provider和consumer的配置檔案中,如果都配置了timeout的逾時時間,dubbo預設以consumer中配置的時間為準

provider.xml的配置:

conusmer中的配置:

最後這個service在調用時的逾時時間就是3秒。

另外,

1,consumer會在超過3秒時得到一個調用逾時的異常。

2,provider中代碼的執行不會因為逾時而中斷,在執行完畢後,會得到一個dubbo的警告。

在Provider上盡量多配置Consumer端屬性

原因如下:

  1. 作服務的提供者,比服務使用方更清楚服務性能參數,如調用的逾時時間,合理的重試次數,等等
  2. 在Provider配置後,Consumer不配置則會使用Provider的配置值,即Provider配置可以作為Consumer的預設值。否則,Consumer會使用Consumer端的全局設定,這對于Provider不可控的,并且往往是不合理的
  3. PS: 配置的覆寫規則:1) 方法級配置别優于接口級别,即小Scope優先 2) Consumer端配置 優于 Provider配置 優于 全局配置,最後是Dubbo Hard Code的配置值(見配置文檔)

比如:timeout="300" retry="2" loadbalance="random" actives="0"/>

< dubbo:service inter version="1.0.0" ref="helloService"

timeout="300" retry="2" loadbalance="random" actives="0" >

< 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:service inter version="1.0.0" ref="helloService"

executes="200" >

< /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就已經抛異常了,是以這個逾時異常其實坑很深,需要根據實際代碼進行具體分析。