问下laravel,对于耗时的操作,除了队列执行还有什么其他方式吗?

情况是我这边有个违禁词检查功能,这功能耗时挺长的,所以我希望能放到后台执行,这样用户发帖之后,能返回审核中的结果,而不是要等违禁词检查完之后才返回结果
我查了下队列可以做到,但是队列需要 php artisan queue:listen 一直执行,这东西会断掉,还要守护进程什么的,太麻烦想问下有其他方式吗?

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

与laravel甚至与语言无关。

单纯耗时长的,那必然只能异步操作。

你自己说了这功能耗时挺长的,所以我希望能放到后台执行,这句话意思本身就是要用队列

laravel的队列只需要 依赖supervisor,由supervisor负责监控进程,进程挂掉自动再启起来。

supervisor本身的保活由systemd来控制,systemd为内核进程不可能挂,他挂了就是系统整个已经崩了。

---另---

生产环境用queue:work不要用listen,弊端就是修改代码后需要通过supervisor重启或者执行php artisan queue:restart来重启。

queue:listen另外一个问题是,会导致频繁的进程启动、挂起、结束。会导致CPU飙高。

queue:restart命令的原理是通过缓存写入一个时间戳,因此,如果多台服务器同时跑队列,必须一定要用redis等类似的服务来集中存放缓存数据,否则queue:restart在哪台服务器上执行,只有这台服务器的队列才能重启。

10个月前 评论
讨论数量: 19

与laravel甚至与语言无关。

单纯耗时长的,那必然只能异步操作。

你自己说了这功能耗时挺长的,所以我希望能放到后台执行,这句话意思本身就是要用队列

laravel的队列只需要 依赖supervisor,由supervisor负责监控进程,进程挂掉自动再启起来。

supervisor本身的保活由systemd来控制,systemd为内核进程不可能挂,他挂了就是系统整个已经崩了。

---另---

生产环境用queue:work不要用listen,弊端就是修改代码后需要通过supervisor重启或者执行php artisan queue:restart来重启。

queue:listen另外一个问题是,会导致频繁的进程启动、挂起、结束。会导致CPU飙高。

queue:restart命令的原理是通过缓存写入一个时间戳,因此,如果多台服务器同时跑队列,必须一定要用redis等类似的服务来集中存放缓存数据,否则queue:restart在哪台服务器上执行,只有这台服务器的队列才能重启。

10个月前 评论
  1. 通过队列实现。尽管刚接触队列的话,感觉会麻烦一些:又是通过 supervisor 保证队列一直在线,又是改了代码需要重启,又是防止队列积压,but... 一旦踩过各种坑,你就会爱上它,而且欲罢不能的那种。

  2. 通过定时任务,定时扫描需要处理的帖子。这种做法看似简单暴力,实际用的久了,也会出现各种各样的问题:比如扫描周期长了,处理不够及时,周期短了,又可能给数据库带来压力,甚至造成进程「堆积」。

个人建议,还是使用队列处理。前期痛苦点,后期不管对于项目维护,还是对于个人技术成长,收益都是很明显的。

10个月前 评论

定时任务也可以吧

10个月前 评论
aba66 10个月前

fastcgi_finish_request

10个月前 评论

守护进程不是很简单的么supervisor,当然是用队列最好了

10个月前 评论
  1. 通过队列实现。尽管刚接触队列的话,感觉会麻烦一些:又是通过 supervisor 保证队列一直在线,又是改了代码需要重启,又是防止队列积压,but... 一旦踩过各种坑,你就会爱上它,而且欲罢不能的那种。

  2. 通过定时任务,定时扫描需要处理的帖子。这种做法看似简单暴力,实际用的久了,也会出现各种各样的问题:比如扫描周期长了,处理不够及时,周期短了,又可能给数据库带来压力,甚至造成进程「堆积」。

个人建议,还是使用队列处理。前期痛苦点,后期不管对于项目维护,还是对于个人技术成长,收益都是很明显的。

10个月前 评论

为什么会耗时很高? 要求时效性高就队列,不高就定时任务。

10个月前 评论

与laravel甚至与语言无关。

单纯耗时长的,那必然只能异步操作。

你自己说了这功能耗时挺长的,所以我希望能放到后台执行,这句话意思本身就是要用队列

laravel的队列只需要 依赖supervisor,由supervisor负责监控进程,进程挂掉自动再启起来。

supervisor本身的保活由systemd来控制,systemd为内核进程不可能挂,他挂了就是系统整个已经崩了。

---另---

生产环境用queue:work不要用listen,弊端就是修改代码后需要通过supervisor重启或者执行php artisan queue:restart来重启。

queue:listen另外一个问题是,会导致频繁的进程启动、挂起、结束。会导致CPU飙高。

queue:restart命令的原理是通过缓存写入一个时间戳,因此,如果多台服务器同时跑队列,必须一定要用redis等类似的服务来集中存放缓存数据,否则queue:restart在哪台服务器上执行,只有这台服务器的队列才能重启。

10个月前 评论
sanders

防队列消费进程中断,使用 supervisor 是解决方案之一。如果你使用 docker 容器,可以通过 docker-compose 配置其自带的容器拉起功能。如果是用 kubernetes 集群也可以使用副本控制器对中断的容器进行拉起。

再说队列消费进程中断的问题,我们其实不应该太依赖其执行的结果。我们假设队列任务处理是不稳定的,即便消费者进程会被重新拉起,但某个消费过的任务可能会执行失败,比如被异常中断或执行超时。这时我们还是需要使用定时脚本对其进行不就处理。我们的经验来看,这种任务会封装一个操作类,一个队列任务和一个补救用的定时脚本。队列任务会及时分发并调用操作类进行处理,定时脚本则批量扫描哪些未及时处理或处理失败的任务调用操作类进行处理(或重新分发到队列任务)。从这个角度看,其实队列任务起到的是时效性优化的效果,而定时脚本负责稳定性。

所以你可以看出,并不一定非要用队列任务进行处理,定时脚本其实是更稳定的方案,只不过在多数情况下时再效性方面不及队列任务。

再多谈一些队列任务的方案,一搬队列存储引擎都是有容量限制的,比如 laravel 用的 redis 被写满不仅会影响队列任务的分发,还会影响其他正常业务,比如缓存、广播或限流器等等。除了添加报警之外,你还需要考虑消费逻辑的处理速度和任务超时的时间。这里我推荐使用官方出品的 horizon 对消费进程进行管理,根据队列长度动态扩缩消费进程,只不过需要注意的是 horizon 本身就需要一定的系统开销和 redis 存储开销。我们的解决方案是用 kubernetes 的 hpa 控制器对运行 horizon 的 pod 再进一步进行动态扩缩。

10个月前 评论
xiaochong0302 10个月前

file

用PM2 进行守护,简单易用,“ 队列可以做到,但是队列需要 php artisan queue:listen 一直执行,这东西会断掉,还要守护进程什么的,太麻烦想问下有其他方式吗?” 这句话有点问题,做技术有问题要解决,不能逃避,如果一直逃避你的技术基本一直停留在这个层次上

10个月前 评论

swoole来处理会不会快点?队列确实一个到一个,确实感觉好慢

10个月前 评论
cevin 10个月前
cevin 10个月前
bishi123 (作者) 10个月前

用webman来处理也可以,队列本来就 样的

10个月前 评论
susucool

耗时操作直接用异步后台另外开一个进程执行就行了,要分三步来执行。

第一步,把任务分派出去,可以用任何工具REDIS,RABBIT MQ都可以,甚至直接记录在数据库都行。

第二步,你要有一个常驻进程来不断检查任务,有任务直接马上获取,并开始执行,这个进程专门来执行这种耗时任务。

第三步,在前台你可以用时间间隔比较大的轮询,查询当前发送的任务执行完成没有,如果已经完成则直接标记为完成,显示在前台上。

10个月前 评论
bishi123 10个月前
lufeijun1234

优化违禁词检查功能?

9个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!