欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

更优雅的延迟执行实现---环形队列 博客分类: 架构相关 定时java环形队列

程序员文章站 2024-02-17 11:41:16
...

在做业务时经常遇到某些一次性的延迟需求,比如新闻的定时发布,过了一个时间阈值后某个任务的状态置为超时或触发某个接口。

之前实现这种一次性的延迟需求基本会有3种思路。

(1)线程轮询扫库

(2)Timer类

(3)定时框架Quartz

这三种方案都存在各自的问题

对于“线程轮询扫库”,性能开销巨大,实时性差

对于“Timer类”来说,假如项目重启,之前设置的定时就荡然无存

对于“定时框架Quartz”虽然支持DBstore,但是框架太过于重量级。

如何优雅而又高效的实现一个延迟任务呢?前不久看到一篇文章 https://mp.weixin.qq.com/s/eDMV25YqCPYjxQG-dvqSqQ ,似乎提供了一个不错的解法。

 

 

按照思路我自己实现了一个环形队列,https://git.oschina.net/spjich/RingQueue.git

引用文章里的一个图片:

 

 
更优雅的延迟执行实现---环形队列
            
    
    博客分类: 架构相关 定时java环形队列
 

这篇文章只是提出一个解决的思路,但是有几个问题并未说明

 

1.这种定时类似于内存里的状态机,是内存就必然会重启清除。 解决方案:需要将任务录入DB一份,重启项目构造环形队列时实现AbstractRingQueue的initData方法,将DB中还未完成的任务重新加载进来运行

 

2.大规模集群环境下如何保证正常运行? 解决方案:这点非常关键,在集群条件下,如果项目重启,那么一个任务就会被执行n次,此时我想到的解决方案是根据某种规则进行数据的初始化,比如某个集群里有3台机器编号分别为1,2,3,那么每台在initData的时候分别加载 taskId%3-机器编号=0 的任务。当然我提出的这种方案并不是最好的,他同样会存在热点问题,会使某台机器上运行的task比其他机器上多,大体解决思路可以参考一些负载均衡策略。

 

 

另外纠正下文章最后说“开源的MQ好像都不支持延迟消息”这句话,据我所知阿里的RocketMQ是支持延迟消息的。

 

 

原创文章转载请声明出处:http://spjich.iteye.com/blog

  • 更优雅的延迟执行实现---环形队列
            
    
    博客分类: 架构相关 定时java环形队列
  • 大小: 33 KB