本文示例代码基于 Dubbo:使用 Spring 注解构建 Dubbo 服务 中的示例项目。
修改 provider 模块的 DemoServiceImpl 实现类:
package demo.provider;
import demo.contract.DemoService;
import org.springframework.stereotype.Service;
@Service
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
try {
Thread.sleep(3000); // sleep 3 秒,模拟超时
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello, " + name;
}
}
dubbo 中的默认超时是 1000 毫秒。
配置 consumer 超时
在 consumer 模块中 dubbo-consumer.xml 配置 timeout :
<dubbo:reference id="demoService" interface="demo.contract.DemoService" check="false" timeout="2000"/>
运行 ConsumerMain,会看到:
Exception in thread "main" org.apache.dubbo.rpc.RpcException: Failed to invoke the method sayHello in the service demo.contract.DemoService. Tried 3 times of the providers [127.0.0.1:20881] (1/1) from the registry 127.0.0.1:2181 on the consumer 127.0.0.1 using the dubbo version 2.7.1. Last error is: Invoke remote method timeout. method: sayHello, provider: dubbo://127.0.0.1:20881/demo.contract....
....
Caused by: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer.
为什么是 Tried 3 times
? 因为 retries 参数默认值是 2 。正常的1次加上重试的2次,一共3次。要修改重试次数,可以:
<dubbo:reference id="demoService"
interface="demo.contract.DemoService"
check="false" timeout="2000" retries="3"/>
配置 provider 超时
去掉上面 dubbo-consumer.xml 中配置的超时,在 dubbo-provider.xml 中配置 timeout:
<dubbo:service interface="demo.contract.DemoService" class="demo.provider.DemoServiceImpl" timeout="2000"/>
Exception in thread "main" org.apache.dubbo.rpc.RpcException: Failed to invoke the method sayHello in the service demo.contract.DemoService. Tried 3 times of the providers [127.0.0.1:20881] (1/1) from the registry 127.0.0.1:2181 on the consumer 127.0.0.1 using the dubbo version 2.7.1. Last error is: Invoke remote method timeout.
aused by: org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout.
优先级
如果 provider 配置超时为 6000,consumer 配置超时为 2000,报超时错误。
如果 provider 配置超时为 2000,consumer 配置超时为 6000,正常运行,不会报超时错误。
可见,consumer超时和provider超时无法共存,consumer超时优先provider。
一般建议在 provider 配置超时,因为 provider 更清楚要配置为多少。consumer 配置的超时要参考 provider 配置的值。
默认全局超时
可以用 <dubbo:provider />
配置 provider 的全局超时;用 <dubbo:consumer/>
在 consumer 侧配置超时。
例如:
<dubbo:provider timeout="2000"/>