Timp rulare script

Salutare la toata lumea si felicitari Ionut pentru website!

Primul post il deschid cu o problema pe care o am cu timpul de rulare a unui script php:

Am un script pe care il apelez prin cron (sau manual cand este cazul) care se conecteaza la un webservice si care trebuie sa imi downloadeze imaginile unor hoteluri. Problema este ca am o lista destul de mare de hoteluri si fiecare request la WS dureaza ceva, ceea ce face ca scriptul sa imi intoarca eroarea 500 dupa un anumit timp.

Cei de la hosting mi-au marit max_execution_time, dar nu am rezolvat nimic, tot imi returneaza 500.

Any ideas?

Multumesc.

Salut, daca scriptul e in regula, insa doar are nevoie de mult timp, execution time ar fi cheia.
In general, la cli/cron setezi timpul la 0 (infinit).

Alta solutie ar fi mai multe job-uri.

Cum il apelezi din cron? cli gen php fisier.php sau curl url ?

Dacă trebuie să faci constant treaba asta, probabil ai nevoie de ceva de genul ăsta.

O altă soluție ar fi o coloană sql cu last_fetch (sau ceva de genul) iar din cron execuți un script bash din care apelezi scriptul PHP cu care faci fetch doar la câteva elemente, actualizezi DB, treci la următoarele.

@oriceon a avut o problemă asemănătoare; max_execution_time era setat dar nu și pentru cazurile în care rulai din consolă (caz în care era luat în considerare alt php.ini)

Incep cu un sfat generalist. Treci pe un VPS. Pentru $5 pe luna cat e un droplet de la DigitalOcean nu merita sa iti bati capul cu restrictiile care vin impreuna cu shared hosting.

Acum, nu cunosc suficiente detalii cat sa iti dau sugesti tehnice, asa ca o sa vorbesc pur teoretic. Cand ai restrictii care se aplica unei executii a unui script, fa tot posibilul sa spargi executia in mai multe. Spre exemplu, zici ca te conectezi la un WS si apoi downloadezi niste imagini. Nu poti cumva ca atunci cand te conectezi la WS doar sa iei lista de imagini, sa o bagi intr-un queue, iar download-ul efectiv sa il faci in alt cronjob, care ruleaza in paralel pe propriul schedule? Eu am aplicat solutia asta cu succes in trecut.

La fel si cu numarul de hoteluri. Daca per executie depasesti time limit-ul, gandeste-te la o metoda de a prelua in grupe de x hoteluri.

2 Likes

@msd Scriptul este ok, chiar daca imi browser imi arata internal serv error, el continua sa faca update-ul pana la capat.

@neamtua Cron am incercat cu wget sau php …

@victorstanciu este pe un vps in ro

stai ca nu inteleg… adica tu chemi un cronjob in browser? pai problema nu-i de la cronjob, problema-i de la scriptul care cheama cronjob-ul. ala-ti da time out.
eu din ce stiam max_execution_time nu se aplica la scripturi rulate in linia de comanda. <- sa ma corecteze cineva daca gresesc

Daca il rulezi cu wget atunci trece prin serverul HTTP (Apache probabil), caz in care am parerea ca si ala trebuie configurat sa nu ucida conexiunea. Faptul ca da 500 ma face sa cred ca PHP ruleaza in mod FastCGI, care necesita propria lui configuratie pentru timeout. E o bataie de cap care nu merita, CLI is the way to go pentru cronjobs.

Acum, tu spui ca l-ai rulat si cu PHP direct, dar atunci de unde eroarea 500, care e error code de HTTP? Ar trebui ca rulat cu PHP CLI sa mearga fara probleme. Atata timp cat nu depasesti resursele VPS-ului, bineinteles.

In alta ordine de idei, orice eroare 500 ar trebui sa aiba o linie corespunzatoare in error log-ul de Apache. Baga un ochi pe acolo si zi-ne si noua ce spune.

Cel mai probabil te lovesti de o alta limitare si anume memoria maxima pe care o poate consuma un script php.
Monitorizeaza consumul de memorie si vezi care e limita maxima (linia de comanda, top etc…). In general cei de la hosting nu o sa te lase cu un consum de memorie peste 128 MB ca asta produce probleme la celelalte site-uri.

Va trebui sa-l spargi sa ruleze de mai multe ori, separat, nu intr-un singur pas.
Pentru viteza recomand descarcarea in paralel a imaginilor, e.g. https://github.com/kriswallsmith/spork

@pghoratiu A zis ca are VPS, deci memoria consumata e in limita disponibila.

Daca il rulezi din CLI atunci nu ai max execution time, cel mai probabil, cum s-a spus pe aici, ramai fara memorie.

Incearca sa maresti din script memoria alocata cu linia ini_set('memory_limit', '256M')

Alte variante ar fi sa poti filtra datele luate si sa le iei pe bucati in mai multe procese.

cand php-ul ramane fara memorie intoarce un Fatal Error care il si scuipa in output, nu cred ca e asta.

Din moment ce a zis ca ii ruleaza totusi scriptul pana la capat dar ii da eroare 500, cel mai probabil ii taie conexiunea serverul web. Ar trebui sa il ruleze din cli.

Asa ar fi normal, dar nu inseamna ca nu se poate suprascrie.

din ce spune omu el ruleaza scriptul din browser. adica trece prin serverul web.

Ruleaza cron normal, iar in browser doar cand are nevoie. Dar poate ne lamureste el mai exact.

acu n-a spus mai departe, da eroare si cand il releaza din cl sau numai cand e din browser

Daca eroarea 500 o primesti de la serverul de pe care descarci imaginile cel mai probabil e vorba de:

  • incarcarea prea mare pe server, introdu timeout intre cereri
  • probleme temporare - incearca un mecanism de retry dupa 5,15, 60 sec …
    Poate fi cauzat si de un mecanism de rate limiting cazul in care timeout intre cereri ar trebui sa rezolve problema.

Pe scurt trebuie sa identifici de la ce este acea eroare. Erorile nu pot fi ignorate mai ales cand “ceva” nu merge. Vezi ce nu merge.

Why u not write no tests?

Eu as scrie un test case care sa aibe un load mare apoi as pune linii de debug in cod si as salva Error stack trace.

500 internal server error, nu e prea util daca nu stii ce impiedica executia. Creaza o functie debug(…) in care salvezi intr-un fisier step by step task-urile care le executa codul. Ulterior o sa-ti dai seama de unde provine eroarea si cauti solutii pt. problema aia.

Daca nu te descurci te putem ajuta sa faci debugging, din ce observ ai pierdut deja ceva timp discutant despre posibile probleme, hai sa incercam sa gasim problema in cod. Makes sense?

@msd Scriptul este pus in cron. Dar daca am nevoie de update urgent la imagini am lasat posibilitatea de a-l rula si din browser.

Cron-ul imi trimite mail cu :

HTTP request sent, awaiting response... 500 Internal Server Error
2014-08-02 09:01:31 ERROR 500: Internal Server Error.

Clientul are un fel de vps semi-managed, si le-am trimis si lor un mail in care le-am povestit problema. Raspunsul lor a fost : posibil ca scriptul sa lucreze prea intens cu db-ul sau disk-ul si mi-au sugerat sa incerc un sleep in loop - care evident ca nu a rezolvat nimic.

O sa incerc sa fac un debug, sa testez si din cli (nu sunt foarte familiarizat…) sa vedem ce rezolv.

Multumesc pentru raspunsurile/indicatiile de pana acum.