dyllen
V2EX  ›  PHP

PHP yii2 框架,定时任务加了 redis Mutex 还是重复执行了,怎么整?

By dyllen at 2020 年 6 月 17 日 · 3671 次点击

php

    public $mutexName = 'xxxxx';  //固定的值

    protected function checkThread()
    {
        \Yii::$app->setComponents([
            'mutex' => [
                'class' => 'yii\redis\Mutex',
                'expire' => 300,
            ],
        ]);

        return \Yii::$app->mutex->acquire($this->mutexName, 10);
    }

有个定时任务,每次执行前我都会调用一下checkThread去获取锁,获取不到就退出。

现在有多台机器设置了同样时刻的这个计划任务,在同一时间执行了这定时任务,我发现还是重复执行了后面的业务逻辑。

这是这个获取锁没效?

10 条回复  •  2020-06-19 09:32:17 +08:00
ljwaheng
   1
ljwaheng  
   2020 年 6 月 17 日
这种是不是可以用 Redis 的 setnx 保证只有一个客户端获取锁? ( ex 设置过期时间)不过解锁的时候最好使用 Lua 解锁.
dyllen
   2
dyllen  
OP
   2020 年 6 月 17 日
@ljwaheng 你说的这些,`yii\redis\Mutex`里面都已经实现好了的。
ljwaheng
   3
ljwaheng  
   2020 年 6 月 17 日
@dyllen #2 哦哦 没用过 yii2 。可是 Redis 不是单进程单线程吗?所以应该只有一个客户端获取到锁吧。
surfire91
   4
surfire91  
   2020 年 6 月 17 日
猜测一个原因:
锁是不是有实效?如果有实效的话,虽然你多台机器设置了同样时刻,但是不同机器时间可能存在误差,导致顺序执行了。比如 a 机器执行完了(锁销毁了),b 机器才开始执行任务(这个时候是能获取到锁到)。
monsterxx03
   5
monsterxx03  
   2020 年 6 月 17 日
连到 redis 上, 用 monitor 指令看下这封装代码具体干了什么
dyllen
   6
dyllen  
OP
   2020 年 6 月 17 日
@surfire91 要是是你说的这情况,那就没问题。
dyllen
   7
dyllen  
OP
   2020 年 6 月 17 日
@monsterxx03 源码我都看过了,就两个操作,加锁 set nx px,解锁用的 lua,没了。
surfire91
   8
surfire91  
   2020 年 6 月 18 日
@dyllen 别“要是”啊,验证下呗
dyllen
   9
dyllen  
OP
   2020 年 6 月 18 日
@surfire91 我是说你说的这个情况,不会有问题。顺序执行了,或者哪个先,那个后执行都不会有问题。
这种锁本来就是执行完了就释放的。
couashi
   10
couashi  
   2020 年 6 月 19 日
建议后期应该部署定时任务管理后台
© 2026 V2EX · 41ms · 3.9.8.5