Muszę uruchomić skrypt php jako proces demona (czekaj na instrukcje i rób rzeczy). cron nie zrobi tego za mnie, ponieważ działania muszą zostać podjęte, gdy tylko nadejdzie instrukcja. Wiem, że PHP nie jest najlepszą opcją dla procesów demonów ze względu na problemy z zarządzaniem pamięcią, ale z różnych powodów muszę w tym przypadku używać PHP. Natknąłem się na narzędzie autorstwa libslack o nazwie Daemon ( http://libslack.org/daemon ), które wydaje się pomagać mi w zarządzaniu procesami demona, ale nie było żadnych aktualizacji w ciągu ostatnich 5 lat, więc zastanawiam się, czy znasz jakieś inne alternatywy odpowiednie dla mojego przypadku. Każda informacja będzie naprawdę mile widziana.
154
Odpowiedzi:
Możesz uruchomić swój skrypt php z wiersza poleceń (np. Bash) za pomocą
nohup php myscript.php &
&
stawia proces w tle.Edycja:
Tak, są pewne wady, ale nie można ich kontrolować? Po prostu źle.
Prosty
kill processid
to powstrzyma. I nadal jest to najlepsze i najprostsze rozwiązanie.źródło
nohup
i&
robi to samo samą rzecz: rozpoczęto proces odłączania od obecnego intance skorupy. Dlaczego potrzebuję ich obu? Czy nie mogę po prostu zrobić,php myscript.php &
czynohup myscript.php
?? Dziękinohup php myscript.php > myscript.log &
Inną opcją jest użycie Upstart . Został pierwotnie opracowany dla Ubuntu (i jest domyślnie dostarczany z nim w pakiecie), ale ma być odpowiedni dla wszystkich dystrybucji Linuksa.
Podejście to jest podobne do Supervisord i daemontools , ponieważ automatycznie uruchamia demona przy starcie systemu i odradza się po zakończeniu skryptu.
Jak to ustawić:
Utwórz nowy plik skryptu pod adresem
/etc/init/myphpworker.conf
. Oto przykład:Uruchamianie i zatrzymywanie demona:
Sprawdź, czy Twój demon jest uruchomiony:
Dzięki
Wielkie podziękowania dla Kevina van Zonnevelda , od którego nauczyłem się tej techniki.
źródło
sudo service myphpworker start/stop/status
działa to tylko z usługami, które nie są/etc/init.d
usługami początkowymi. Wydaje się, że @ matt-sich odkrył poprawną składnię. Inną opcją jest użycie Gearman lub Resque, które umożliwiają przetwarzanie w tle i deamonizację.Dzięki nowemu systemowi możesz stworzyć usługę.
Musisz utworzyć plik lub dowiązania w
/etc/systemd/system/
, np. myphpdaemon.service i umieść zawartość taką jak ta, myphpdaemon będzie nazwą usługi:Będziesz mógł uruchomić, uzyskać status, zrestartować i zatrzymać usługi za pomocą polecenia
systemctl <start|status|restart|stop|enable> myphpdaemon
Skrypt PHP powinien mieć rodzaj „pętli”, aby kontynuować działanie.
Przykład pracy:
Jeśli twoja procedura PHP powinna być wykonywana raz w cyklu (jak diggest), możesz użyć powłoki lub skryptu bash do wywołania w pliku usługi systemd zamiast bezpośrednio PHP, na przykład:
Jeśli wybrałeś tę opcję, powinieneś zmienić KillMode na
mixed
procesy, zabić bash (main) i PHP (child).This method also is effective if you're facing a memory leak.
źródło
systemctl status <your_service_name> -l
wynik, to da ci wskazówkę, co się dzieje.Jeśli możesz - pobierz kopię Zaawansowanego programowania w środowisku UNIX . Cały rozdział 13 jest poświęcony programowaniu demonów. Przykłady są w C, ale wszystkie potrzebne funkcje mają opakowania w PHP (w zasadzie rozszerzenia pcntl i posix ).
W kilku słowach - pisanie demona (jest to możliwe tylko w systemach operacyjnych opartych na * nix - Windows korzysta z usług) wygląda tak:
umask(0)
aby zapobiec problemom z pozwoleniami.fork()
i wyprowadzić rodzica.setsid()
.SIGHUP
(zwykle jest to ignorowane lub używane do sygnalizowania demonowi ponownego załadowania konfiguracji) iSIGTERM
(aby nakazać procesowi prawidłowe zakończenie).fork()
ponownie i pozwól rodzicowi wyjść.chdir()
.fclose()
stdin
,stdout
Astderr
i nie pisać do nich. Poprawnym sposobem jest przekierowanie ich do jednego z nich/dev/null
lub do pliku, ale nie mogłem znaleźć sposobu, aby to zrobić w PHP. Po uruchomieniu demona jest to możliwe, aby przekierować je za pomocą powłoki (sam musisz się dowiedzieć, jak to zrobić, nie wiem :).Ponadto, ponieważ używasz PHP, uważaj na cykliczne odwołania, ponieważ garbage collector PHP, przed PHP 5.3, nie ma możliwości zbierania tych odwołań i proces będzie przeciekał pamięć, aż w końcu ulegnie awarii.
źródło
Uruchamiam wiele demonów PHP.
Zgadzam się z Tobą, że PHP nie jest najlepszym (a nawet dobrym) językiem do tego celu, ale demony współdzielą kod z komponentami internetowymi, więc ogólnie jest to dla nas dobre rozwiązanie.
Używamy do tego daemontools. Jest inteligentny, czysty i niezawodny. W rzeczywistości używamy go do uruchamiania wszystkich naszych demonów.
Możesz to sprawdzić pod adresem http://cr.yp.to/daemontools.html .
EDYCJA: krótka lista funkcji.
źródło
Możesz
nohup
zgodnie z sugestią Henrika.screen
i uruchamiaj swój program PHP jako zwykły proces wewnątrz tego. Daje to większą kontrolę niż używanienohup
.Poleciłbym najprostszą metodę (moim zdaniem ekran), a następnie, jeśli chcesz mieć więcej funkcji lub funkcjonalności, przejdź do bardziej złożonych metod.
źródło
Jest więcej niż jeden sposób rozwiązania tego problemu.
Nie znam szczegółów, ale być może jest inny sposób na uruchomienie procesu PHP. Na przykład, jeśli chcesz, aby kod był uruchamiany na podstawie zdarzeń w bazie danych SQL, możesz skonfigurować wyzwalacz do wykonania skryptu. W PostgreSQL jest to naprawdę łatwe: http://www.postgresql.org/docs/current/static/external-pl.html .
Szczerze mówiąc, myślę, że najlepiej jest stworzyć proces Damona za pomocą nohup. nohup pozwala na kontynuowanie wykonywania polecenia nawet po wylogowaniu użytkownika:
Jest jednak bardzo poważny problem. Jak powiedziałeś, menedżer pamięci PHP jest kompletnym śmieciem, został zbudowany przy założeniu, że skrypt jest wykonywany tylko przez kilka sekund, a potem istnieje. Twój skrypt PHP zacznie używać GIGABYTÓW pamięci już po kilku dniach. MUSISZ TAKŻE utworzyć skrypt cron, który będzie uruchamiany co 12, a może 24 godziny, który zabija i ponownie odradza twój skrypt php w następujący sposób:
Ale co, jeśli scenariusz był w trakcie pracy? Cóż, kill -3 to przerwanie, to to samo, co wykonanie ctrl + c w CLI. Twój skrypt php może przechwycić to przerwanie i wyjść z wdziękiem za pomocą biblioteki PHP pcntl: http://php.oregonstate.edu/manual/en/function.pcntl-signal.php
Oto przykład:
Ideą $ lock jest to, że skrypt PHP może otworzyć plik z fopen ("plik", "w") ;. Tylko jeden proces może mieć blokadę zapisu w pliku, więc używając tego możesz upewnić się, że działa tylko jedna kopia twojego skryptu PHP.
Powodzenia!
źródło
Kevin van Zonneveld napisał bardzo ładny, szczegółowy artykuł na ten temat , w swoim przykładzie wykorzystuje
System_Daemon
pakiet PEAR (ostatnia data wydania to 2009-09-02).źródło
Sprawdź https://github.com/shaneharter/PHP-Daemon
To jest zorientowana obiektowo biblioteka demonów. Ma wbudowaną obsługę takich rzeczy, jak rejestrowanie i odzyskiwanie po błędach, a także obsługuje tworzenie pracowników w tle.
źródło
Niedawno potrzebowałem rozwiązania wieloplatformowego (Windows, Mac i Linux), aby rozwiązać problem uruchamiania skryptów PHP jako demonów. Rozwiązałem problem, pisząc własne rozwiązanie oparte na C ++ i tworząc pliki binarne:
https://github.com/cubiclesoft/service-manager/
Pełne wsparcie dla Linuksa (przez sysvinit), ale także dla usług Windows NT i Mac OSX.
Jeśli potrzebujesz tylko Linuksa, kilka innych przedstawionych tutaj rozwiązań działa wystarczająco dobrze i, w zależności od smaku. Obecnie istnieje również wersja Upstart i systemd, która ma rozwiązania awaryjne dla skryptów sysvinit. Ale połowa sensu używania PHP polega na tym, że ma on charakter wieloplatformowy, więc kod napisany w tym języku ma całkiem spore szanse na działanie wszędzie tak, jak jest. Niedociągnięcia zaczynają się pojawiać, gdy pojawiają się pewne zewnętrzne natywne aspekty poziomu systemu operacyjnego, takie jak usługi systemowe, ale ten problem wystąpi w przypadku większości języków skryptowych.
Próba złapania sygnałów, jak ktoś zasugerował tutaj w przestrzeni użytkownika PHP, nie jest dobrym pomysłem. Przeczytaj
pcntl_signal()
uważnie dokumentację, a szybko przekonasz się, że PHP obsługuje sygnały przy użyciu raczej nieprzyjemnych metod (w szczególności „tików”), które żują kilka cykli na coś rzadko spotykanego w procesach (np. Sygnały). Obsługa sygnałów w PHP jest również ledwo dostępna na platformach POSIX, a obsługa różni się w zależności od wersji PHP. Początkowo brzmi to jak przyzwoite rozwiązanie, ale nie jest naprawdę przydatne.W miarę upływu czasu PHP coraz lepiej radzi sobie z problemami z wyciekiem pamięci. Nadal musisz być ostrożny (parser DOM XML wciąż przecieka), ale w dzisiejszych czasach rzadko widzę niekontrolowane procesy, a moduł śledzenia błędów PHP jest dość cichy w porównaniu do dawnych czasów.
źródło
Jak już wspominali inni, uruchomienie PHP jako demona jest dość łatwe i można to zrobić za pomocą jednej linii poleceń. Ale rzeczywisty problem polega na tym, że działa i zarządza nim. Miałem ten sam problem już jakiś czas temu i chociaż dostępnych jest już wiele rozwiązań, większość z nich ma wiele zależności lub są trudne w użyciu i nie nadają się do podstawowych zastosowań. Napisałem skrypt powłoki, który może zarządzać dowolnym procesem / aplikacją, w tym skryptami PHP CLI. Można go ustawić jako cronjob do uruchamiania aplikacji i będzie zawierać aplikację i nią zarządzać. Jeśli zostanie uruchomiony ponownie, na przykład za pomocą tego samego cronjob, sprawdza, czy aplikacja działa, czy nie, a jeśli tak, po prostu zamyka się i pozwala jej poprzedniej instancji kontynuować zarządzanie aplikacją.
Wgrałem go na github, nie krępuj się go używać: https://github.com/sinasalek/EasyDeamonizer
EasyDeamonizer
Po prostu czuwa nad aplikacją (uruchamianie, restart, logowanie, monitorowanie itp.). ogólny skrypt, aby upewnić się, że aplikacja działa poprawnie. Celowo używa nazwy procesu podczas wczytywania pliku pid / lock, aby zapobiec wszystkim jego efektom ubocznym i zachować jak najprostszy i możliwie najprostszy skrypt, dzięki czemu zawsze działa nawet po ponownym uruchomieniu EasyDaemonizer. cechy
źródło
Rozszerzając odpowiedź Emila Ivaova , możesz wykonać następujące czynności, aby zamknąć STDIN, STDOUT i STDERROR w php
Zasadniczo zamykasz standardowe strumienie, aby PHP nie miało gdzie pisać. Następujące
fopen
wywołania ustawią standardowe We / Wy na/dev/null
.Przeczytałem to z książki Roba Aleya - PHP poza siecią
źródło
Napisałem i wdrożyłem prostego demona php, kod jest tutaj
https://github.com/jmullee/PhpUnixDaemon
Cechy: zrzucanie uprawnień, obsługa sygnałów, logowanie
Użyłem go w module obsługi kolejki (przypadek użycia: wyzwolenie długiej operacji ze strony internetowej, bez czekania na generowanie strony przez php, tj. Uruchomienie operacji asynchronicznej) https://github.com/jmullee/PhpIPCMessageQueue
źródło
możesz sprawdzić pm2 tutaj: http://pm2.keymetrics.io/
utwórz plik ssh, taki jak worker.sh i umieść w swoim skrypcie php, którym będziesz się zajmować.
worker.sh
Demon start
Na zdrowie, to wszystko.
źródło