商业PHP脚本,长时间运行的进程.守护进程与cronjobs


Commercial PHP script, long running processes. daemons vs. cronjobs?

我正在组装我的第一个商业PHP应用程序,它并没有什么大不了的,因为我仍然在热切地学习PHP:)

目前,我仍处于规划应用程序的概念阶段,但我一直遇到一个问题,该应用程序应该由我的客户在他们自己的服务器上自行托管,并将包括一些运行时间很长的脚本,这取决于每个客户在其应用程序中输入的数据量。

现在我想我有两个选项,要么使用cronjobs,比如让一个或多个cronjobs一次运行,每个客户都可以自己设置,要么把整个数据处理作为后台运行的守护进程。。。

我的问题是,由于它是一个自托管的应用程序(每个服务器都不同)。。。是否建议您尝试在客户服务器上编写启动后台进程的php,或者这更像是您只能在自己的服务器上可靠地完成的事情。。。?

还是应该将cronjobs用于这些长时间运行的进程?

(取决于我的客户将在应用程序中输入的数据量,一个过程可能运行3个多小时)

这是一个可以用PHP可靠地解决的问题吗。。。?如果这是一个奇怪的问题,请原谅,我真的不熟悉PHP守护进程和/或PHP创建的长时间运行的cronjobs。

因此,概括一下所有内容:商业自托管应用程序,包括长时间运行的进程、cronjobs还是守护进程?对于付费应用程序,其中一个或两者是否也是一个可靠的解决方案,您可以问心无愧地向客户提供,因为您知道它在各种不同的服务器上都能可靠工作。。。?

编辑*PS:对不起,我忘了提到这个应用程序只针对Linux服务器,所以所有的东西都像Debian、Ubuntu等。

简短的回答是,不,如果这将是一个客户端托管的解决方案,就不要使用后台进程。如果你倾向于ASP概念(应用程序服务提供商…而不是Active Server Pages;),那么你可以用后台进程和连接到sql服务器的外部应用程序来做一些奇怪的事情,并为你处理这些事情。

我的建议是创建一个强大的任务管理骨干,并将其与坚实的任务处理基础设施联系起来。我建议你阅读我不久前写的一篇关于后台流程和我为修复长时间运行的流程而采用的策略的旧帖子:

启动&从后端管理网页停止PHP脚本

阅读愉快。。。

更新

我意识到我以前的帖子很难理解,所以下面是:

您需要2个模型:作业和作业队列,2个控制器:作业处理器,XYZProcessor

JobProcessor在页面触发时由用户调用,或者根据需要使用cronjob。JobProcessor::process()是启动或继续整个处理的键。它加载JobQueues并询问作业队列是否有工作要做。如果有工作要干,它会要求作业队列启动/继续它的作业。

JobQueue Model:用于将多个JOBS一个接一个地排队,并通过保留某种ID和STATE来控制当前的作业。

作业模型:准确地表示需要执行的操作,例如,它包含将处理数据的控制器的名称、要调用以处理数据的函数以及描述必须执行的操作的序列化配置属性。

XYZController:是包含处理方法的控制器。当调用处理方法时,控制器必须将所需的一切加载到内存中,然后尽可能快地处理每个单独的工作单元。

示例:

  1. index.php调用
  2. Index.php创建作业处理器控制器
  3. Index.php调用作业处理器的进程()
  4. JobProcessor::Process()加载所有队列并对其进行处理
  5. 对于每个JobQueue::Process(),作业队列加载可能的作业,并检测其中一个作业当前是否正在运行。如果没有正在运行,它将通过调用Job::Process()来启动下一个
  6. Job::Process()创建XYZController,该控制器将处理手头的任务。例如,我的旧系统有一个InvoicingController和一个MassmailingController,它们协同工作
  7. Job::Process()调用XYZController::Prepare(),以便加载要处理的信息。(例如,加载一批要处理的电子邮件,加载一批次要创建的发票)
  8. Job::Process()调用XYZController::RunWorkUnit(),以便它处理单个工作单元(例如,创建一个发票,发送一封电子邮件)
  9. Job::Process()询问JobProcessingController::DoIStillHaveTimeToProcess(),如果是,则继续处理下一个元素
  10. 作业::Process()超时并调用XYZController::Cleanup()以释放所有资源
  11. JobQueue::Process()结束并返回到JobController
  12. JobController::Process()即将结束?打开一个套接字,给自己回电话,这样我就可以开始另一轮处理,直到我没有任何事情可做为止
  13. 处理从位置#1开始的用户的请求

最终,你可以每次打开一个套接字,让处理器做点什么,或者你可以排队让CronJob调用你的处理器。这样,您的用户就不会每次都在等待3/4个工作单元的完成。

值得注意的是,除了运行守护进程或cron作业外,您还可以从web请求启动长时间运行的进程(但请注意,它必须在web服务器进程组之外运行),当然还有异步消息处理(这本质上是批处理方法的变体)。

这四种方法在行为方式、并发性和定时管理方式方面都有很大不同。使它们完全不同的因素与你在问题中忽略的因素相同,所以不可能真正回答。

不幸的是,所有这些都依赖于MSWindows和POSIX系统之间非常不同的功能,所以尽管PHP将在两者上运行,但如果你想在这两个平台上销售你的应用程序,它需要两个版本。

也许你应该和你的潜在客户群谈谈,问问他们想要什么?