gpt4 book ai didi

php - 使用 PHP 进行异步处理 - 每个作业一个 worker

转载 作者:可可西里 更新时间:2023-10-31 23:14:29 24 4
gpt4 key购买 nike

考虑一个 PHP 网络应用程序,其目的是接受用户请求以启动通用异步作业,然后创建一个工作进程/线程来运行该作业。这些作业不是特别占用 CPU 或内存,但预计会相当频繁地阻塞 I/O 调用。每秒不应启动超过一两个作业,但由于运行时间较长,可能会同时运行多个作业。

因此,并行运行作业至关重要。此外,每个作业都必须由负责杀死挂起的 worker 、根据用户请求中止 worker 等的管理器守护进程进行监控。

实现此类系统的最佳方式是什么?我可以看到:

  1. 从经理那里分派(dispatch)一名 worker ——这似乎是最低级别的选择,我必须自己实现一个监控系统。 Apache 是 Web 服务器,因此看来此选项需要通过 FastCGI 启动所有 PHP 工作程序。
  2. 使用某种作业/消息队列。 (gearman、beanstalkd、RabbitMQ 等)- 最初,这似乎是显而易见的选择。经过一些研究,我对所有选项都感到有些困惑。例如,Gearman 看起来像是为大型分布式系统设计的,那里有固定的工作人员池……所以我不知道它是否适合我的需要(每个工作一个工作人员)。

最佳答案

嗯,如果你在 Linux 上,你可以使用 pcntl_fork叉 child 。 “主人”然后看着 children 。每个 child 完成自己的任务,然后正常存在。

就我个人而言,在我的实现中我从来不需要消息队列。我只是在带锁的“主人”中使用了一个数组。当 child 找到工作时,它会写一个带有工作 ID 号的锁文件。然后主人会等到那个 child 离开。如果 child 退出后锁定文件仍然存在,那么我知道任务未完成,并重新启动具有相同作业的 child (删除锁定文件后)。根据您的情况,您可以在一个简单的数据库表中实现队列。在表中插入作业,并每 30 或 60 秒检查一次 master 中的表是否有新作业。然后只有在 child 完成后才从表中删除它们(并且 child 删除了锁定文件)。如果您同时运行多个“master”,这会出现问题,但您可以实现一个全局“master pid 文件”来检测和防止多个实例...

而且我不建议使用 FastCGI 进行 fork 。它可能会导致一些非常模糊的问题,因为环境应该持续存在。相反,如果您必须拥有它的 Web 界面,请使用 CGI,但最好使用 CLI 应用程序(守护进程)。要与其他进程的 master 交互,您可以使用套接字进行 TCP 通信,或者创建一个 FIFO file用于通信。

至于检测挂起的工作程序,您可以实现“心跳”系统,子进程每隔几秒就会向主进程发出一个 SIG_USR1。那么如果那段时间你两三次都没有听到 child 的消息,它可能会被挂掉。但问题是因为 PHP 不是多线程的,你无法判断一个 child 是否挂起或者它是否只是在等待阻塞资源(比如数据库调用)......至于实现“心跳” , 你可以使用 tick function使心跳自动化(但请记住,阻塞调用仍然不会执行)...

关于php - 使用 PHP 进行异步处理 - 每个作业一个 worker ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3513112/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com