2011-01-31 4 views
1

좋아,이 문제를 파악하려고합니다. 수동으로 다시 시작하거나 사용 가능한 RAM이 부족할 때까지 무한 루프를 반복합니다. 필자는 CLI와 일반적인 웹 기반 실행 모두를 준수하도록 코드를 작성했습니다. 유일한 차이점은 웹 기반 실행으로 스크립트가 메모리 문제로 인해 충돌 할 때까지 약 12 ​​시간 정도 지속된다는 것입니다. CLI로 실행하면 훨씬 오래갑니다 (메모리로 인한 충돌이 발생하기 평균 4-5 일 전에)sh에서 CLI에서 PHP 종료 캐치

스크립트는 내가 필요로하는 것을 많이 필요로하는 IRC 봇입니다. 나는 C++, 루비, 파이썬 또는 다른 언어들로 크로스 플랫폼을 지원하는 것을 만들기에 충분하지 않다. 내 dev 컴퓨터는 Windows이고 내 프로덕션 서버는 우분투입니다. 바로 지금 스크립트를 성공적으로 종료하고 터미널 창에서 분리하여 스크립트를 끝내지 않고 닫을 수 있습니다.

그러나 내가 알아 내려고하는 것은 오류를 잡아 내고 자동으로 스크립트를 다시 시작하는 방법입니다.이 스크립트는 임의의 시간에 오류가 발생하는 경향이 있으며 오류를 잡으려고 IRC 채널에있을 때 항상 그런 것은 아닙니다. 마지막으로 긍정적 인 점은 채널에서 다시 시작을 요청하고 계속 새 코드 기능을 추가하거나 일반적인 버그 수정을 추가 할 때 봇을 다시 시작하는 방법입니다. 여기

실행 내가 스크립트를 얻을 그것은 내가 터미널에 다음을 실행할 2 개 서버의 최대 연결 이후에 연결된 서버에 따라 내 CLI 시작 PHP 스크립트

#!/usr/bin/php 
<?php 

include_once ("./config/base_conf.php"); 
include_once ("./libs/irc_base.php"); 

if ($config ['database'] == true) { 
    include_once ("./config/db_conf.php"); 
} 
$server = getopt ('s', array ("server::")); 

if (! $server) { 
    $SER = 'default_server'; 
} elseif ($server ['server'] == 'raelgun') { 
    $SER = 'server_a'; 
} else { 
    $SER = 'default_server'; 
} 

declare (ticks = 1) 
    ; 
$pid = pcntl_fork(); 
if ($pid == - 1) { 
    die ("could not fork"); 
} else if ($pid) { 
    exit(); // we are the parent 
} else { 
    // we are the child 
} 
// detatch from the controlling terminal 
if (posix_setsid() == - 1) { 
    die ("could not detach from terminal"); 
} 
$posid = posix_getpid(); 
$PID_FILE = "/var/run/bot_process_".$SER.".pid"; 
$fp = fopen ($PID_FILE , "w") or die("File Exists Process Running"); 
fwrite ($fp, $posid); 
fclose ($fp); 
// setup signal handlers 
pcntl_signal (SIGTERM, "sig_handler"); 
pcntl_signal (SIGHUP, "sig_handler"); 
// loop forever performing tasks 
$bot = new IRC_BOT ($config, $SER); 
function sig_handler($signo) { 
    switch ($signo) { 
     case SIGTERM : 
      $bot->machineKill(); 
      unlink($PID_FILE); 
      exit(); 
      break; 
     case SIGHUP : 
      $bot->machineKill(); 
      unlink($PID_FILE); 
      break; 
     default : 

     // handle all other signals 
    } 
} 

입니다

php bot_start_shell.php --server="servernamehere" > /dev/null 

그래서 내가 뭘 하려는지 제대로 스크립트를 모니터링하기 위해 코딩 된 쉘 파일을 얻고 오류로 인해 종료하거나 스크립트를 다시 시작하도록 요청한 경우.

+0

확인 [내 대답 (http://stackoverflow.com/questions/4780247에 온다/다시 시작 - PHP 스크립트 - 사용 - 쉘 스크립트/4780328 # 4780328) [매우 비슷한 질문] (http://stackoverflow.com/questions/4780247/restart-a-php-script-using-shell -script)도 여기에서 트릭을하는지보기 위해서 :) – sarnold

+0

트릭을하지 않고있다. 다른 이유로 php를위한 모든 램을 먹어 버리고 올바른 결과를 얻지 못한다. 하지만 스크립트를 직접 실행하면 오류가 발생하지 않습니다. – amwdrizz

답변

2

이 기술은 쉘 스크립트가 PHP 스크립트를 실행하고 종료 값을 모니터링하고 다시 시작되는 동안이 기술을 사용했습니다.

다음은 exit()를 사용하여 쉘 스크립트에 값을 반환하는 테스트 스크립트입니다 - 95,96 & 100은 스크립트의 맨 아래에서 처리되는 다른 '계획되지 않은 다시 시작'으로 간주됩니다.

#!/usr/bin/php 
<?php 
// cli-script.php 
// for testing of the BASH script 
exit (rand(95, 100)); 

/* normally we would return one of 
# 97 - planned pause/restart 
# 98 - planned restart 
# 99 - planned stop, exit. 
# anything else is an unplanned restart 
*/ 

은 내가 스크립트가 실패 즉시 호출되고, 그래서 바로 다시 시작한다면 CPU를 낭비하지 않도록하기 위해 스크립트를 다시 시작하기 전에 몇 초를 기다려야하는 것을 선호합니다.

#!/bin/bash 

# runPHP-Worker.sh 

# a shell script that keeps looping until an exit code is given 
# if its does an exit(0), restart after a second - or if it's a declared error 
# if we've restarted in a planned fashion, we don't bother with any pause 
# and for one particular code, we can exit the script entirely. 
# The numbers 97, 98, 99 must match what is returned from the PHP script 

nice php -q -f ./cli-script.php -- [email protected] 
ERR=$? 

## Possibilities 
# 97 - planned pause/restart 
# 98 - planned restart 
# 99 - planned stop, exit. 
# 0  - unplanned restart (as returned by "exit;") 
#  - Anything else is also unplanned paused/restart 

if [ $ERR -eq 97 ] 
then 
    # a planned pause, then restart 
    echo "97: PLANNED_PAUSE - wait 1"; 
    sleep 1; 
    exec $0 [email protected]; 
fi 

if [ $ERR -eq 98 ] 
then 
    # a planned restart - instantly 
    echo "98: PLANNED_RESTART, no pause"; 
    exec $0 [email protected]; 
fi 

if [ $ERR -eq 99 ] 
then 
    # planned complete exit 
    echo "99: PLANNED_SHUTDOWN"; 
    exit 0; 
fi 

# unplanned exit, pause, and then restart 
echo "unplanned restart: err:" $ERR; 
echo "sleeping for 1 sec" 
sleep 1 

exec $0 [email protected] 

각 값에 대해 서로 다른 일을하지 않으려면, 그것은 정말

#!/bin/bash 
php -q -f ./cli-script.php -- [email protected] 
exec $0 [email protected];