jfinal 订单超时,任务跟踪
各路牛人,请教一个问题:现在我们需要开发一个类似滴滴打车一样的系统,用户提交一个订单后,服务器(jfinal,感谢波总)根据匹配原则,主动推送(ddpush)订单给一个司机。同时服务器需要定时,如果在1分钟钟没有接单,再推送给下一个司机,以此类推。由于可能订单很多(几万个),如何来做这个定时任务是个比较棘手的问题。拟采用方案:1、采用一个list,每个订单生成后放到这个list中,拿一个线程专门扫描,并完成相应逻辑。2、每个订单,生成一个线程或者timer任务。3、用quartz,但是如何使用还不是很清楚。请高手指导一下,应该采用哪种策略,最好有开源的框架,配合Jfinal一起用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
定时任务使用 quartz或con4j 更好,使用轮询浪费资源而且效率低。建议使用 @玛雅牛 做的JFinal极简任务调度插件 jfinal-scheduler,使用非常简单。
订单数据持久化,并且做个状态字段,可能有这些状态:初始、推送中、已接单、接单失败,状态是持久化的,以便于在操作过程中出问题后恢复正常,例如推送过程中系统重启或断电。
看到各位大牛提出的宝贵意见,万分感谢!现在思路清晰了。谢谢,马上做手实现。
维护两个队列,一个是未分配订单,一个是已分配订单
未分配订单不必说,就是个单向的,进出一次。
已分配订单还是一分钟扫一次,如果接了,直接删掉,如果没接,就再分一次追加到队列末尾。
消息怎么处理1分钟这个定时?
回复
callable和future应该可以实现。专门有那种线程超时处理。
消息,MQ
麻烦再讲一下具体如何操作定时的那部分呢,如果都放到队列中,也必须对每个任务进行定时监听。因为我推送给某个用户后,必须监听用户1分钟内是否有接单,如果没有接单,需要重新选择下一个用户。
回复
接单的话会在你的订单系统里有反映。此方案的定时执行完全依靠activeMQ,你只需要在每次执行的时候查询下订单是否被谁接了,执行相应的任务即可。
回复
不知楼主最终方案怎么做的?
回复
现在还没有确定,头疼中,其实我们的应用中订单有很多个状态,每个状态都需要定时功能。知道最终订单付费完成才close。quartz不是专门用于多任务定时完成的吗?为什么大家都没提到这种方式呢?
你这业务需求显然不是quartz单单定时就能解决的,每个订单的时间各异,所以方案里推荐这种监听消费方式。
下单后,把任务信息推送到activeMQ,activeMQ有延迟队列可以间隔一段时间。你可以间隔一段相等的时间,也可以是间隔时间越来越长(根据客户端的配置)。你分布式部署多个程序多线程监听Mq进行消费,消费失败扔回Mq,会自动间隔时间后再次消费,可以定义超过一定消费次数的任务进入死信队列。此方案中,activeMQ和消费程序都可以分布式避免单点,失败的任务可以追踪。
对于少量的定时器,那种方案都不是问题,#jfinal-scheduler#当然也可以。
当有几万/几十万定时器时,就必须自己设计定时器了。
首先设定约束和假定条件:
1)定时器的精度要求达到秒级即可(比如定时器为1分钟,误差1~5秒都是可以的)。
2)最好支持集群部署/分布式部署。
3)假定所有应用服务器使用同一台时间服务器,每隔10分钟自动同步一次,所有服务器的时间误差在1秒以内。
4)定时器的触发并不强制要求有序(比如,定时器为1分钟,误差1秒,几乎同时先后启动的两个定时器,实际执行时并不一定按启动的顺序执行,但对于每一个业务对象来说是有序的)
5)系统中的定时器有一定规律,并不是所有都是随机的,比如有60秒的定时器,120秒的定时器。
设计方案:
启动定时器时,定时器的超时绝对时间=系统当前绝对时间+定时器时间(相对时间,比如60秒)。
基于3)和5)对于所有应用系统来说,同一类定时器(比如60秒定时器)绝对超时时间是一个有序列表,或者说这类定时器一定是依次激活的。
当然系统中可能存在多种类型的定时器,所以还需要一个支持自动排序的数据结构,可选的有红黑树和最小堆,Nginx是利用红黑树来管理定时器,而libevent是利用最小堆来管理定时器。具体可以查看相关文献。
所以最终的设计如下:
1)使用红黑数/最小堆维护一个可自动排序的定时器列表(TreeMap/TreeSet),单线程轮询,并用线程池派发处理。在具体的超时处理服务器上实现。
2)每一类定时器使用一个单独队列,此类定时器均自动放到队列尾部,依据定时器要求的误差要求定期从队列头部取处最近(误差范围内的都取)的定时器,并将此定时器放到1)中的定时器中。每个队列一个线程。可以做成集群/分布式式队列。
这样做的优势如下:
1)红黑树/最小堆相对较小,效率比较高。
2)队列实现可集群/分布处理,利用应用特性,依然效率较高。
以上是个人愚见,希望对你有用。