【问题标题】:PHP Web Service QueuePHP Web 服务队列
【发布时间】:2015-09-30 15:29:40
【问题描述】:

我正在连接到一个网络服务,该服务只允许从同一来源同时连接到它的 MAX(可能是 1、5、10,具体取决于您的许可证)。我需要一个可以实时(非异步)对 Web 服务的请求进行排队的解决方案,确保一次只运行 MAX 请求。

我的当前设置正常工作:

$jobId = $this->queue->addJob($operation);               
while ( !$this->queue->canRunJob($jobId) ) {
  //error_log("Queue full, waiting");                     
   usleep(500);                                    
}
$this->queue->runJob($jobId);
...
$this->queue->completeJob($jobId);

这使用了一个自定义队列类,它使用一个 mysql 表来跟踪作业,并计算正在运行和挂起的作业的数量。

$this->queue->addJob 将新作业添加到数据库中,状态为“待定”

$this->queue->canRunJob($jobId) 检查有多少正在运行的作业。如果运行的作业少于 MAX 个,它将按 FIFO 顺序从列表中获取下一个待处理的作业。

PHP 脚本正在循环和休眠,直到作业可以运行。

一旦canRunJob 调用$this->queue->runJob($jobId),它将队列中的作业更新为“正在运行”并将请求发送到网络服务。

当 web 服务返回响应时,它调用 $this->queue->completeJob($jobId) 将队列中的作业更新为“已完成”。

这在 95% 的情况下都有效,但如果 Web 服务提供商陷入困境或完全瘫痪,它会慢慢导致我的服务器上的进程堆积,从而锁定 Web 和数据库连接。

寻找另一种在不循环/休眠的情况下处理这种情况的方法的建议

【问题讨论】:

  • 而不是脚本循环和检查队列槽,为什么不让您的作业在完成时简单地调用“运行下一个作业”?这样就根本不需要循环脚本。也许有一个定期启动的安全脚本,以处理由于“运行下一个作业”位从未被调用而导致作业提前停止并且队列清空的情况。
  • 我喜欢这个概念,但是这个工作怎么知道“等待”被调用呢?例如: 工作 1 - 创建一个新客户(进入队列并开始,因为它是唯一的工作) 工作 2 - 创建一个新客户,需要等待工作 1 完成。作业 1 可以完成并调用作业 2,但作业 2 需要知道其状态
  • 这个工作不需要知道任何事情。它只是告诉您的调度代码作业结束,调度程序负责确定接下来要运行的内容。例如你的实际工作类似于<?php do_stuff(); tell_scheduler_to_run_next_job(); ?>

标签: php mysql web-services queue


【解决方案1】:

看一下 Symfony 2 的 Process 组件。您将能够触发可以完成工作的子进程,例如API 连接。父进程可以确保只有 n 个子进程被触发。将所有内容打包在一个循环中,并在其中查询每个作业状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-06
    • 2013-06-05
    • 1970-01-01
    • 2013-01-18
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    相关资源
    最近更新 更多