PHP通过使用使用http请求的模块来防止超时

Jen*_*ell 9 php timeout httprequest

我使用PHP并且需要运行10个任务.他们中的每一个都不应该超时,但所有10个任务可能会在一起.

使用带有新http请求的模块化方法是一个很好的解决方案吗?

像这样的东西:

http://example.com/some/module/fetch
http://example.com/some/module/parse
http://example.com/some/module/save
Run Code Online (Sandbox Code Playgroud)

也许这些网址各自执行一项任务.如果成功,请执行该任务的下一个任务.一种连锁反应.一条路径调用下一条路径(使用curl).

优点和缺点?这是一个好方法吗?如果没有,什么是更好的选择?

Rob*_*bie 2

模块化方法是一个好主意(如果一个“单元”发生故障,作业会根据您的需要停止;此外,调试/测试每个单独的单元也更简单)。

它会起作用,但是您的链接方法存在一些问题:

  • 如果存在瓶颈(即一个“单元”比其他“单元”花费更长的时间),那么最终可能会导致 100 个瓶颈进程全部运行,并且您将失去对服务器资源的控制
  • 缺乏控制;假设服务器需要重新启动:要重新启动作业,您需要从头启动它们。
  • 同样,如果您出于某种原因需要在运行时停止/启动/调试单个单元,则需要在第一个单元处重新启动作业以重复。
  • 通过发出 Web 请求,您正在使用 Apache/NGIX 资源、内存、套接字连接等来运行 PHP 进程。您可以直接运行 PHP 进程,而无需使用开销。
  • 最后,如果在 DMZ 的 Web 服务器上,该服务器实际上可能无法向自身发出请求。

为了获得更多控制,您应该使用排队系统来进行此类操作。

使用 PHP(或任何语言,实际上),您的基本过程是:

  1. 每个“单元”都是一个不断循环的 php 脚本,永远不会结束*

  2. 每个“单元”进程监听一个排队系统;当一个作业到达它可以处理的队列时,它将它从队列中取出

  3. 当每个单元完成作业时,它会确认已处理并推送到下一个队列。

  4. 如果单位决定作业不应继续,请确认已处理的作业,但不要推送到下一个队列。

优点:

  • 如果“单元”停止,则作业将保留在队列中,并且可以在重新启动“单元”时收集。可以更轻松地重新启动设备/服务器或在一台设备崩溃时进行操作。
  • 如果一个“单元”非常重,如果您有空间服务器容量,您可以启动第二个进程,执行完全相同的操作。如果没有服务器能力,你就接受瓶颈;因此,您可以非常透明地了解您正在使用多少资源。
  • 如果您认为另一种语言可以更好地处理请求,您可以混合使用 NodeJS、Python、Ruby 等等,它们都可以与相同的队列通信。

关于“连续循环 PHP”的旁注:这是通过将 max_execution_time 设置为“0”来完成的。确保您不会导致“内存泄漏”并具有 cleanm 。您可以在启动时自动启动该进程(systemd 或任务调度程序,具体取决于操作系统)或手动运行以进行测试。如果您不想让它不断循环,请在 5 分钟后超时并重新启动 cron/任务调度程序。

关于队列的旁注:您可以使用内存缓存数据库“自行推出”简单的应用程序(例如,使用数据库系统可以轻松地每小时处理队列中的 100,000 个项目),但避免冲突/管理状态/重试有点困难属于一门艺术。更好的选择是 RabbitMQ ( https://www.rabbitmq.com/ )。安装起来有点麻烦,但是一旦安装了它,请按照 PHP 教程进行操作,您将永远不会回头!