有一个有关订单自动取消的问题,请大家指教一下

2017-11-20 09:48:43 +08:00
 zhangwugui

前提:是这样的,一笔订单下单之后,如果不支付,会处于待支付状态。而一般这个订单会有类似 30 分钟不支付自动取消订单的功能。

实现:这种功能的实现,可以通过定时任务,每隔 30 秒或一分钟扫描一次。但如果集群环境下,可能定时任务会执行重复。当然我们可以通过类似操作系统 PV 操作限制同一时段只能一个定时任务执行。

目标:我想知道,这种情况,除了定时任务,还有没有其他好点的实现?

想法:目前在领导的提醒下,想到了用消息来处理,下完单后延时 30 分钟发送消息来处理,不知还有没有其他的处理方式,多谢大家,请多多指教。

9229 次点击
所在节点    程序员
51 条回复
skyFuture
2017-11-20 12:10:23 +08:00
我觉得你考虑有点多,任务多次执行?执行一次任务和多次任务的效果目标都是会导致订单的取消掉。有何不可呢?而且有木有算过比例呢?值得让整个流程变的更加复杂呢?
just1
2017-11-20 12:18:11 +08:00
用户触发+定时( 1 小时一次),应该是个不错的方案
zhangwugui
2017-11-20 13:47:56 +08:00
@skyFuture 订单取消我们会涉及到退积分相关的操作,所以只有执行一次。而退积分又是 RPC 操作,我目前控制不了这个。但这个不是主要问题,我是说对于一段时间内自动取消订单这类问题,有没有更好的实现方案。
zhangwugui
2017-11-20 13:51:21 +08:00
@openbsd 哈哈哈,反正我们是下单减库存,不是扣款减库存。
zhangwugui
2017-11-20 13:55:22 +08:00
@YORYOR 是和幂等有点关系,不过我这的主要问题是 一段时间内订单的自动取消问题。
openbsd
2017-11-20 13:58:31 +08:00
@zhangwugui 内部系统么 ?下单前会核实库存数量不 ?
有人恶意下个 9999999....的单,会怎样?
好邪恶的想法
chocotan
2017-11-20 13:59:41 +08:00
我们用的 tbschedule
zhangwugui
2017-11-20 14:00:57 +08:00
@yuankui 嗯,延时队列可以考虑使用。下次试一试。
heyang
2017-11-20 14:00:58 +08:00
维护一个优先级队列,以超时时间作为优先权,每隔 n 秒扫描一下队头( n 值取决于你们对延迟的敏感程度),只要队头节点大于等于当前时间就把队头节点丢到 worker 里去处理取消订单逻辑,队头节点超时时间小于当前时间,就完成此次扫描。
如果业务量特别大,队列长度可以做限制,生产节点时如果超长,就把节点持久化从队列删除,消费节点时如果达到阈值,从磁盘读取节点,补充队列。
Jealee
2017-11-20 14:02:31 +08:00
我写过这种,利用的是 redis 发布订阅(pub/sub)
weer0026
2017-11-20 14:08:59 +08:00
刚做完这个功能,延时队列+10086,分布式情况下维护一个公共队列。
owenliang
2017-11-20 14:17:13 +08:00
脚本最靠谱,状态机,乐观锁什么的就不提了。
MiguelValentine
2017-11-20 14:32:50 +08:00
redis expire - -什么都不用操心
zhangwugui
2017-11-20 15:51:56 +08:00
@MiguelValentine 放到 redis 缓存里?每看太懂呢。

@owenliang 哈哈哈,脚本也是一种方式。

@weer0026 嗯,延时队列我也准备试试。

@Jealee 这是用 redis 做消息队列么
owenliang
2017-11-20 16:13:07 +08:00
有兴趣加我 Q 聊:120848369
Jealee
2017-11-20 16:22:19 +08:00
@zhangwugui reids 2.8 有一种 键空间通知的机制 Keyspace Notifications, 允许客户端去订阅一些 key 的事件,其中就有 key 过期的事件,我们可以把 key 名称设置为 task 的 id 等标识(这种方式 value 的值无法取到,所以只用 key 来识别任务),expire 设置为计划要执行的时间,然后开启一个客户端来订阅消息过期事件,然后处理 task。(网上复制的,但大致思路就是这样)
stargazer242
2017-11-20 16:34:43 +08:00
扫描
SlipStupig
2017-11-20 16:42:50 +08:00
@Jealee 这种方法有个不好的地方,就是需要自定义一些 callback 否则涉及一些库存更新,无法直接完成
SlipStupig
2017-11-20 16:46:35 +08:00
@Jealee 还有一个坏处就一旦 hang out 后,可能导致大量消息丢失,跟踪都不好跟踪
Jealee
2017-11-20 16:55:46 +08:00
@SlipStupig 所以可以再做相对应的一些优化,比如服务异常处理之类的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/407801

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX