更新时间:2022年07月28日10时15分 来源:传智教育 浏览次数:
为什么需要时间轮?
在Dubbo中,为增强系统的容错能力,会有相应的监听判断处理机制。在Dubbo最开始的实现中,是将所有的返回结果(DefaultFuture)都放入集合中,并且通过定时任务扫描所有的 future,逐个判断是否超时。
但这样效率低下,Dubbo借鉴 Netty,引入了时间轮算法,减少无意义的轮询判断操作。
时间轮原理
时钟轮的实质上是参考了生活中的时钟跳动的原理。
在时钟轮机制中,有时间槽和时钟轮的概念,时间槽就相当于时钟的刻度;而时钟轮就相当于指针跳动的一个周期。
如果时钟轮有10个槽位,而时钟轮一轮的周期是10秒,那么我们每个槽位的单位时间就是1秒,而下一层时间轮的周期就是100秒,每个槽位的单位时间也就是10秒。
假设现在我们有 3 个任务,分别是任务 A(0.9秒之后执行)、任务 B(2.1秒后执行)与任务 C(12.1秒之后执行),我们将这 3 个任务添加到时钟轮中,任务 A 被放到第 0 槽位,任务 B 被放到第 2槽位,任务 C 被放到下一层时间轮的第2个槽位,如下图所示:
通过这个场景我们可以了解到,每个任务会按要求只扫描执行一次, 这样就能够很好的解决 CPU 浪费的问题。
Dubbo中的时间轮原理是如何实现?
主要是通过 Timer,Timeout,TimerTask 几个接口定义了一个定时器的模型,再通过 HashedWheelTimer 这个类实现了一个时间轮定时器。通过该定时器,Dubbo 实现了高效的任务调度。
时间轮在RPC的应用
调用超时: 在高并发、高访问量的情况下,时钟轮每次只轮询一个时间槽位中的任务,这样会节省大量的 CPU。
启动加载:比如服务启动完成之后要去加载缓存,执行定时任务等, 都可以放在时钟轮里。
定时心跳检测:可以将心跳的逻辑封装为一个心跳任务,放到时钟轮里。