mstrychalski/supervisor

:vertical_traffic_light: PHP 进程管理器。

1.1.1 2018-07-03 09:34 UTC

This package is not auto-updated.

Last update: 2024-09-29 23:24:02 UTC


README

Supervisor

Build Status Latest Version PHP ~5.5 MIT Licensed

该库实现了 CLI 进程管理器和聚合进程管理器,旨在限制失败脚本造成的损害。

您可以选择任何您喜欢的安装方式,但我们推荐 [Composer][packagist]。

$ composer require graze/supervisor

文档

<?php
use Graze\Supervisor\ProcessSupervisor;
use Symfony\Component\Process\Process;

$while = new Process('/usr/bin/python while_true.py');

$sup = new ProcessSupervisor($while);
$sup->start();
$sup->supervise(0.001); // Check the "while" process every 0.001s (blocking)

假设子进程运行顺利,supervise 方法将停止监视该进程,您可以继续您的业务。但是,那些失败的进程怎么办呢?

Uncaught exception 'Graze\Supervisor\Exception\TerminatedProcessException' with message
The process was unexpectedly terminated
[process] /usr/bin/python while_true.py
[code]    143
[text]    Termination (request to terminate)
[stderr]  Terminated
[stdout]

现在我们已经从一个脚本失败变成了两个脚本失败,但这有什么帮助呢?好吧,它没有,但这就是处理程序的作用。

处理程序

处理程序可以帮助您在子进程失败(以及它们成功终止时)控制要执行的操作。您可以使用处理程序做任何您想做的事情

  • 重试进程
  • 通知您的开发人员或基础设施团队
  • 将作业重新排队到某些复杂的排队服务中
  • 通知您的错误日志服务
  • 启动不同的脚本
  • 停止其他相关脚本
  • 简单地抛出一个异常
<?php
use Graze\Supervisor\Handler\RetryHandler;
use Graze\Supervisor\ProcessSupervisor;
use Symfony\Component\Process\Process;

$while = new Process('/usr/bin/python while_true.py');
$retry = new RetryHandler(3);

$sup = new ProcessSupervisor($while, $retry);
$sup->start();
$sup->supervise();

现在,如果您的进程死亡,重试处理程序将重新启动它,最多3次。但我们可以做得更好;假设您想要重试3次,然后通知开发人员和记录错误,所有这些都在抛出异常之前。只需装饰!

<?php
use Graze\Supervisor\Handler\ExceptionHandler;
use Graze\Supervisor\Handler\RetryHandler;
use Graze\Supervisor\Handler\UnexpectedTerminationHandler;
use Graze\Supervisor\ProcessSupervisor;
use Symfony\Component\Process\Process;

$while = new Process('/usr/bin/python while_true.py');
$handler = new RetryHandler(3,
    new MyPagerDutyHandler($pagerduty,
        new MyBugSnagErrorHandler($bugsnag,
            new ExceptionHandler(
                new UnexpectedTerminationHandler()
            )
        )
    )
);

$sup = new ProcessSupervisor($while, $handler);
$sup->start();
$sup->supervise();

该库目前仅捆绑了一些处理程序,但通过实现简单的接口,您可以快速使用自己的。始终欢迎额外的核心处理程序!

监督监督者

所以有一个监督员来监视您的进程是很好的,但如果您想监督多个逻辑上相关联的进程(例如批量处理),怎么办?您可以通过监督您的单个进程管理器来实现这一点。

<?php
use Graze\Supervisor\ProcessSupervisor;
use Graze\Supervisor\SupervisorSupervisor;
use Symfony\Component\Process\Process;

$batchA = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=a'));
$batchB = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=b'));
$batchC = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=c'));

$sup = new SupervisorSupervisor([$batchA, $batchB, $batchC]);
$sup->start();
$sup->supervise();

就像进程管理器一样,监督管理器使用处理程序处理成功和失败的终止。

<?php
use Graze\Supervisor\Handler\ExceptionHandler;
use Graze\Supervisor\Handler\RetryHandler;
use Graze\Supervisor\Handler\UnexpectedTerminationHandler;
use Graze\Supervisor\ProcessSupervisor;
use Graze\Supervisor\SupervisorSupervisor;
use Symfony\Component\Process\Process;

$batchA = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=a'));
$batchB = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=b'));
$batchC = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=c'));

// Retry all supervised processes if one fails (max 3 times)
$handler = new RetryHandler(3,
    new ExceptionHandler(
        new UnexpectedTerminationHandler()
    )
);

$sup = new SupervisorSupervisor([$batchA, $batchB, $batchC], $handler);
$sup->start();
$sup->supervise();

谁监督监督管理器?

根据逻辑分组进程的复杂性,您可能需要多个层级的故障管理。这完全是可能的,通过将监督管理器传递给父监督管理器。实际上,您甚至可以混合您所监督的监督类型!

<?php
use Graze\Supervisor\Handler\ExceptionHandler;
use Graze\Supervisor\Handler\RetryHandler;
use Graze\Supervisor\Handler\UnexpectedTerminationHandler;
use Graze\Supervisor\ProcessSupervisor;
use Graze\Supervisor\SupervisorSupervisor;
use Symfony\Component\Process\Process;

$batchA = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=a --half=a'));
$batchB = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=b --half=a'));
$batchC = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=c --half=a'));
$halfA  = new SupervisorSupervisor([$batchA, $batchB, $batchC]);

$batchD = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=d --half=b'));
$batchE = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=e --half=b'));
$batchF = new ProcessSupervisor(Process('/usr/bin/python batch.py --id=f --half=b'));
$halfB  = new SupervisorSupervisor([$batchD, $batchE, $batchF]);

$daemon = new ProcessSupervisor(Process('/usr/bin/php daemon.php'), new RetryHandler(1, new ExceptionHandler()));

$handler = new RetryHandler(3,
    new ExceptionHandler(
        new UnexpectedTerminationHandler()
    )
);

$sup = new SupervisorSupervisor([$halfA, $halfB, $daemon], $handler);
$sup->start();
$sup->supervise();

您可以看到事情会变得多么疯狂。然而,这个库绝对不能取代真正的系统守护进程管理。您应该使用类似 systemdupstart 的东西来处理。

贡献

我们通过拉取请求接受对源代码的贡献,但在考虑合并之前,必须包含单元测试。

$ composer install
$ composer test

如果您发现了一个错误,请在您 创建问题 时包含一个失败的测试。

许可

本库内容由 Nature Delivered Ltd. 根据 MIT 许可证 发布。

您可以在 LICENSEhttps://open-source.org.cn/licenses/mit》中找到此许可证的副本。