سؤال

المشكلة: أريد تنفيذ العديد من عمليات عامل PHP الاستماع في قائمة انتظار خادم MQ-Server للوظائف غير المتزامنة. المشكلة الآن هي أنه ببساطة تشغيل هذه العمليات حيث لا تعطيني Daemons على الخادم أي مستوى من الرقابة في الحالات (تحميل أو الحالة، مغلق) ... باستثناء ربما لإغراق PS -aux. نظرا لأنني أبحث عن بيئة وقت التشغيل من نوع ما يتيح لي مراقبة المراقبة والتحكم في الحالات، إما على مستوى النظام (العملية) أو على طبقة أعلى (نوع من appserver على غرار جافا)

أي مؤشرات؟

هل كانت مفيدة؟

المحلول

إليك بعض التعليمات البرمجية التي قد تكون مفيدة.

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

نصائح أخرى

يبدو أنك أيضا لديك بالفعل MQ Up وتشغيلها على نظام * NIX وتريد طريقة لإدارة العمال.

طريقة بسيطة جدا للقيام بذلك هي استخدام شاشة جنو. لبدء 10 عمال يمكنك استخدامهم:

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

سيبدأ هذا 10 عمال في الخلفية باستخدام شاشات تسمى Worker_1،2،3 وما إلى ذلك.

يمكنك reatttach إلى الشاشات عن طريق تشغيل الشاشة -R Worker_ وقائمة العمال قيد التشغيل باستخدام قائمة الشاشة.

لمزيد من المعلومات، قد يكون هذا الدليل مساعدة:http://www.kuro5hin.org/story/2004/3/9/16838/14935.

حاول ايضا:

  • الشاشة - Help.
  • رجل الشاشة
  • أو غوغل.

بالنسبة لخوادم الإنتاج، أود أن أوصي عادة باستخدام البرامج النصية لبدء بدء تشغيل النظام العادي، لكنني كنت قد قيدت أوامر الشاشة من البرامج النصية لبدء التشغيل لسنوات بدون مشاكل.

هل تحتاج فعلا إلى تشغيلها باستمرار؟

إذا كنت ترغب فقط في تفعيل عملية جديدة عند الطلب، فيمكنك تسجيلها كخدمة في Xinetd.

خادم البرنامج المساعد PCNTL الخفي ل PHP

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

رفع الصوت عاليا هو تنفيذ عملنا في chaos الإجابة. تمت إزالة الرمز للتعامل مع الإشارات لأن هذا البرنامج النصي هذا عادة ما يكون بضع مللي ثانية فقط.

أيضا، في التعليمات البرمجية أضفنا 2 وظائف لحفظ pids بين المكالمات: restore_processors_state () وحفظ_processors_state (). لقد استخدمنا redis هناك، ولكن يمكنك أن تقرر استخدام التنفيذ على الملفات.

ندير هذا البرنامج النصي كل دقيقة باستخدام كرون. الشيكات كرون إذا كانت جميع العمليات حية. إذا لم يكن الأمر كذلك - أعاد تشغيلها ثم يموت. إذا كنا نريد قتل العمليات الحالية، فكلنا ببساطة تشغيل هذا البرنامج النصي مع وسيطة 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();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top