【问题标题】:Is it ok to use PHP-FPM to manage queue consumers?使用 PHP-FPM 管理队列消费者可以吗?
【发布时间】:2026-01-21 22:20:06
【问题描述】:

有一个 beanstalkd 队列,每 10 分钟就会充满很多任务,并且每个任务都尽快处理是重中之重。任务可能需要几毫秒才能完成,因为有对第三方服务的调用,这往往会时不时地超时。

因此,由于 PHP 没有多线程,一种选择是创建大量空闲的工作人员,它们会尝试保留任务,但可能会占用过多的 RAM,这些机器上可能不可用.

使用 PHP-FPM 调整工人数量并节省一些 RAM 是不是一个好主意?准备好生产了吗?有没有更好的解决方案?

谢谢

【问题讨论】:

    标签: beanstalkd php


    【解决方案1】:

    我正在运行一个每天处理数百万条消息的队列系统。主要是通过 Amazon SQS,但我现在也在运行一个新的 Beanstalkd 系统,里面有超过 600,000 条消息。

    正如a blogpost on the subject 中所述,我在循环中运行的 shell 脚本处理消息(PHP 脚本中的循环在返回之前运行多个作业也有些用处,至少对于较小的作业而言)。

    这些 shell 脚本以 Supervisord 开头。还有另一个blog post on the use of that。我目前在九台机器上运行超过 800 个工作脚本(用于几种不同类型的作业),所有这些脚本都从各种队列中提取并将数据放回其他队列,写入数据库或文件。增加每台机器的工人数量是增加“numprocs”(或已经足够大),然后根据需要开始更多的问题。您也可以说 5 个自动启动,然后再按需要准备启动另一个 50 个块。

    我发现每个工作人员只占用大约 20mb 的非共享内存(其余的在进程之间是通用的)。当然,这确实取决于工人所做的任务。调整图像大小可能需要付出很多努力。部分原因是我设置了能够频繁重启 PHP 脚本。

    【讨论】:

      【解决方案2】:

      每当我必须同时(或异步)运行某些东西时,我都会将作业分派给gearman 工人。我通常在每台运行的物理机器上每个 CPU 内核至少有一个进程。

      PHP-FPM 是一个 cgi 守护进程。所以你基本上会让你的 beanstalkd 处理器向你自己的系统运行一堆 HTTP 请求。这些可能必须通过您的 http 堆栈。不确定这是否是个好主意。

      您还可以查看pcntl_fork 将您当前的进程分叉为多个同时运行的进程。

      【讨论】:

      • 谢谢你的建议,我去看看gearman。有一个用于 FPM 的 PHP 客户端,它允许绕过 HTTP 堆栈,所以这有点好,但仍然不完美。分叉基本上会消耗与运行不同进程相同的内存,对吧?
      • 是的,分叉会消耗自己的内存。但它们仅在需要时创建并在之后删除。使用 PHP-FPM,您始终可以缓存一堆进程(这很有意义……)。嗯,我不知道任何 FPM 客户端,在哪里可以找到?