graze/supervisor

:vertical_traffic_light: PHP进程管理器。

1.2.0 2018-11-01 16:30 UTC

This package is auto-updated.

Last update: 2024-09-24 03:49:12 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 这样的工具。

贡献

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

make build test

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

许可

此库的内容由 Nature Delivered Ltd.MIT 许可证 发布。

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