除了前面提到的基于zset和rabbitmq的方式。还有一些方式。
1、数据库直接轮询select where ,然后 处理逻辑然后update。
这种方式虽然low,但是,是最简单,最容易实现,最不容易出问题的方式。。。
如果数据不大,而且短期没有那么大的任务,真的没必要搞得那么复杂。
2、基于jdk得DelayQueue方式。
java得delayQueue就是个延迟队列,自然可以处理处理延迟消息。
缺点就是:
1、需要自己做持久化。
2、扩容、高可用方面需要自己思考实现。
3、基于时间轮得方式。
时间轮两个数据结构:
1、环形队列。
2、队列种每个slot,防止一个set任务。
有一个指针轮询在这个环上移动,移动到哪个slot,则这个slot得符合要求得元素,则到期了。
每次put一个任务,计算这个任务应该放到哪个slot,并且,这个任务得年龄为多少。(比如,环有32个slot,一个slot代表一分钟,则一个任务延迟64分钟,则年龄为64 / 32 = 2, 现在指针指向得是第一个slot,则应该把这个任务,放到第一个slot上,年龄为2),然后指针移到到哪个slot,则这个slot年龄为1得元素,到期了,其他得元素,年龄-1。如此,一个线程就可以跑完所有得任务。
缺点:
1、这个一个内存队列,要自己实现持久化。
2、扩容、高可用需要自己思考实现。
4、找一些开源东西
比如,beanstalks这个消息中间件就能搞定延迟队列。
总结:反正,最后都是看业务来做,小业务,直接select 轮询吧。其他得,再考虑其他得。
网友评论