PHP守护进程/工作者环境

问题:我想实现几个正在侦听MQ服务器队列以进行异步作业的php-worker进程。 现在的问题是,简单地将这个进程作为服务器上的守护进程运行并不能真正给我任何级别的控制实例(负载,状态,锁定)......除了可能用于转储ps -aux。
因此 我正在寻找某种运行时环境,它允许我监视和控制实例,无论是在系统(进程)级别还是在更高层(某种类型的Java风格的应用程序服务器)上</ p>

< p>任何指针?</ p>
</ div>

展开原文

原文

Problem: I want to implement several php-worker processes who are listening on a MQ-server queue for asynchronous jobs. The problem now is that simply running this processes as daemons on a server doesn't really give me any level of control over the instances (Load, Status, locked up)...except maybe for dumping ps -aux. Because of that I'm looking for a runtime environment of some kind that lets me monitor and control the instances, either on system (process) level or on a higher layer (some kind of Java-style appserver)

Any pointers?

dongpo5239
dongpo5239 另请参阅:symfony.com/doc/master/components/process.html
8 年多之前 回复

5个回答

Here's some code that may be useful.

<?
define('WANT_PROCESSORS', 5);
define('PROCESSOR_EXECUTABLE', '/path/to/your/processor');
set_time_limit(0);
$cycles = 0;
$run = true;
$reload = false;
declare(ticks = 30);

function signal_handler($signal) {
    switch($signal) {
    case SIGTERM :
        global $run;
        $run = false;
        break;
    case SIGHUP  :
        global $reload;
        $reload = true;
        break;
    }   
}

pcntl_signal(SIGTERM, 'signal_handler');
pcntl_signal(SIGHUP, 'signal_handler');

function spawn_processor() {
    $pid = pcntl_fork();
    if($pid) {
        global $processors;
        $processors[] = $pid;
    } else {
        if(posix_setsid() == -1)
            die("Forked process could not detach from terminal
");
        fclose(stdin);
        fclose(stdout);
        fclose(stderr);
        pcntl_exec(PROCESSOR_EXECUTABLE);
        die('Failed to fork ' . PROCESSOR_EXECUTABLE . "
");
    }
}

function spawn_processors() {
    global $processors;
    if($processors)
        kill_processors();
    $processors = array();
    for($ix = 0; $ix < WANT_PROCESSORS; $ix++)
        spawn_processor();
}

function kill_processors() {
    global $processors;
    foreach($processors as $processor)
        posix_kill($processor, SIGTERM);
    foreach($processors as $processor)
        pcntl_waitpid($processor);
    unset($processors);
}

function check_processors() {
    global $processors;
    $valid = array();
    foreach($processors as $processor) {
        pcntl_waitpid($processor, $status, WNOHANG);
        if(posix_getsid($processor))
            $valid[] = $processor;
    }
    $processors = $valid;
    if(count($processors) > WANT_PROCESSORS) {
        for($ix = count($processors) - 1; $ix >= WANT_PROCESSORS; $ix--)
            posix_kill($processors[$ix], SIGTERM);
        for($ix = count($processors) - 1; $ix >= WANT_PROCESSORS; $ix--)
            pcntl_waitpid($processors[$ix]);
    } elseif(count($processors) < WANT_PROCESSORS) {
        for($ix = count($processors); $ix < WANT_PROCESSORS; $ix++)
            spawn_processor();
    }
}

spawn_processors();

while($run) {
    $cycles++;
    if($reload) {
        $reload = false;
        kill_processors();
        spawn_processors();
    } else {
        check_processors();
    }
    usleep(150000);
}
kill_processors();
pcntl_wait();
?>
dongtao5055
dongtao5055 你应该把它写成一个单独的答案而不是评论。 :)
9 年多之前 回复
doufen3134
doufen3134 另外,github.com / kvz / system_daemon。
9 年多之前 回复
dongxu1668
dongxu1668 我自己的代码。 我不倾向于解释它,不。
大约 10 年之前 回复
dsp15140275697
dsp15140275697 你在哪里得到这个? 开源项目还是您自己的代码? 有关这里到底发生了什么的任何文件或解释?
大约 10 年之前 回复



听起来你已经在* nix系统上启动并运行了MQ,只是想要一种管理工作者的方法。</ p >

一种非常简单的方法是使用GNU屏幕。 要启动10个工作人员,您可以使用:</ p>

 #!/ bin / sh 
for x in seq 1 10`; do
screen -dmS worker_ $ x php /path/to/script.php worker $ x
end
</ code> </ pre>

这将使用命名的屏幕在后台启动10名工作人员 worker_1,2,3等等。</ p>

您可以通过运行screen -r worker_重新连接到屏幕,并使用screen -list列出正在运行的worker。</ p>
\ n

欲了解更多信息,本指南可能会有所帮助:
http://www.kuro5hin.org/story/2004/3/9/16838/14935 </ p>

还可以尝试:</ p>



  • screen --help </ li>
  • man screen </ li>
  • google 。</ li>
    </ ul>

    对于生产服务器,我通常建议使用正常的系统启动脚本 ,但我已经从启动脚本运行屏幕命令多年没有问题。</ p>
    </ div>

展开原文

原文

It sounds like you already have a MQ up and running on a *nix system and just want a way to manage workers.

A very simple way to do so is to use GNU screen. To start 10 workers you can use:

#!/bin/sh
for x in `seq 1 10` ; do
screen -dmS worker_$x php /path/to/script.php worker$x
end

This will start 10 workers in the background using screens named worker_1,2,3 and so on.

You can reattach to the screens by running screen -r worker_ and list the running workers by using screen -list.

For more info this guide may be of help: http://www.kuro5hin.org/story/2004/3/9/16838/14935

Also try:

  • screen --help
  • man screen
  • or google.

For production servers I would normally recommend using the normal system startup scripts, but I have been running screen commands from the startup scripts for years with no problems.



你真的需要它继续运行吗?</ p>

如果你只想生成新的 根据请求处理,您可以将其注册为xinetd中的服务。 </ p>
</ div>

展开原文

原文

Do you actually need it to be continuously running?

If you only want to spawn new process on request, you can register it as a service in xinetd.

douyong1974
douyong1974 这是一个选择。 对于监视,您还可以使用flock() - 编辑的PID文件。 崩溃后,所有锁都被释放。
11 年多之前 回复
douhui9631
douhui9631 产卵方面不是一个大问题,因为工人的数量取决于系统性能,而这通常是不变的。 更重要的是个体工人身份的监控方面(崩溃,无论如何)。 我刚刚发现的一个工具可能是DJBs deamontools
11 年多之前 回复



用于PHP的pcntl插件类型服务器守护程序</ p>

http://dev.pedemont.com/sonic/ </ p>
</ div>

展开原文

原文

a pcntl plugin type server daemon for PHP

http://dev.pedemont.com/sonic/

Bellow is our working implementation of @chaos answer. Code to handle signals was removed as this script lives usually just few milliseconds.

Also, in code we added 2 functions to save pids between calls: restore_processors_state() and save_processors_state(). We've used redis there, but you can decide to use implementation on files.

We run this script every minute using cron. Cron checks if all processes alive. If not - it re-run them and then dies. If we want to kill existing processes then we simply run this script with argument kill: php script.php kill.

Very handy way of running workers without injecting scripts into init.d.

<?php

include_once dirname( __FILE__ ) . '/path/to/bootstrap.php';

define('WANT_PROCESSORS', 5);
define('PROCESSOR_EXECUTABLE', '' . dirname(__FILE__) . '/path/to/worker.php');
set_time_limit(0);

$run = true;
$reload = false;
declare(ticks = 30);

function restore_processors_state()
{
    global $processors;

    $redis = Zend_Registry::get('redis');
    $pids = $redis->hget('worker_procs', 'pids');

    if( !$pids )
    {
        $processors = array();
    }
    else
    {
        $processors = json_decode($pids, true);
    }
}

function save_processors_state()
{
    global $processors;

    $redis = Zend_Registry::get('redis');
    $redis->hset('worker_procs', 'pids', json_encode($processors));
}

function spawn_processor() {
    $pid = pcntl_fork();
    if($pid) {
        global $processors;
        $processors[] = $pid;
    } else {
        if(posix_setsid() == -1)
            die("Forked process could not detach from terminal
");
        fclose(STDIN);
        fclose(STDOUT);
        fclose(STDERR);
        pcntl_exec('/usr/bin/php', array(PROCESSOR_EXECUTABLE));
        die('Failed to fork ' . PROCESSOR_EXECUTABLE . "
");
    }
}

function spawn_processors() {
    restore_processors_state();

    check_processors();

    save_processors_state();
}

function kill_processors() {
    global $processors;
    foreach($processors as $processor)
        posix_kill($processor, SIGTERM);
    foreach($processors as $processor)
        pcntl_waitpid($processor, $trash);
    unset($processors);
}

function check_processors() {
    global $processors;
    $valid = array();
    foreach($processors as $processor) {
        pcntl_waitpid($processor, $status, WNOHANG);
        if(posix_getsid($processor))
            $valid[] = $processor;
    }
    $processors = $valid;
    if(count($processors) > WANT_PROCESSORS) {
        for($ix = count($processors) - 1; $ix >= WANT_PROCESSORS; $ix--)
            posix_kill($processors[$ix], SIGTERM);
        for($ix = count($processors) - 1; $ix >= WANT_PROCESSORS; $ix--)
            pcntl_waitpid($processors[$ix], $trash);
    }
    elseif(count($processors) < WANT_PROCESSORS) {
        for($ix = count($processors); $ix < WANT_PROCESSORS; $ix++)
            spawn_processor();
    }
}

if( isset($argv) && count($argv) > 1 ) {
    if( $argv[1] == 'kill' ) {
        restore_processors_state();
        kill_processors();
        save_processors_state();

        exit(0);
    }
}

spawn_processors();
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐