共计 1405 个字符,预计需要花费 4 分钟才能阅读完成。
UML
工夫轮算法
工夫轮是一种高效、低提早的调度数据结构。其在 Linux 内核中宽泛应用,是 Linux 内核定时器的实现办法和根底之一。按应用场景,大抵能够分为两种工夫轮:原始工夫轮和分层工夫轮。分层工夫轮是原始工夫轮的降级版本,来应答工夫“槽”数量比拟大的状况,对内存和精度都有很高要求的状况。提早工作的场景个别只须要用到原始工夫轮就能够。
constructor
public HashedWheelTimer(ThreadFactory threadFactory, // 定时工作都是后台任务,须要开启线程,咱们通常会通过自定义 threadFactory 来命名线程,嫌麻烦就应用 Executors.defaultThreadFactory()
long tickDuration, // 一格的工夫长度,默认 100ms
TimeUnit unit, // 一格的工夫长度,默认 100ms
int ticksPerWheel, // 一圈有多少格,默认 512
boolean leakDetection,// 用于追踪内存透露
long maxPendingTimeouts// 最大容许期待的 Timeout 实例数,也就是咱们能够设置不容许太多的工作期待。如果未执行工作数达到阈值,那么再次提交工作会抛出 RejectedExecutionException 异样。默认不限度
) {}
原理剖析
1、HashedWheelTimer 实质上是一个 Timer,用于将工作定时执行,newTimeout 用于增加工作,stop 用于终止 Timer 执行。
2、HashedWheelTimeout 封装了待执行的工作 TimerTask,并记录属于哪个工夫轮,被增加到哪个 bucket 上,以及前后节点信息,并提供了工作勾销、删除和超时执行的能力。
3、Worker 封装了线程执行工作的能力。
4、HashedWheelBucket 保护了存储待执行工作的双向链表,并提供了增加、删除和超时执行工作的能力。
应用场景
工夫轮是一个高性能,低消耗的数据结构,它适宜用非准实时,提早的短平快工作,例如心跳检测。在 netty 和 kafka 中都有应用。
HashedWheelTimer 实质是一种相似提早工作队列的实现,那么它的特点如上所述,实用于对时效性不高的,可疾速执行的,大量这样的“小”工作,可能做到高性能,低消耗。
HashedWheelTimer 工夫轮是一个高性能,低消耗的数据结构,它适宜用非准实时,提早的短平快工作,比方心跳检测和会话探活,对于可靠性要求比拟严格的提早工作,工夫轮目前并不是比拟好的解决方案,起因如下:原生工夫轮是单机的,在分布式和多实例部署的场景中乏力;宕机从新复原执行,原生工夫轮的存储是 Mpsc 队列,毫无疑问是内存存储,如果呈现宕机或者重启,数据是不可复原的;对于相似订单超时勾销的场景,能够思考工夫轮 +zk + db 的形式实现,zk 做中心化管制,防止超时工作在多节点反复执行,也即是数据去重,db 做为延时工作的长久化存储,宕机可复原。
HashedWheelTimer 利用场景大抵有:
● 心跳检测 (客户端探活)
● 会话、申请是否超时
● 音讯提早推送
● 业务场景超时勾销 (订单、退款单等)
参考文章
https://www.bianchengquan.com…
https://www.jianshu.com/p/1eb…
https://www.javadoop.com/post…