Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][CLI] Zabezpieczenie przed uruchomieniem parokrotnie skryptu
Forum PHP.pl > Forum > Przedszkole
Octobus
Witam,

mam skrypt php ktory musi na okraglo wykonywac petle i obrabiac dane (glownie laczac sie z innymi serwerami: api, scrapowanie danych, zewnetrzne bazy danych, etc). Uruchomiony jest w cronie co minute, jak obrobi pewna ilosc danych zapisuje status do bazy i sie wylacza - i tak w kolko. Problem w tym ze czasem te skrypty wykonuja sie w pare sekund a czasem w pare godzin wiec musze zapobiegac przed tym zeby cronjob nie uruchomil kolejnych instancji jezeli jedna juz chodzi. Skrypt jest uruchamiany w cronjob i wykonywany z poziomu ssh, przy kazdym wykonaniu sprawdzam czy tego skryptu nie ma juz na liscie procesow:

  1. $ilosc_uruchomien = 0;
  2. $procesy = explode(PHP_EOL, shell_exec('ps -C php -f'));
  3. $needle = $_SERVER['SCRIPT_FILENAME'];
  4. foreach($procesy as $proces){
  5. if (strpos($proces, 'php '.$needle)!==false){
  6. ++$ilosc_uruchomien;
  7. }
  8. }
  9. if($ilosc_uruchomien > 1) die();


problem z tym rozwiazaniem jest taki ze czasem serwer nie zwraca takiej odpowiedzi jaka powinien (w shel_exec) np. zwraca informacje ze nie mozna bylo wykonac komendy z jakiegos powodu lub jakas inna wartosc i rozwiazanie to jest nie idealne a ja widze po procesach ze skrypt jest uruchamiany czasem nawet 5 razy na serwerze.
Widzialem w projektach open source ze rozwiazuja to za pomoca lock_file, blokuja plik na poczatku wykonywania skryptu a zwalniaja na koncu. Skrypt na pewno sie nie powieli ale problem w tym ze takich skryptow mam sporo na roznych serwerach i czesto zwracaja bledy (np. przez przeciazony serwer do ktorego sie lacze, pad bazy danych, etc) ciezko jest przewidzec wszystkie ewentualnosci i ciagle musialbym je odblokowywac recznie jezeli skrypt by nie doszedl do konca.

Moze zetkneliscie sie z takim problemem albo wiecie jak to lepiej rozwiazac ?
nospor
Ja to rozwiazywalem przez tworzenie dodatkowego pliku. Skrypt sie odpalal, tworzyl plik, po skonczeniu kasowal plik. Gdy startowal skrypt znowu to patrzyl czy jest plik i jak byl to nie robil nic wiecej. oczywiscie zachodzily sytuacje jak napisales, ze skrypt mogl sie wywalic w srodku bo cos tam i nie skasowac pliku. Na te okolicznosc dodalem poprostu waznosc pliku. Jak byl stworzony ostatni raz za dlugo temu to uwazalem ze skrypt moze sie odpalic bo plik jest juz niewazny. Jakos dzialalo i to calkiem niezle.
Jesli zas uwazasz, ze twoj skrypt moze pracowac nawet kilka godzin, to aktualizuj ten tworzony plik rowniez w czasie pracy skryptu by bylo wiadomo ze skrypt ciagle chodzi.
sabat24
U mnie wygląda to tak, że do tego pliku lock zapisuję ID procesu. Dzięku temu nawet jeśli plik istnieje, pobieram ID procesu, sprawdzam, czy taki proces już występuje. Jeśli nie występuje, to znaczy, że serwer zabił go i skrypt nie skończył się wykonywać normalnie. Wtedy zazwyczaj odpalam ponownie ten proces i aktualizauję ID. Jeśli proces ciągle istnieje to patrzę na datę modyfikacji pliku i albo zabijam sam taki proces, jeśli uznam, że czas jest dziwnie długi, czekam na zabicie i odpalam ponownie właściwy skrypt albo zostawiam go i nie odpalam kolejnego.
Możesz też napisać własnego, prostego demona w PHP, który będzie kontrolował wszystkie procesy na danym serwerze zamiast crona.
batman
Jeśli musisz korzystać z crona, lock file jest tutaj najlepszym wyjściem. Jeśli jednak cron nie jest „must have”, zastanów się nad wykorzystaniem kolejek lub mechanizmu pub/sub.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.