source

데몬 프로세스로 php 스크립트 실행

manysource 2022. 10. 14. 22:13

데몬 프로세스로 php 스크립트 실행

데몬 프로세스로 php 스크립트를 실행해야 합니다(지시 대기 및 작업).cron 작업에서는 명령어가 도착하자마자 액션을 수행해야 하기 때문에 작업을 수행할 수 없습니다.메모리 관리 문제로 인해 PHP가 데몬 프로세스에 가장 적합한 옵션은 아니지만 다양한 이유로 인해 이 경우 PHP를 사용해야 합니다.libslack에서 Daemon(http://libslack.org/daemon)이라는 툴을 발견했습니다만, 데몬 프로세스 관리에 도움이 되는 것 같습니다만, 최근 5년간 갱신이 없었기 때문에, 제 케이스에 맞는 다른 대체 툴은 알고 계십니까?어떤 정보라도 감사합니다.

php 스크립트를 명령줄에서 시작할 수 있습니다(즉, bash).

nohup php myscript.php &

&프로세스를 백그라운드로 만듭니다.

★★★★
네, 몇 가지 단점이 있지만 통제할 수 없는 건가요?그건 잘못된 거야.
한 a a.kill processid 여전히 그리고 이것은 여전히 가장 간단하고 최선의 해결책입니다.

다른 옵션은 Upstart를 사용하는 것입니다.원래는 Ubuntu용으로 개발되었지만(디폴트로는 패키지로 제공됨) 모든 Linux 디스트로에 적합하도록 설계되어 있습니다.

이 방법은 시스템 부팅 시 데몬이 자동으로 시작되고 스크립트 완료 시 재시작된다는 점에서 슈퍼바이저드데몬툴과 비슷합니다.

셋업 방법:

./etc/init/myphpworker.conf하다

# Info
description "My PHP Worker"
author      "Jonathan"

# Events
start on startup
stop on shutdown

# Automatically respawn
respawn
respawn limit 20 5

# Run the script!
# Note, in this example, if your PHP script returns
# the string "ERROR", the daemon will stop itself.
script
    [ $(exec /usr/bin/php -f /path/to/your/script.php) = 'ERROR' ] && ( stop; exit 1; )
end script

데몬 시작 및 중지:

sudo service myphpworker start
sudo service myphpworker stop

데몬이 실행 중인지 확인합니다.

sudo service myphpworker status

감사해요.

케빈조네벨드에게 큰 감사를 표합니다. 제가 이 기술을 배운 곳에서요.

새로운 systemd를 사용하여 서비스를 생성할 수 있습니다.

파일 또는 심볼링크를 작성해야 합니다./etc/systemd/system/(음악: myphdaemon).myphdaemon이라는 서비스 .

[Unit]
Description=My PHP Daemon Service
#May your script needs MySQL or other services to run, eg. MySQL Memcached
Requires=mysqld.service memcached.service 
After=mysqld.service memcached.service

[Service]
User=root
Type=simple
TimeoutSec=0
PIDFile=/var/run/myphpdaemon.pid
ExecStart=/usr/bin/php -f /srv/www/myphpdaemon.php arg1 arg2> /dev/null 2>/dev/null
#ExecStop=/bin/kill -HUP $MAINPID #It's the default you can change whats happens on stop command
#ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

Restart=on-failure
RestartSec=42s

StandardOutput=null #If you don't want to make toms of logs you can set it null if you sent a file or some other options it will send all PHP output to this one.
StandardError=/var/log/myphpdaemon.log
[Install]
WantedBy=default.target

다음 명령을 사용하여 서비스를 시작, 상태 가져오기, 재시작 및 중지할 수 있습니다.

systemctl <start|status|restart|stop|enable> myphpdaemon

는 PHP를 사용하여 할 수 .php -S 127.0.0.1:<port>스크립트로 실행할 수도 있습니다.PHP 스크립트를 사용하여 실행을 계속하려면 일종의 "영원한 루프"가 있어야 합니다.

<?php
gc_enable();//
while (!connection_aborted() || PHP_SAPI == "cli") {
  
  //Code Logic
  
  //sleep and usleep could be useful
    if (PHP_SAPI == "cli") {
        if (rand(5, 100) % 5 == 0) {
            gc_collect_cycles(); //Forces collection of any existing garbage cycles
        }
    }
}

작업 예:

[Unit]
Description=PHP APP Sync Service
Requires=mysqld.service memcached.service
After=mysqld.service memcached.service

[Service]
User=root
Type=simple
TimeoutSec=0
PIDFile=/var/run/php_app_sync.pid
ExecStart=/bin/sh -c '/usr/bin/php -f /var/www/app/private/server/cron/app_sync.php  2>&1 > /var/log/app_sync.log'
KillMode=mixed

Restart=on-failure
RestartSec=42s

[Install]
WantedBy=default.target

PHP 루틴을 사이클에 한 번 실행해야 하는 경우(디게스트 등), 셸 또는 bash 스크립트를 사용하여 PHP 대신 systemd 서비스 파일에 직접 호출할 수 있습니다.예를 들어 다음과 같습니다.

#!/usr/bin/env bash
script_path="/app/services/"

while [ : ]
do
#    clear
    php -f "$script_path"${1}".php" fixedparameter ${2}  > /dev/null 2>/dev/null
    sleep 1
done

이 옵션을 선택한 경우 KillMode를 다음과 같이 변경해야 합니다.mixed프 bash 、 bash ( main ) 、 PHP ( child ) 。

ExecStart=/app/phpservice/runner.sh phpfile parameter  > /dev/null 2>/dev/null
KillMode=process

This method also is effective if you're facing a memory leak.

주의: 매번 myphdaemon을 변경합니다.service"는 "systemctl daemon-daemon-daemon-daemon"을 실행해야 하지만 실행하지 않으면 필요할 때 알림이 표시됩니다.

가능한 경우 UNIX 환경의 고급 프로그래밍 복사본을 가져옵니다.13장 전체는 데몬 프로그래밍에 대한 내용입니다.예를 들어 C에 있지만 필요한 모든 함수는 PHP로 래퍼를 사용합니다(기본적으로 pcntlposix 확장자).

한마디로 데몬 쓰기(*nix 기반 OS에서만 가능 - Windows는 서비스를 사용합니다)는 다음과 같습니다.

  1. 권한 문제를 방지하기 위해 호출합니다.
  2. fork() 부모에게 퇴출시킬 수 있습니다.
  3. 를 호출합니다.
  4. 「」의 셋업 신호 .SIGHUP 위해 됩니다)및 ('Daemon't 'Daemon't signal to reload').SIGTERM(프로세스를 정상적으로 종료하도록 지시합니다).
  5. fork()다시 부모를 종료합니다.
  6. 와 함께 현재 동작 중인 dir를 변경합니다.
  7. fclose() stdin,stdout ★★★★★★★★★★★★★★★★★」stderr★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★은 이런 을 '어느 쪽인가'로입니다./dev/null파일도 있지만 PHP로 할 수 있는 방법을 찾을 수 없었습니다.데몬을 기동하면 셸을 사용하여 리다이렉트 할 수 있습니다(모르겠습니다).
  8. 일을 해라!

또, PHP 를 사용하고 있기 때문에, 주기적인 참조에 주의해 주세요.PHP 가비지 콜렉터는, PHP 5.3 이전 버전에서는, 이러한 참조를 수집할 방법이 없기 때문에, 프로세스가 크래쉬 할 때까지, 메모리 누수가 발생합니다.

저는 많은 PHP 데몬을 실행하고 있습니다.

PHP가 이를 위한 최적의 언어(또는 좋은 언어)는 아니지만 데몬은 웹용 컴포넌트와 코드를 공유하기 때문에 전반적으로 우리에게 좋은 솔루션입니다.

데몬툴을 사용합니다.그것은 똑똑하고, 깨끗하고, 믿을 수 있다.사실 우리는 모든 데몬을 작동시키기 위해 그것을 사용합니다.

http://cr.yp.to/daemontools.html 에서 확인하실 수 있습니다.

편집: 기능의 빠른 목록.

  • 재부팅 시 자동으로 데몬 시작
  • 장애 발생 시 자동으로 dameon 재시작
  • 롤오버 및 프루닝 등 로깅이 처리됩니다.
  • 관리 인터페이스: 'svc' 및 'svstat'
  • UNIX 친화적(모든 사람에게 좋은 것은 아닐 수도 있음)

넌 할 수 있다.

  1. nohup헨릭이 제안한 대로요
  2. screenPHP 프로그램을 일반 프로세스로 실행할 수 있습니다. 하면 더 잘 할 수 .nohup
  3. http://supervisord.org/과 같은 데몬라이저를 사용합니다(Python으로 작성되어 있지만 어떤 명령줄 프로그램도 데몬라이즈 할 수 있으며 원격 제어로 관리할 수 있습니다).
  4. 에밀이 제안한 대로 데몬스 포장지를 직접 쓰세요 하지만 그건 과잉 살상 IMO입니다

가장 간단한 방법(화면)을 추천합니다.그리고 더 많은 기능을 원한다면 더 복잡한 방법으로 넘어갑니다.

이 문제를 해결하는 방법은 여러 가지가 있다.

자세한 것은 모릅니다만, PHP 프로세스를 기동하는 다른 방법이 있을지도 모릅니다.예를 들어 SQL 데이터베이스의 이벤트를 기반으로 코드를 실행해야 하는 경우 스크립트를 실행하는 트리거를 설정할 수 있습니다.이것은 Postgre에서 하기 매우 쉽다.SQL: http://www.postgresql.org/docs/current/static/external-pl.html

솔직히 말해서, 나는 네가 노업을 사용하여 Damon 프로세스를 만드는 것이 최선이라고 생각해.nohup을 사용하면 사용자가 로그아웃한 후에도 명령어를 계속 실행할 수 있습니다.

nohup php myscript.php &

그러나 매우 심각한 문제가 있다.PHP의 메모리 매니저는 완전 가비지라고 말씀하셨듯이 스크립트가 몇 초만 실행되고 그 후에 존재한다고 가정하여 구축되었습니다.PHP 스크립트가 GIGAB를 사용하기 시작합니다.불과 며칠 후의 메모리 YTES.또한 다음과 같이 php 스크립트를 종료하고 재스패닝하는 cron 스크립트를 12시간 또는 24시간마다 작성해야 합니다.

killall -3 php
nohup php myscript.php &

하지만 대본이 작업 중이라면요?Kill - 3은 인터럽트이며 CLI에서 ctrl+c를 실행하는 것과 같습니다.php 스크립트는 이 인터럽트를 포착하여 PHP pcntl 라이브러리를 사용하여 정상적으로 종료할 수 있습니다.http://php.oregonstate.edu/manual/en/function.pcntl-signal.php

다음은 예를 제시하겠습니다.

function clean_up() {
  GLOBAL $lock;
  mysql_close();
  fclose($lock)
  exit();
}
pcntl_signal(SIGINT, 'clean_up');

$lock의 배후에 있는 아이디어는 PHP 스크립트가 fopen("file")을 사용하여 파일을 열 수 있다는 것입니다.파일에 대한 쓰기 잠금을 설정할 수 있는 프로세스는 1개뿐이므로 이를 사용하면 PHP 스크립트의 복사본이 1개만 실행되도록 할 수 있습니다.

행운을 빕니다.

Kevin van Zonneveld는 이에 대한 매우 상세한 기사를 작성했습니다.이 예에서는 PEAR 패키지를 사용하고 있습니다(2009-09-02의 최종 출시일).

https://github.com/shaneharter/PHP-Daemon 를 확인해 주세요.

이것은 객체 지향 데몬 라이브러리입니다.로깅 및 오류 복구와 같은 기능을 기본적으로 지원하며 백그라운드 워커를 생성할 수 있습니다.

최근 PHP 스크립트를 데몬으로 실행하는 문제에 대한 크로스 플랫폼 솔루션(Windows, Mac 및 Linux)이 필요했습니다.독자적인 C++ 베이스의 솔루션을 작성해, 바이너리를 작성함으로써 문제를 해결했습니다.

https://github.com/cubiclesoft/service-manager/

Linux(sysvinit 경유)를 완전히 지원하지만 Windows NT 서비스 및 Mac OSX 출시도 지원합니다.

Linux 만이 필요한 경우, 여기에 제시된 다른 솔루션 중 몇 가지는 충분히 동작합니다.또, 맛에 따라서도움이 됩니다.최근에는 Upstart와 systemd도 있어 sysvinit 스크립트로 폴백이 되어 있습니다.그러나 PHP를 사용하는 요점의 절반은 본질적으로 크로스 플랫폼이기 때문에 언어로 작성된 코드는 현재 어디에서나 사용할 수 있습니다.시스템 서비스 등 특정 외부 네이티브 OS 수준의 측면이 도입되면 결함이 나타나기 시작하지만 대부분의 스크립트 언어에서 이러한 문제가 발생합니다.

PHP 유저랜드에서 누군가가 제안한 대로 신호를 잡으려고 하는 것은 좋은 생각이 아닙니다.『 『 』의 매뉴얼을 .pcntl_signal()PHP가 프로세스에서 거의 볼 수 없는 것(즉, 신호)을 위해 많은 사이클을 씹는 다소 불쾌한 방법(특히 '틱스')을 사용하여 신호를 처리하는 것을 주의 깊게 알게 될 것입니다.PHP에서의 신호 처리도 POSIX 플랫폼에서만 거의 사용할 수 없으며, 지원은 PHP 버전에 따라 다릅니다.처음에는 괜찮은 해결책처럼 들리지만 실제로는 유용하지 않습니다.

PHP는 시간이 지날수록 메모리 누수 문제도 개선되고 있습니다.여전히 주의해야 합니다(DOM XML 파서는 여전히 누출되는 경향이 있습니다). 하지만 요즘 폭주 프로세스를 거의 볼 수 없고 PHP 버그 트래커는 예전과 비교하면 상당히 조용합니다.

pm2는 http://pm2.keymetrics.io/ 에서 확인할 수 있습니다.http://pm2.keymetrics.io/

ssh 파일을 만듭니다.예를 들어 worker.sh을 php 스크립트에 삽입하여 취급합니다.

worker.sh

php /path/myscript.php

데몬 기동

pm2 start worker.sh

건배, 그게 다야.

다른 사람들이 이미 언급했듯이, PHP를 데몬으로 실행하는 것은 매우 쉬우며 하나의 명령줄을 사용하여 실행할 수 있습니다.그러나 실제 문제는 시스템을 계속 가동하고 관리하는 것입니다.이전에도 같은 문제가 있었습니다만, 이미 많은 솔루션이 있습니다만, 대부분은 의존성이 높거나 사용하기 어렵고, 기본적인 사용법에 적합하지 않습니다.PHP CLI 스크립트를 포함한 모든 프로세스/애플리케이션을 관리할 수 있는 셸 스크립트를 작성했습니다.cronjob으로 설정하여 응용 프로그램을 시작할 수 있으며 응용 프로그램을 포함하고 관리합니다.예를 들어 동일한 cronjob을 통해 다시 실행되면 앱이 실행 중인지 여부를 확인하고 실행 중이면 단순히 종료하고 이전 인스턴스가 애플리케이션을 계속 관리하도록 합니다.

github에 올렸으니 자유롭게 사용하세요:https://github.com/sinasalek/EasyDeamonizer

Easy Deamonizer

애플리케이션(시작, 재시작, 로그, 모니터 등)을 간단하게 감시할 수 있습니다.응용 프로그램이 올바르게 실행되도록 하는 일반 스크립트입니다.의도적으로 pid/lock 파일의 instread 프로세스 이름을 사용하여 모든 부작용을 방지하고 스크립트를 최대한 단순하고 쉽게 유지하므로 Easy Daemonizer 자체를 재시작해도 항상 작동합니다.특징들

  • 애플리케이션을 기동해, 기동 마다 커스터마이즈 된 지연을 선택적으로 실시합니다.
  • 하나의 인스턴스만 실행 중인지 확인합니다.
  • CPU 사용량을 모니터링하고 정의된 임계값에 도달하면 앱을 자동으로 재시작합니다.
  • 어떤 이유로 중지된 경우 cron을 통해 실행되도록 EasyDeamonizer 설정
  • 액티비티를 로그에 기록합니다.

추가 설치 없이 SSH 액세스를 허용하는 일반적인 호스팅과 호환되는 단순한 솔루션을 찾고 있었습니다.

채팅 서버의 설정은 다음과 같습니다.

-rwxr-xr-x  1 crazypoems psacln   309 ene 30 14:01 checkChatServerRunning.sh
-rw-r--r--  1 crazypoems psacln  3018 ene 30 13:12 class.chathandler.php
-rw-r--r--  1 crazypoems psacln    29 ene 30 14:05 cron.log
-rw-r--r--  1 crazypoems psacln  2560 ene 29 08:04 index.php
-rw-r--r--  1 crazypoems psacln  2672 ene 30 13:29 php-socket.php
-rwxr-xr-x  1 crazypoems psacln   310 ene 30 14:04 restartChatServer.sh
-rwxr-xr-x  1 crazypoems psacln   122 ene 30 13:28 startChatServer.sh
-rwxr-xr-x  1 crazypoems psacln   224 ene 30 13:56 stopChatServer.sh

그리고 스크립트:

startChatServer 입니다.

#!/bin/bash
nohup /opt/plesk/php/5.6/bin/php -q /var/www/vhosts/crazypoems.org/httpdocs/chat/php-socket.php > /dev/null &

stopChatServer.

#!/bin/bash
PID=`ps -eaf | grep '/var/www/vhosts/crazypoems.org/httpdocs/chat/php-socket.php' | grep -v grep | awk '{print $2}'`
if [[ "" !=  "$PID" ]]; then
  echo "killing $PID"
  kill -9 $PID
else
  echo "not running"
fi

restartChatServer.

#!/bin/bash
PID=`ps -eaf | grep '/var/www/vhosts/crazypoems.org/httpdocs/chat/php-socket.php' | grep -v grep | awk '{print $2}'`
if [[ "" !=  "$PID" ]]; then
  echo "killing $PID"
  kill -9 $PID
else
  echo "not running"
fi
echo "Starting again"
/var/www/vhosts/crazypoems.org/httpdocs/chat/startChatServer.sh

마지막으로 cron 작업에 마지막 스크립트를 배치하여 "채팅서버가 실행 중"인지 확인하고 실행 중이지 않은 경우 부팅합니다.

Cron 작업 매분

-bash-4.1$ crontab -l
*       *       *       *       * /var/www/vhosts/crazypoems.org/httpdocs/chat/checkChatServerRunning.sh > /var/www/vhosts/crazypoems.org/httpdocs/chat/cron.log

checkChatServerRunning 입니다.

#!/bin/bash
PID=`ps -eaf | grep '/var/www/vhosts/crazypoems.org/httpdocs/chat/php-socket.php' | grep -v grep | awk '{print $2}'`
if [[ "" !=  "$PID" ]]; then
  echo "Chat server running on $PID"
else
  echo "Not running, going to start it"
  /var/www/vhosts/crazypoems.org/httpdocs/chat/startChatServer.sh
fi

이 설정에서는:

  • 필요에 따라 스크립트를 사용하여 서비스를 수동으로 제어할 수 있습니다(예: 유지보수).
  • cron 작업은 재부팅 시 또는 크래시 시 서버를 시작합니다.

간단한 php-daemon을 작성하여 배포했습니다. 코드는 여기 온라인입니다.

https://github.com/jmullee/PhpUnixDaemon

기능: 특권 폐기, 신호 처리, 로깅

큐잉에서 사용하였습니다(사용 예: 페이지 생성 php를 대기시키지 않고 웹 페이지에서 긴 작업을 트리거합니다.즉, 비동기 작업을 시작합니다).https://github.com/jmullee/PhpIPCMessageQueue

Emil Ivaov 응답을 확장하면 다음 작업을 수행하여 php에서 STDIN, STDOUT 및 STDERROR을 닫을 수 있습니다.

if (!fclose(STDIN)) {
    exit("Could not close STDIN");
}

if (!fclose(STDOUT)) {
    exit("Could not close STDOUT");
}

if (!fclose(STDERR)) {
    exit("Could not close STDERR");
}

$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen('/dev/null', 'w');
$STDERR = fopen('/var/log/our_error.log', 'wb');

기본적으로 표준 스트림을 닫으면 PHP가 쓸 곳이 없어집니다.이하와 같다fopen콜은 표준 IO를 다음과 같이 설정합니다./dev/null.

Rob Aley - 웹을 넘어선 PHP의 책에서 이 글을 읽었습니다.

언급URL : https://stackoverflow.com/questions/2036654/run-php-script-as-daemon-process