用户自定义定时任务的php实现

需求:

一个类似滴答清单任务提醒的功能。用户可以自定义 每天 每周星期几,每月几号 接收提醒,方式不限于 短信 电子邮件 公众号推送.

例如,用户 a 设定一个每天 3 点提醒的任务 用户 b 设定一个每周三 5 点提醒的任务,用户 c 设定一个每月 3 号提醒的任务.

一般我们可以用 crontab 表达式来现实,但是成千上万的用户,有上万的定时任务怎么样用 crontab 实现呢?而且 php 没有好的定时任务系统.

我的解决办法是用 一个或者几个定时任务来实现.

用户的定时任务可以用一个表来保存。记录 定时任务的类型,是单次还是重复,类型是每天,每周,还是每年每月。具体提醒的 小时和分钟.

然后使用其他语言的定时任务系统,或者 laravel 自动的定时任务系统 (分钟级别就够) 来触发.

xxl-job-admin (java) 或者 jiacrontab (go)

写一个 laravel 自定义命令 用 以上的定时任务触发 例如 php artisan MyCrontab.

用 carbon 包,可以得出,现在这一分钟是 星期几,几号,小时,分钟,月份.
carbon.nesbot.com/docs/

然后写 sql 语句找出符合条件的任务出来。写入 laravel 队列来执行.

建议用户的定时任务可以设置几种状态,未执行,已入队列,执行完队列,把状态设置回未执行.

还有单次执行的任务和周期性重复的任务分开表存,查询的时候也分开查。最多几个 定时任务,就可以把 每年 每月 每日的任务查询出写入队列.

这个是其中一种实现方式。给大家参考一下。这种方式的缺点就是 要每分钟查表,如果这一分钟的用户定时任务有几百万。可能就不够时间写入队列.

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 12
zds

要不试试 swoole/workerman 的 timer

1年前 评论
农夫山泉 (楼主) 1年前
sanders

既然已经选用推送的方式 “短信 电子邮件 公众号推送” 就意味着应用对时间不是太敏感。这样的话,楼主的问题应该主要集中在大量消息如何快速访问对应接口下发的问题。

首先从功能上是要确定对方消息接口的吞吐量和单位时间上的调用配额,是否存在延时下发的逻辑或批量下发的逻辑,以及是否被 spam 或其他风控逻辑标注的风险。如果对方接口有相应的能力,尽量使用这些能力强过自己来控制。

不仅是楼主这种大批量消息下发的场景,其实所有大量任务执行的场景,在不考虑三方接口吞吐量限制的情况下,皆可以使用 Laravel 的队列任务进行并行处理。你只需要将生产的数据丢给队列,多开几个消费者进程便可以并行处理,考虑单台机器负载,还可以通过集群在多台机器上一起消费这些数据并处理。

1年前 评论
农夫山泉 (楼主) 1年前
sanders (作者) 1年前
周小云 1年前

我想到是:

  1. 任务调度(后台任务)
  2. 任务调度(后台任务) + 开多个进程队列(并发消费)
1年前 评论

定义个天级定时任务,每天把待发送的信息和发送时间拼好入库待发送表 定义个分钟级定时任务,每分钟取待发送表的数据丢队列中发送

如果有当天的新增 / 删除任务,操作待发送表数据实现当天任务实时变更 如果有单分钟待发送任务超高,在入库待发送表时应该可以识别,可以做个大数据方案的处理

1年前 评论
bb-bear (作者) 1年前
农夫山泉 (楼主) 1年前

你这种业务最近我刚好做过,了解一下时间轮算法。完整的思路你可以参考涂鸦的分享:segmentfault.com/a/119000002278353...

1年前 评论
农夫山泉 (楼主) 1年前