限制队列任务的并发数量
业务场景
先说下业务场景:商业公司通常会允许客户按需生成报表,但每个用户同时只允许生成 5 份报表。
对于生成报表这种耗时的磁盘 IO 操作,我们可以将其推送到消息队列异步处理,避免用户长时间等待,为此,我们编写这个任务类的 handle
方法如下:
在这里,我们先生成报表,再更新对应的数据库状态。为了加快队列任务的消费速度,可以开启多个队列处理器进程,不过,由于一个用户同时只能生成 5 份报表,就需要限制队列处理器进程并发执行的数量。
并发限制
Laravel 提供了很多队列任务频率限制器,这里我们使用基于漏斗算法的并发频率限制器。要限制针对每个用户最多同时执行 5 个报表生成队列任务,可以这么做:
如果没有达到并发上限,就可以执行 then
回调中的报表生成代码,否则,就会延迟 10s 后再执行该任务。通过这种方式,就可以实现队列处理器进程并发执行的队列任务数量。
等待几秒
默认情况下,并发频率限制器在放弃并释放任务前会等待 3 秒,你可以通过 block
方法来控制这个等待时间:
设置超时时间
默认情况下,并发频率限制器会强制每 60s 后执行一个任务(用于控制并发槽位的锁失效,可以将其看作是队列任务默认超时时间),如果单个报表生成任务执行时间超过 60s,则会释放这个槽位然后执行下一个,这就会出现 6 份报告同时生成的情况,这是我们不想看到的。
要解决这个问题,我们可以通过 releaseAfter
方法将超时时间设置为 5 分钟:
管理尝试次数
在上述代码实现中,由于队列任务可能会多次释放回队列,你可以通过设置 tries
属性限制同一个任务的最大尝试次数:
当然,如果 ReportGenerator
抛出异常,我们也不想要继续尝试,因此可以设置 maxExceptions
值为 2:
现在就变成了同一个队列任务正常情况下最多尝试 10 次,如果出现异常,最多只尝试 2 次就终止。
No Comments