15

問題:非同期ジョブをMQサーバーキューでリッスンしているいくつかのphp-workerプロセスを実装したいと思います。現在の問題は、サーバー上でデーモンとしてこのプロセスを実行するだけでは、インスタンス(ロード、ステータス、ロックアップ)を実際に制御することはできません...おそらくps-auxをダンプする場合を除きます。そのため、システム(プロセス)レベルまたは上位層(ある種のJavaスタイルのアプリサーバー)のいずれかでインスタンスを監視および制御できる、ある種のランタイム環境を探しています。

ポインタはありますか?

4

5 に答える 5

12

役に立つかもしれないいくつかのコードがあります。

<?
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();
?>
于 2009-04-15T15:31:25.797 に答える
4

すでにMQが*nixシステムで稼働していて、ワーカーを管理する方法が必要なようです。

そのための非常に簡単な方法は、GNUscreenを使用することです。10人のワーカーを開始するには、次を使用できます。

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

これにより、worker_1、2、3などの名前の画面を使用してバックグラウンドで10人のワーカーが起動します。

screen -r worker_を実行して画面に再接続し、screen-listを使用して実行中のワーカーを一覧表示できます。

詳細については、このガイドが役立つ場合があります: http ://www.kuro5hin.org/story/2004/3/9/16838/14935

また、試してみてください:

本番サーバーの場合、通常は通常のシステム起動スクリプトを使用することをお勧めしますが、起動スクリプトから画面コマンドを何年も問題なく実行しています。

于 2009-04-15T18:56:52.087 に答える
1

実際に継続的に実行する必要がありますか?

リクエストに応じて新しいプロセスを生成するだけの場合は、xinetdにサービスとして登録できます。

于 2009-04-15T15:33:00.143 に答える
1

PHP用のpcntlプラグインタイプのサーバーデーモン

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

于 2009-06-05T03:55:06.493 に答える
0

以下は、@chaosanswerの実用的な実装です。このスクリプトは通常わずか数ミリ秒で動作するため、シグナルを処理するコードは削除されました。

また、コードでは、呼び出しの間にpidを保存する2つの関数restore_processors_state()とsave_processors_state()を追加しました。そこで使用しましredisたが、ファイルの実装を使用することを決定できます。

cronを使用してこのスクリプトを毎分実行します。Cronは、すべてのプロセスが動作しているかどうかを確認します。そうでない場合-それはそれらを再実行してから死にます。既存のプロセスを強制終了する場合は、引数を指定してこのスクリプトを実行するだけkillですphp script.php kill

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();
于 2013-11-18T08:19:06.380 に答える