超时是针对消费端还是服务端?
dubbo的超时是针对客户端的
超时的实现原理是什么?
dubbo默认采用了netty做为网络组件,它属于一种NIO的模式。消费端发起远程请求后,线程不会阻塞等待服务端的返回,而是马上得到一个ResponseFuture,消费端通过不断的轮询机制判断结果是否有返回。因为是通过轮询,轮询有个需要特别注要的就是避免死循环,所以为了解决这个问题就引入了超时机制,只在一定时间范围内做轮询,如果超时时间就返回超时异常。实现代码在DefaultFuture中的get方法中。
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();
}
超时解决的是什么问题?
当前端大量请求并发出现时,很有可以将业务线程池中的线程消费完,因为默认缺省的线程池是固定大小,对调用的服务设置超时时间,是为了避免因为某种原因导致线程被长时间占用,最终出现线程池用完返回拒绝服务的异常。
超时与服务降级
发生超时异常时,进而导致整个获取产品明细的接口异常,这也就是平常说的强依赖。这类强依赖是超时不能解决的,解决方案一般是两种:
调用时做异常捕获,返回空值或者返回具体的错误码,消费端根据不同的错误码做不同的处理。
调用做服务降级,比如发生异常时返回一个mock的数据,dubbo默认支持mock。
只有通过做异常捕获或者服务降级才能确保某些不重要的依赖出问题时不影响主服务的稳定性。而超时就可以与服务降级结合起来用。
超时重试可能会导致服务器雪崩。