惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
H
Help Net Security
B
Blog RSS Feed
G
Google Developers Blog
博客园 - 司徒正美
MongoDB | Blog
MongoDB | Blog
量子位
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
P
Proofpoint News Feed
小众软件
小众软件
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
V
V2EX
月光博客
月光博客
C
Check Point Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
Arctic Wolf
Help Net Security
Help Net Security
Schneier on Security
Schneier on Security
D
DataBreaches.Net
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
T
Tenable Blog
L
LangChain Blog
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
F
Fortinet All Blogs
Recent Announcements
Recent Announcements
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Y
Y Combinator Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
NISL@THU
NISL@THU
GbyAI
GbyAI
博客园 - Franky
S
Secure Thoughts
有赞技术团队
有赞技术团队
PCI Perspectives
PCI Perspectives
U
Unit 42

王欣的博客

第6章:工具篇——使用 RunningHub(ComfyUI)生成短剧 - 王欣说AI|信息安全|AIGC|AI 第5章:工具篇——使用小云雀Agent生成短剧 - 王欣说AI|信息安全|AIGC|AI 第4篇:导演思维 + AI素材生成全流程 - 怎么用AI从0做出短剧/漫剧? - 王欣说AI|信息安全|AIGC|AI 马斯克出手!SpaceX 豪掷 600 亿美元锁定 Cursor,AI 编程江湖巨变 - 王欣说AI|信息安全|AIGC|AI 第3篇:编剧篇——一切从一个好故事开始 - 怎么用AI从0做出短剧/漫剧? - 王欣说AI|信息安全|AIGC|AI 第2篇:四项基本功——提示词、镜头语言、剪映、投流 - 怎么用AI从0做出短剧/漫剧? - 王欣说AI|信息安全|AIGC|AI 第1篇:为什么2026年是一个人拍短剧的最佳时机?- 怎么用AI从0做出短剧/漫剧? - 王欣说AI|信息安全|AIGC|AI 2026 AI 开发新范式:Harness Engineering(驾驭工程)为何是智能体的决胜点? - 王欣说AI|信息安全|AIGC|AI 通过Claude Code的源码分析其技术架构 - 王欣说AI|信息安全|AIGC|AI 没团队、没演员、没经验——我一个写代码的,用AI独自做完了短剧《顶级温差》 - 王欣说AI|信息安全|AIGC|AI 谁能替你操作电脑?OpenClaw vs Claude Code vs Codex 终极拆解 - 王欣说AI|信息安全|AIGC|AI OpenClaw macOS安装:飞书机器人一键生成小说+分镜 - 王欣说AI|信息安全|AIGC|AI AI公司亲自下场研究 Macos上跑Docker Desktop遇到registry-1.docker.io网络不通问题填坑笔记 - 王欣说AI|信息安全|AIGC|AI Macos上跑Docker Desktop遇到registry-1.docker.io网络不通问题填坑笔记 - 王欣的博客|微服务|RPC|信息安全|AIGC RocketMQ的死信队列你了解多少?怎么实现的? - 王欣说AI|信息安全|AIGC|AI RocketMQ的死信队列你了解多少?怎么实现的? - 王欣的博客|微服务|RPC|信息安全|AIGC Dubbo服务间的连接是怎么控制处理的? - 王欣说AI|信息安全|AIGC|AI Dubbo服务间的连接是怎么控制处理的? - 王欣的博客|微服务|RPC|信息安全|AIGC Seata 基本原理和源码分析 - 王欣说AI|微服务|RPC|信息安全|AIGC 分布式事务一致性算法Paxos、raft、zab等的比较 - 王欣说AI|微服务|RPC|信息安全|AIGC 谈谈各种流程引擎、规则引擎 - 王欣说AI|微服务|RPC|信息安全|AIGC 从netty组件的传输讲讲io - 王欣说AI|微服务|RPC|信息安全|AIGC JVM内存结构的历史 (从Jdk1.6、1.7、8) - 王欣说AI|信息安全|AIGC|AI 怎么定位线上的内存溢出? - 王欣说AI|微服务|RPC|信息安全|AIGC MQ组件盘点,哪些你用在了生产中? - 王欣说AI|信息安全|AIGC|AI JVM内存结构的历史 (从Jdk1.6、1.7、8) - 王欣的博客|微服务|RPC|信息安全|AIGC 怎么定位线上的内存溢出? - 王欣的博客|微服务|RPC|信息安全|AIGC Seata 基本原理和源码分析 - 王欣的博客|微服务|RPC|信息安全|AIGC 分布式事务一致性算法Paxos、raft、zab等的比较 - 王欣的博客|微服务|RPC|信息安全|AIGC 谈谈各种流程引擎、规则引擎 - 王欣的博客|微服务|RPC|信息安全|AIGC 从netty组件的传输讲讲io - 王欣的博客|微服务|RPC|信息安全|AIGC MQ组件盘点,哪些你用在了生产中? - 王欣的博客|微服务|RPC|信息安全|AIGC 一些有用的github配置 - 王欣说AI|信息安全|AIGC|AI 一些有用的github配置 - 王欣的博客|微服务|RPC|信息安全|AIGC 我看《subscribed》 - 王欣说AI|信息安全|AIGC|AI 我看《subscribed》 - 王欣的博客|微服务|RPC|信息安全|AIGC 为什么Redis读写快? - 王欣说AI|微服务|RPC|信息安全|AIGC 为什么Redis读写快? - 王欣的博客|微服务|RPC|信息安全|AIGC Dubbo代码分析—超时和重试设计 - 王欣的博客|微服务|RPC|信息安全|AIGC 【译】apache 基金会角色列表 - 王欣说AI|微服务|RPC|信息安全|AIGC 【译】apache 基金会角色列表 - 王欣的博客|微服务|RPC|信息安全|AIGC Dubbo代码分析---服务端线程池 - 王欣说AI|微服务|RPC|信息安全|AIGC rpc跟踪日志常用shell统计脚本 - 王欣说AI|微服务|RPC|信息安全|AIGC Dubbo代码分析---服务端线程池 - 王欣的博客|微服务|RPC|信息安全|AIGC rpc跟踪日志常用shell统计脚本 - 王欣的博客|微服务|RPC|信息安全|AIGC 并发 - 谈谈HashMap和ConcurrentHashMap - 王欣说AI|微服务|RPC|信息安全|AIGC 并发 - 谈谈HashMap和ConcurrentHashMap - 王欣的博客|微服务|RPC|信息安全|AIGC JVM基本结构 - 王欣说AI|微服务|RPC|信息安全|AIGC JVM基本结构 - 王欣的博客|微服务|RPC|信息安全|AIGC 血的教训:线程池定义一定要全局化,共享使用 - 王欣说AI|微服务|RPC|信息安全|AIGC 谈谈并发包的工具都是用在什么地方,底层是怎么实现的? - 王欣说AI|信息安全|AIGC|AI 血的教训:线程池定义一定要全局化,共享使用 - 王欣的博客|微服务|RPC|信息安全|AIGC
Dubbo代码分析—超时和重试设计 - 王欣说AI|微服务|RPC|信息安全|AIGC
2019-02-11 · via 王欣的博客

dubbo提供在provider和consumer端,都提供了超时(timeout)和重试(retries)的参数配置。

一、Dubbo协议中的超时机制

​ 超时机制是dubbo中的一个很重要的机制。在“快速失败”设计中,能将客户端断掉,防止服务端资源耗尽而被压挂。

​ 我们先看一下Dubbo协议中的超时机制是怎么实现的。

​ 超时的实现原理是什么?

我们先回顾一下dubbo的大致流程图。

在生产过程中都是客户端向服务端发送请求,在流程4。

​ 我们可以看到:4的流程是: 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

​ 超时是针对消费端还是服务端?

  • 如果是争对消费端,那么当消费端发起一次请求后,如果在规定时间内未得到服务端的响应则直接返回超时异常,但服务端的代码依然在执行。
  • 如果是争取服务端,那么当消费端发起一次请求后,一直等待服务端的响应,服务端在方法执行到指定时间后如果未执行完,此时返回一个超时异常给到消费端。

dubbo的超时是争对客户端的,由于是一种NIO模式,消费端发起请求后得到一个ResponseFuture,然后消费端一直轮询这个ResponseFuture直至超时或者收到服务端的返回结果。虽然超时了,但仅仅是消费端不再等待服务端的反馈并不代表此时服务端也停止了执行。

​ 超时的实现原理是什么?

之前有简单提到过, dubbo默认采用了netty做为网络组件,它属于一种NIO的模式。消费端发起远程请求后,线程不会阻塞等待服务端的返回,而是马上得到一个ResponseFuture,消费端通过不断的轮询机制判断结果是否有返回。因为是通过轮询,轮询有个需要特别注要的就是避免死循环,所以为了解决这个问题就引入了超时机制,只在一定时间范围内做轮询,如果超时时间就返回超时异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64


public interface ResponseFuture {






Object get() throws RemotingException;







Object get(int timeoutInMillis) throws RemotingException;






void setCallback(ResponseCallback callback);






boolean isDone();
}





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();
}
超时解

超时的实现原理是什么?
之前有简单提到过, dubbo默认采用了netty做为网络组件,它属于一种NIO的模式。消费端发起远程请求后,线程不会阻塞等待服务端的返回,而是马上得到一个ResponseFuture,消费端通过不断的轮询机制判断结果是否有返回。因为是通过轮询,轮询有个需要特别注要的就是避免死循环,所以为了解决这个问题就引入了超时机制,只在一定时间范围内做轮询,如果超时时间就返回超时异常。

二、Dubbo协议中的重试机制

在客户端
int DEFAULT_RETRIES = 2;
看到重试次数是2 ,就是说出了本身的一次请求,再失败后,又会再请求一次。

重试策略在集群的失败重试 FailoverClusterInvoker 的策略中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public Result doInvoke(Invocation invocation, final List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
List<Invoker<T>> copyInvokers = invokers;
checkInvokers(copyInvokers, invocation);
String methodName = RpcUtils.getMethodName(invocation);
int len = getUrl().getMethodParameter(methodName, RETRIES_KEY, DEFAULT_RETRIES) + 1;
if (len <= 0) {
len = 1;
}

RpcException le = null;
List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyInvokers.size());
Set<String> providers = new HashSet<String>(len);
for (int i = 0; i < len; i++) {


if (i > 0) {
checkWhetherDestroyed();
copyInvokers = list(invocation);

checkInvokers(copyInvokers, invocation);
}
Invoker<T> invoker = select(loadbalance, invocation, copyInvokers, invoked);
invoked.add(invoker);
RpcContext.getContext().setInvokers((List) invoked);
try {
Result result = invoker.invoke(invocation);
......

可以看到使用的是for循环做的失败重试的。当有异常发生时候,就重试一次访问,直到达到最大重试次数为止。

参考:https://www.cnblogs.com/xuwc/p/8974709.html