我在做一个球场场次预约方面的接口开发,现在有这样的需求,求大神给与解决思路:
前提:在小程序界面上,有N个球场,用户根据自己的时间选择想要的球场,球场开放的时间从每天早上8:30,到晚上22:00 结束,间隔1个半小时。用户在小程序上下单支付后,到现场出示二维码进场核销。
操作:用户选择某一个场次,比如选择了 2023-12-10 的 17:30 - 19:00 的场次,并支付了费用,但是到了时间他却没来,系统如何自动在19:00后,自动释放这个场次?
当然,考虑过定时任务,有没有更好的办法解决这个问题?
支付成功之后给当前场次新增延时队列,到时间自动执行,验证当前场次是否使用,没有使用则释放
大神,那这种延时队列和定时任务哪个是最优解?
当然延迟队列,也复杂不了很多
了解了,感谢
1.定时任务写起来简单,根据场次结束时间戳去扫描任务是否过期(场次是否结束)
2.延时队列,请查看 https://www.workerman.net/plugin/12.
任务不多的情况下,就定时任务。任务多还是用队列比较好。你使用定时任务多久执行一次扫描呢?
你的场次记录越来越多,下单记录越来越多,举个例子:
上线1个月1000订单,场次50个
上线6个月6000订单,场次300个
定时任务去扫描:
time() > 场次结束时间,进行更新场次结束状态。
就算你添加了索引,那也得需要每次遍历整个索引记录。
(优点自然是写起来块,开发方便,数据量不大适合)
延时队列:
time() > 场次结束时间,进行更新场次结束状态。
每次下单投递数据 ( 订单id,场次id 等等主要信息即可)
优点(性能好点,毕竟每次处理不需要从头遍历整个索引,直接场次主键, 订单主键就能找到记录),(每次不用扫描重复以前的记录)
缺点:你多了服务器依赖要维护,代码量要多一点。
这绝对是 2023年度最佳回复,谢谢大神!
说实话,对于这个,我也不清楚定时多久合适,我目前随便设置了10分钟,当然,我知道肯定频繁,上线我预估1个小时干一次,当然,您说的很对,这个就看数据量大小了。
好吧,我先储备一下队列,稍后上线后,如果单天量高,我就立刻换队列。
再次感谢大神的详细指导,这绝对受益匪浅!
大神,我再追问一下,如果让您来选择,您凭您的专业,预估觉得多少数据量就应该选择队列?
是我就不释放只记录,球场一张表不存状态,预约记录一张表,查状态直接去预约表里按条件查(状态可缓存,修改预约记录的话记得释放缓存),队列有个问题(单指laravel哈,webman的我还没用过)放入队列就没办法控制了,如果预约过再取消就很不好做
我目前就是场次一张表,预约记录一张表,我先阶段没那么复杂去处理,用户下单未支付的保留十分钟的,我直接放 redis 里去了,设置 redis 过期十分钟后释放,反正客户不在乎未支付的订单数据。其他的都入库,然后根据定时任务去更新预约记录的状态。
(1)用户表:用户信息
(2)球场配置表:球场信息,球场时段及时段开放价格 配置 等
(3)球场预约表:球场时段预约记录,核销码 及生效状态 等
(4)订单表:球场预约的支付订单 等
(1)用户查询球场预约各时段的最新状态(球场配置表+球场预约表)。
(2)用户下单(球场配置表+球场预约表+订单表+延时队列)。这里需判断在下单时预约时段被抢占的问题。
(3)通过延时消息可操作:关闭未支付订单;增加时段即将开放前的短信通知;若到期用户未核销 则更新核销码的生效状态,并完成自动退款及短信通知。
(1)数据库:https://www.workerman.net/doc/webman/db/tutorial.html
(2)RabbitMQ 插件:https://www.workerman.net/plugin/67。
注意使用1.x版本:https://github.com/workbunny/webman-rabbitmq/blob/1.x/README.md。
1.x版本相关提问:https://www.workerman.net/q/10665。
(3)容器部署 RabbitMQ 并安装延时插件:https://www.yuque.com/caesartang/su2cap/ytih9c?singleDoc# 《容器部署 - RabbitMQ》
(1)定时任务执行,需要每次扫表
(2)若定时任务处理的业务比较复杂且堵塞,则会影响核销码及订单的及时处理
(3)业务量大,会造成任务堆积
延时消息,一定要安装延时插件;延时消息存在rabbitmq,需要持久化,避免rabbitmq重启后消息丢失;服务版本升级时,需考虑新升级的服务是否能正确处理旧版本业务投递的延时消息,服务部署最好使用nginx做代理 等
感谢大神的详细资料,谢谢!!!!