博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dubbo超时异常
阅读量:5848 次
发布时间:2019-06-19

本文共 3081 字,大约阅读时间需要 10 分钟。

hot3.png

dubbo超时异常

在调用dubbo服务时经常看到如下错误: Caused by: com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer.

源码分析

客户端调用远程服务时,本地会生成一个DefaultFuture,调用DefaultFuture.get()获取远程服务返回的结构,此方法获取锁,调用await方法,此时当前线程进入等待队列,此线程会有两种结果过:要么超时,抛出TimeOutException;如果被唤醒,则返回rpc的结果。 而这里的报错很明显是由于等待服务端返回结果时客户端超时异常,查看源码如下:

public class DefaultFuture implements ResponseFuture {    private static final Logger                   logger = LoggerFactory.getLogger(DefaultFuture.class);    private static final Map
CHANNELS = new ConcurrentHashMap
(); private static final Map
FUTURES = new ConcurrentHashMap
(); // invoke id. private final long id; private final Channel channel; private final Request request; private final int timeout; private final Lock lock = new ReentrantLock(); private final Condition done = lock.newCondition(); private final long start = System.currentTimeMillis(); private volatile long sent; private volatile Response response; private volatile ResponseCallback callback; public DefaultFuture(Channel channel, Request request, int timeout){ this.channel = channel; this.request = request; this.id = request.getId(); this.timeout = timeout > 0 ? timeout : channel.getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT); // put into waiting map. FUTURES.put(id, this); CHANNELS.put(id, channel); } public Object get() throws RemotingException { return get(timeout); } public Object get(int timeout) throws RemotingException { if (timeout <= 0) { timeout = Constants.DEFAULT_TIMEOUT; } if (! isDone()) { long start = System.currentTimeMillis(); lock.lock(); try { while (! isDone()) { done.await(timeout, TimeUnit.MILLISECONDS); if (isDone() || System.currentTimeMillis() - start > timeout) { break; } } } catch (InterruptedException e) { throw new RuntimeException(e); } finally { lock.unlock(); } if (! isDone()) { throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false)); } } return returnFromResponse(); }}

这里的超时时间设置的是1s

public static final int     DEFAULT_TIMEOUT                    = 1000;

解决方案

检查消费者配置查看是否配置总的超时时长,这里建议配置一个总的,我由于没配置导致使用的是默认配置使得超过1s就报错。

也可以在消费者端对每个服务自定义配置

这里也需要注意服务端也有一个超时时间

  • 全局配置
  • 服务配置

当客户端timeout值>服务端timeout值,会出现超时日志,但是仍然可以获取到结果。客户端timeout超时抛出异常时,有一个线程RemotingInvocationTimeoutScan会自动清理对应超时的Future。

转载于:https://my.oschina.net/u/560547/blog/1618773

你可能感兴趣的文章
Ubuntu 16.04安装Eclipse
查看>>
java中Object转String
查看>>
需求用例分析之备选流
查看>>
redis之如何配置jedisPool参数
查看>>
《系统架构师》——操作系统和硬件基础
查看>>
FTP下载工具
查看>>
oauth2-server-php for windows 的那些坑 (研究中...)
查看>>
文件名后缀详解
查看>>
PHP ElasticSearch的使用
查看>>
微信公众号文章采集方案
查看>>
[转]jquery的一个模板引擎-zt
查看>>
步步为营 .NET 设计模式学习笔记 四、Singleton(单例模式)
查看>>
步步为营 .NET 代码重构学习笔记系列总结
查看>>
最近的几篇NLog相关文章 & 《The Zen of CSS Design》
查看>>
android.app.Activity
查看>>
定时任务quartz
查看>>
Net内存程序集通用脱壳机实现原理(二、反射以及重建方法头)
查看>>
SGU 246 Black & White(思考的转化)
查看>>
HDU 4390 Number Sequence(容斥原理+组合计数)
查看>>
BZOJ 2111 Perm 排列计数(满二叉树)
查看>>