一、工夫轮算法简介
为了大家可能了解下文中的代码,咱们先来简略理解一下netty工夫轮算法的外围原理
工夫轮算法货真价实,工夫轮就是一个环形的数据结构,相似于表盘,将工夫轮分成多个bucket(比方:0-8)。假如每个工夫轮轮片的分隔时间段tickDuration=1s(即:指针通过每个格子破费工夫是 1 s),以后的工夫bucket=3,那么在18秒后须要被执行的工作须要落到((3+18)%8=5取余运算)的5号bucket上。如果有多个须要在该时间段内执行的工作,就会组成一个双向链表。
另外针对工夫轮咱们要有上面的几个认知:
- 工夫轮指针是一个Worker线程,在工夫轮整点的时候执行双向链表中的工作。
- 工夫轮算法的并不是精准的延时,它的执行精度取决于每个工夫轮轮片的分隔时间段tickDuration
- Worker线程是单线程,一个bucket、一个bucket的程序解决工作。所以咱们的延时工作肯定要做成异步工作,否则会影响工夫轮后续工作的执行工夫。
二、工夫轮hello-world
实现一个延时工作的例子,需要依然非常的简略:你买了一张火车票,必须在30分钟之内付款,否则该订单被主动勾销。订单30分钟不付款主动勾销,这个工作就是一个延时工作。 咱们的火车票订单勾销工作,从需要上看并不需要十分精准的延时,所以是能够应用工夫轮算法来实现这个工作的。
首先通过maven坐标引入netty
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.45.Final</version></dependency>
而后咱们创立一个工夫轮,如果是Spring的开发环境,咱们能够这么做。下文中咱们new了一个蕴含512个bucket的工夫轮,每个工夫轮的轮片工夫距离是100毫秒。
@Bean("hashedWheelTimer")public HashedWheelTimer hashedWheelTimer(){ return new HashedWheelTimer(100, TimeUnit.MILLISECONDS, 512);}
举例:当用户买火车票下单的时候,向工夫轮中增加一个30分钟的延时工作。延时工作将在30分钟之后被执行,下文的lambda表达式局部实现了一个TimerTask(task)延时工作。这个延时工作的函数体内,请肯定应用异步工作,即:独自起一个线程或者应用SpringBoot异步工作线程池。因为Worker线程是单线程的,你的工作解决工夫长于tickDuration会障碍后续工夫轮轮片上的工作的执行。
//订单下单操作void order(String orderInfo) { //下单的时候,向工夫轮中增加一个30分钟的延时工作 hashedWheelTimer.newTimeout(task -> { //留神这里应用异步工作线程池或者开启线程进行订单勾销工作的解决 cancelOrder(orderInfo); }, 30, TimeUnit.MINUTES);}
三、异步工作线程池
咱们在上文中曾经屡次强调,工夫轮的工作TimerTask的执行内容要做成异步的。最简略的做法就是接到一个工作之后启动一个线程解决该工作。在Spring环境下其实咱们有更好的抉择,就是应用Spring的线程池,这个线程池是能够自定义的。比方:下文中的用法是我当时定义了一个名字为test的线程池,而后通过@Async应用即可。
@Async("test")public void cancelOrder(String orderInfo){ //查问订单领取信息,如果用户未领取,敞开订单}
可能有的敌人,还不晓得该如何自定义一个Spring线程池,能够参考:我之前写过一个SpringBoot的可观测、易配置的线程池开源我的项目,源代码地址:https://gitee.com/hanxt/zimug... 。我的这个zimug-monitor-threadpool开源我的项目,能够做到对线程池应用状况的监控,我本人平时用的成果还不错,向大家举荐一下!
四、工夫轮优缺点
工夫轮算法实现延时工作的长处就是,绝对于应用JDK的DelayQueue,其算法上具备劣势,执行性能绝对好一些。
其毛病就是所有的延时工作以及延时触发的治理,都是在单个应用服务的内存中进行的,一旦该应用服务产生故障重启服务,工夫轮工作数据将全副失落。这一毛病和DelayQueue是一样的。为了解决这个问题,咱们能够应用redis、RocketMQ等分布式中间件来治理延时工作音讯的形式来实现延时工作,这个我会在后续的文章中为大家介绍。
欢送关注我的布告号:字母哥杂谈,回复003赠送作者专栏《docker修炼之道》的PDF版本,30余篇精品docker文章。字母哥博客:zimug.com