首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >监督者:如果任何工作人员,例如进程id 123停止,我如何执行自定义php命令?

监督者:如果任何工作人员,例如进程id 123停止,我如何执行自定义php命令?
EN

Stack Overflow用户
提问于 2020-08-05 17:20:33
回答 1查看 2.6K关注 0票数 2
代码语言:javascript
复制
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php artisan queue:work --tries=3 --queue=checkin_checkout
directory=/var/www/byjus-ams
autostart=true
autorestart=true
numprocs=5
redirect_stderr=true
stdout_logfile=/var/log/supervisor/supervisord.log
#stopwaitsecs=3600

到目前为止,我对主管的配置如下所示,它并行运行5名员工。现在我想要的是:当任何一个工人被杀时,我想要触发自定义php命令(例如:php、手工广播-process杀死的)。任何人都知道如何处理这些事件,并在任何辅助进程获得之后触发自定义php命令,以及如何配置它?

甚至简化了下面

代码语言:javascript
复制
supervisor> status
laravel-worker:laravel-worker_00   RUNNING   pid 9460, uptime 4:32:43
laravel-worker:laravel-worker_01   RUNNING   pid 15907, uptime 7:01:51
laravel-worker:laravel-worker_02   RUNNING   pid 22621, uptime 6:30:17
laravel-worker:laravel-worker_03   RUNNING   pid 15909, uptime 7:01:51
laravel-worker:laravel-worker_04   RUNNING   pid 24049, uptime 6:23:00
supervisor> 

如果我使用杀害-9 9460,我想运行自定义命令。有人使用过自定义事件吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-06 03:52:46

我找到了一个解决方案,您可以在实际命令之前运行命令:

代码语言:javascript
复制
command=/bin/sh -c "php artisan broadcast-process-started; exec php artisan queue:work --tries=3 --queue=checkin_checkout"

这样做将始终在员工停止工作并重新启动之后执行broadcast-process-started

通过使用/bin/sh -c,您可以从这两个命令中生成一个命令。通过将execute添加到第二个“实际”命令中,supervisord将能够处理其pid。

如果省略了执行部分,您将得到由/bin/sh分叉的pid,而内部的所有命令都会作为子进程产生,这是监督无法处理的。因此,当您重新加载子进程持续!所以留下执政官吧!

如果你翻转命令,广播就不会执行。

事件侦听器解决方案

监督配置

代码语言:javascript
复制
[eventlistener:test-listener]
command=php /some/dir/event-listener.php <name>
events=PROCESS_STATE
stderr_logfile=/some/dir/event_err.log

其中<name>指的是您的配置的[program:<name>] --您想要观察的程序。

event-listener.php

编写为php-script -您也可以将其编码为artisan命令。

代码语言:javascript
复制
<?php

declare(strict_types=1);

$programToListen = $argv[1] ?? false;
$eventsToListen = [
    'PROCESS_STATE_EXITED',
    'PROCESS_STATE_FATAL',
    'PROCESS_STATE_STOPPED',
];

if ($programToListen === false) {
    exit(1);
}

while (true) {
    // tell supervisord we are ready to receive event-headers
    echo 'READY' . PHP_EOL;
    
    $eventHeader = parseEventHeader(fgets(STDIN));
    
    if (
        ($eventHeader['groupname'] ?? '') === $programToListen &&
        in_array(($eventHeader['eventname'] ?? ''), $eventsToListen)
    ) {
        debug(sprintf(
            'Handling %s of %s',
            $eventHeader['eventname'],
            $eventHeader['groupname']
        ));
       
        // add your code here
        // exec('php artisan ...') for example
    }

    // Tell supervisord we are done handling the event-header
    echo 'RESULT 2' . PHP_EOL . 'OK';
}

function debug(string $message): void {
    fwrite(STDERR, $message . PHP_EOL);
    return;
}

function parseEventHeader(string $eventHeaderString): array {
    $keyValuePairs = explode(' ', $eventHeaderString);

    $eventArray = [];
    foreach ($keyValuePairs as $keyValuePair) {
        $keyValue = explode(':', $keyValuePair);

        $eventArray[$keyValue[0]] = $keyValue[1];
    }

    return $eventArray;
}

exit(0)
?>

琐事

  • 与其使用echo,您还可以使用fwrite(STDOUT,..),但这对我来说有点太花哨了。
  • 我保留了我的调试机制,以防您想要摆弄它(您会:D)。

补充资料

  • 在这里查看一下可用的过程类型
  • 在这里查看次级进程-国家 (它会产生事件)。
  • 事件侦听器通知协议 (我们的echo消息和事件头解析)。
  • PROCESS_STATE_EXITED将在> kill或执行结束时触发
  • PROCESS_STATE_STOPPED将由主管(restart等)触发。
  • 我没有触发PROCESS_STATE_FATAL,但我会监听它,以防万一:)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63270368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档