Domanda

Problema: Voglio realizzare diversi processi php-lavoratori che stanno ascoltando su una coda MQ-server per job asincroni. Il problema ora è che semplicemente l'esecuzione di questo elabora come demoni in un server in realtà non mi danno nessun livello di controllo sui casi (Load, Stato, rinchiusi) ... tranne forse per il dumping ps -aux. A causa di ciò che sto cercando un ambiente runtime di qualche tipo che mi permette di monitorare e controllare le istanze, sia a livello di sistema (processo) o su un livello superiore (una sorta di appserver in stile Java)

Tutti gli indicatori?

È stato utile?

Soluzione

Ecco un po 'di codice che può essere utile.

<?
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\n");
        fclose(stdin);
        fclose(stdout);
        fclose(stderr);
        pcntl_exec(PROCESSOR_EXECUTABLE);
        die('Failed to fork ' . PROCESSOR_EXECUTABLE . "\n");
    }
}

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();
?>

Altri suggerimenti

Sembra che hai già un MQ installato e funzionante su un sistema * nix e vogliono solo un modo per gestire i lavoratori.

Un modo molto semplice per farlo è quello di utilizzare lo schermo GNU. Per iniziare a 10 lavoratori è possibile utilizzare:

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

Questo avrà inizio 10 lavoratori in background utilizzando schermi di nome worker_1,2,3 e così via.

È possibile ricollegare alle schermate eseguendo screen -r worker_ ed elencare i lavoratori che eseguono utilizzando -list schermo.

Per ulteriori informazioni questa guida può essere di aiuto: http://www.kuro5hin.org/story/2004/3/ 9/16838/14935

Ricerche correlate:

Per i server di produzione che normalmente consiglia di utilizzare i normali script di avvio del sistema, ma mi è stato l'esecuzione di comandi dello schermo da script di avvio per anni senza problemi.

Avete veramente bisogno di essere continuamente in esecuzione?

Se si desidera solo per deporre le uova nuovo processo, su richiesta, è possibile registrare come servizio in xinetd.

un tipo di server daemon PCNTL plug-in per PHP

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

Qui in basso è la nostra implementazione di lavoro del @chaos risposta. Codice per gestire segnali è stato rimosso come questo script vive di solito solo pochi millisecondi.

Inoltre, nel codice che abbiamo aggiunto 2 funzioni per salvare PID tra le chiamate: restore_processors_state () e save_processors_state (). Abbiamo utilizzato redis lì, ma si può decidere di usare l'esecuzione sui file.

Noi usiamo questo script ogni minuto usando cron. Cron controlla se tutti i processi in vita. In caso contrario - li ri-correre e poi muore. Se vogliamo uccidere i processi esistenti, allora abbiamo semplicemente eseguire lo script con l'argomento kill:. php script.php kill

modo molto pratico di gestire lavoratori senza iniettare script in 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\n");
        fclose(STDIN);
        fclose(STDOUT);
        fclose(STDERR);
        pcntl_exec('/usr/bin/php', array(PROCESSOR_EXECUTABLE));
        die('Failed to fork ' . PROCESSOR_EXECUTABLE . "\n");
    }
}

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();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top