6

我熟悉 php-resque 和其他用于处理后台作业的作业处理系统,但我认为它不能满足我的需要。

在这种情况下,我有一个传入的 Web 服务请求,该请求需要对外部系统执行多个 (2-4) 独立调用,并返回对客户端的合并响应。每个标注可能需要 300-500 毫秒,所以我希望每个标注并行执行,以便整个过程总共花费不超过 500 毫秒+/-。

我对 php-resque 和其他系统的问题是,即使等待 1 秒才能开始发出这些标注,等待时间太长,我正在考虑另一种方法。

我在想什么:

  1. 每个单独的标注都被描述并存储在具有给定唯一请求 ID 的数据库中
  2. 我们以异步 php 进程(又名“工作进程”)的形式立即开始工作
  3. 每个工人将其结果写回作业记录并指示它已完成
  4. 同时,我们每隔 50-100ms 轮询一次作业表,检查每个作业的状态
  5. 当每个都完成时,我们根据需要解析结果并返回响应。

当然,我们会为每个请求和整个过程实现超时......

想法?我错了吗?php-resque 可以立即并行启动多个工作吗?

4

2 回答 2

2

您的计划应该可行,但我认为您可以通过使用PHP 进程控制函数来避免所有数据库通信甚至轮询。

  1. 分叉你的主进程与你需要它并行运行的任务一样多。参见:pcntl_fork
  2. 在那些分叉的进程中执行你的任务并让它们正常退出。
  3. 启动任务的进程应该通过在它们退出时侦听它们的 SIGCHLD 信号来等待它们全部完成。或者,如果他们在您选择的超时之前没有,则向他们发送 SIGTERM 信号以进行清理。请参阅:pcntl_sigtimedwaitposix_kill

但是,您必须在 PHP CLI 脚本中使用这些函数,因为...

http://www.php.net/manual/en/intro.pcntl.php

不应在 Web 服务器环境中启用流程控制,如果在 Web 服务器环境中使用任何流程控制功能,可能会出现意外结果。

但是您的 Web 服务器可以轻松地使用exec()您的 CLI 脚本,该脚本将完成所有艰苦的工作,返回这些任务的状态等。

于 2012-10-08T05:32:39.980 回答
1

如果您的外部调用只是 HTTP 请求,您可以简单地使用 curl 并执行多个请求。他们似乎完全按照您的需要做。

如果是不同的东西,我强烈推荐Gearman

如果您想亲自动手并编写自己的守护程序,我建议您跳过 IPC 函数,并使用更高级的东西,例如ZeroMQ ,如果 PHP 进程死了,也许可以使用Supervisord重新启动它们。编写长时间运行的 PHP 进程相对困难,因此您必须在构建它时考虑到外部脚本随机终止并准备好优雅地处理它。

于 2012-10-08T09:30:21.337 回答