84669 person learning
152542 person learning
20005 person learning
5487 person learning
7821 person learning
359900 person learning
3350 person learning
180660 person learning
48569 person learning
18603 person learning
40936 person learning
1549 person learning
1183 person learning
32909 person learning
PHP队列执行任务的时候,如何防止进程之间抢夺资源?比如视频转码队列,每分钟会起一个进程去处理视频转码任务,每次从数据库获取10条进程1已经获取了ID为10的视频去处理,一分钟后,如何防止进程2 拿到其他进程已经处理过的?处理完成后,有异步通知,但是异步通知会有延迟,所以视频状态有可能修改不及时
When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A - When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A
Come and watch and learn.
实际上有一个非常简单的办法,你可以利用数据库操作的原子性来实现,不需要那么复杂的锁机制,甚至队列。就按你的方法来,假设任务数据表 task 里有两个字段 id, status,我们定义status三个状态
0: 待处理 1: 正在处理 2: 处理完成
假设你有一堆 PHP 进程都用如下 SQL 语句去取出数据库里的待处理任务
SELECT * FROM task WHERE status = 0
取出来以后,我们为了防止其他用户不再重复取出要把它的状态标记为 1
UPDATE task SET status = 1 WHERE id = xxx
但是等等,这样就会产生如你所说的资源抢夺,但如果加上一个简单的技巧就可以避免,你把语句变成这样
UPDATE task SET status = 1 WHERE id = xxx AND status = 0
熟悉一点数据库的人可能会说这样还是避免不了抢夺,只是避免了重复写入。我要说的是,能避免重复写入就够了,我们的进程在执行完这条操作后,去获取 affected_rows ,即更新的条数,根据数据库的原子性,只有第一个抢占的进程才会返回 1,它可以进行后面的操作。而剩下返回 0 的进程,直接进入下一个等待流程即可。
When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A - When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A
Come and watch and learn.
实际上有一个非常简单的办法,你可以利用数据库操作的原子性来实现,不需要那么复杂的锁机制,甚至队列。就按你的方法来,假设任务数据表 task 里有两个字段 id, status,我们定义status三个状态
假设你有一堆 PHP 进程都用如下 SQL 语句去取出数据库里的待处理任务
取出来以后,我们为了防止其他用户不再重复取出要把它的状态标记为 1
但是等等,这样就会产生如你所说的资源抢夺,但如果加上一个简单的技巧就可以避免,你把语句变成这样
熟悉一点数据库的人可能会说这样还是避免不了抢夺,只是避免了重复写入。
我要说的是,能避免重复写入就够了,我们的进程在执行完这条操作后,去获取 affected_rows ,即更新的条数,根据数据库的原子性,只有第一个抢占的进程才会返回 1,它可以进行后面的操作。而剩下返回 0 的进程,直接进入下一个等待流程即可。