解释
通常需要 10-20 秒响应的 API 调用(对另一个服务)存储在数据库中,
存储后,系统会立即尝试使用API将结果显示给用户,但可能会失败(并显示失败,但我们会自动重试),因此还有一个Cron Job
设置为每 30 秒运行一次并再次尝试(失败的)查询。
如果API返回成功(无论是即时使用还是使用Cron Job),数据库中的标志将更改为成功,并且不会再次运行。
Issue
我的问题是Instant Call
API 正在处理中,Cron Job
也可以尝试另一个调用,因为它尚未标记为成功,
此外,在极少数情况下,当上一个 Cron 作业正在进行时,下一个 Cron 作业可能会再次运行代码。
我已经尝试过防止该问题发生的方法
我尝试存储In Process
数据库表中的 API 调用Status=1
当 API 调用成功时删除它们,或者如果失败则将状态设置为 0,
if ($status === 0)
{
// Set Status to 1 in Database First (or die() if database update failed)
// Then Call The API
// If Failed Set Status to 0 so Cron Job can try again
// If Successful Change Flag to success and remove from queue
}
但如果Instant Call
和Cron Job Call
完全在同一时间发生?他们都检查状态是否为 0(确实如此),然后都将状态设置为 1 并执行 API 调用...
问题
-
我尝试过的处理方法是正确的吗?
-
如果有很多呼叫(有时+500/秒),我是否应该担心它们在确切的时间发生(我在上面的黄色引用中解释的问题)
赏金前更新
难道 PHP 端就没有一种简单的方法来处理这种情况吗?如果不是,专家认为哪种方式更好?下面是一些方法,但没有一个足够详细,也没有一个有任何反对/赞成票。
附:数据库有很多更新/插入,我认为锁定不是一个有效的想法,并且我不确定其余的想法。
这就是为什么信号 http://php.net/manual/en/intro.sem.php是为.
在php中,可以通过以下方式使用:
在 PHP 中使用信号量实际上非常简单。信号量函数只有 4 个:
sem_acquire() – Attempt to acquire control of a semaphore.
sem_get() – Creates (or gets if already present) a semaphore.
sem_release() – Releases the a semaphore if it is already acquired.
sem_remove() – Removes (deletes) a semaphore.
那么它们是如何协同工作的呢?
- 首先,你打电话
sem_get()
获取信号量的标识符。
- 之后,您的进程之一将调用
sem_acquire()
尝试获取信号量。如果当前无法使用,sem_acquire()
将阻塞,直到信号量被另一个进程释放。
- 一旦获得信号量,您就可以访问您正在用它控制的资源。
- 使用完资源后,请致电
sem_release()
以便另一个进程可以获取信号量。
- 当一切都说了又做了,并且您已经确保您的进程不再需要信号量时,您可以调用
sem_remove()
完全删除信号量。
您可以在以下位置找到更多信息和示例:本文 http://www.re-cycledair.com/php-dark-arts-semaphores.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)