怎么注册定时任务,自动回调?

现在业务需要这样一个功能:

需要一个类似定时任务的一个功能,比如用户开始某一个任务,假设时间限制30分钟。不管用户是否完成该任务,到30分钟(1800秒)后更新该任务状态或更新该任务对应的其它业务数据。不要访问触发有效期判断。

注册定时器:

参数:

  1. 回调时间:精确到秒。比如10s10s后执行回调url接口。
  2. 回调url接口;
  3. 回调参数:json字符串;

要求:

  1. 回调时间相对当前时间精确到秒,且只回调一次
  2. 可以在回调前注销某一个回调定时器,让它别回调了。

不知道现在有什么好的办法来实现以上类似定时任务的功能?谢谢。

现在目前后台服务器是LNMP环境,外加Redis

Redis只会简单的存取操作,不会太复杂的。所以下面这个答案也没怎么看明白。不知道还有没有好一点解决方案,谢谢。

参考回答一:

依你目前的架构,这种需求,把回调参数扔 Redis 里,然后在一个 sorted set 里把 key 和回调时间记上,再>通过 pub/sub 通知执行回调的服务。

执行回调的服务,收到通知之后就去 sorted set 里取最早的一个回调数据,然后等时间到了就执行回调。然后继续取下一个回调数据。

取消的逻辑:把回调在 Redis 里的 key 删掉,这样回调执行者取不到数据就不会执行了嘛。

你的回调执行者当然不能依托于 php-fpm 那种东西了。单独起一个进程专门执行,PHP 可以做到的。当然你也可以用其它语言来实现。

参考回答二:

光看你那个例子,任务的功能:可以在创建任务的时候产生一个任务开始时间,然后利用lnmp里的linux crontab功能,定时每秒执行一次你的URL API,逻辑全部放在API里,比如api中先用sql查询一遍是否有超时的任务,超时就停止,并执行你说的其他业务逻辑,这个你应该目前就非常清楚了。当然除了sql还有优化空间,但是目前我建议你根据实际情况选择最简单的方案

阅读 5.3k
5 个回答

laravel框架有一个命令, 可以完全满足你的要求.

php artisan queue:listen

原理就像你说问题下面的说明.

会向redis里面添加一个json数据, 以及你要执行任务的时间.
json数据包括你要执行的任务及参数.

php artisan queue:listen这个命令后在后台每秒查询一次redis队列, 有需要执行的任务就取出来执行.

1.结合linux的crontab可以实现,秒级别比较麻烦一点,但还是可以实现的
2.用php-cli模式起一个常驻进程就可以了

备注:

如果是thinkphp5框架有自定义命令,这样启用:php think your-autotask,结合linux的crontab实现自动调用
这是我项目中的配置,1分钟跑一次的,希望对你有用

*/1 * * * * cd /data/wwwroot/gs-api.localhost.com/;/usr/local/php/bin/php think OrderTimeout >> ./runtime/autotask/$(date +\%Y\%m\%d)-OrderTimeout.log 2>&1

另外,crontab秒级别的实现
crontab每10秒执行一次

redis感觉只是一个存储系统,用它来做这些就算能实现似乎也不太妥当.
我倾向于写一个常驻进程,在进程中异步执行你所说的那些操作,可以参考使用swoole扩展.

新手上路,请多包涵
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题