Cum să programați cu Yii2 Rularea serviciilor Cron

Ce veți crea

Dacă vă întrebați: "Ce este Yii?" verificați tutorialul meu anterior: Introducere în Cadrul Yii, care analizează beneficiile Yii și include o prezentare generală a ceea ce este nou în Yii 2.0, lansat în octombrie 2014.

În această programare cu seria Yii2, ghid direct cititorii în folosirea cadrului Yii2 pentru PHP. În tutorialul de astăzi, vă voi împărtăși cum să profitați de capacitatea consolei Yii de a rula cron de locuri de muncă.

În trecut, am folosit wget în cron-urile mele de lucru - o adresă URL accesibilă pe web îmi va executa sarcinile de fundal. Acest lucru a ridicat probleme de securitate și are unele probleme de performanță. În timp ce am abordat câteva modalități de atenuare a riscurilor în episoadele seriei de pornire privind securitatea, speram să trec la comenzi conduse de console. Și cu Yii2 este destul de simplă.

Pentru exemplul de astăzi, voi demonstra comenzile cron bazate pe console pe site-ul meu Twixxr pe care l-am descris în acest episod Twitter API. Datorită limitelor de rată și a problemelor legate de gestionarea performanței, API-ul Twitter este foarte dependent de sarcini eficiente și fiabile ale cron. Deci este un exemplu excelent de a împărtăși cu dvs..

Înainte de a începe, voi reitera: întotdeauna mă apreciez ideile și feedback-ul. Dacă aveți o sugestie de întrebare sau subiect, vă rugăm să postați gândurile în comentariile de mai jos. Puteți să mă contactați și pe Twitter @reifman direct.

Ce este Cron?

Wikipedia descrie cron ca "un programator de timp bazat pe timp în sistemele de operare de tip computer Unix." Și asta este destul de precis. Practic, cron rulează toate sarcinile de fundal de care avem nevoie pentru a rula serviciile web, de la gestionarea jurnalului și copierea de rezervă la cererile API la curățarea bazei de date.

Pentru a vedea lucrările cron existente pe un server, de obicei tastați sudo crontab -l și vezi ceva de genul:

# Editați acest fișier pentru a introduce sarcini care trebuie executate de cron. # # Fiecare sarcină pentru a rula trebuie să fie definită printr-o singură linie # indicând cu câmpuri diferite atunci când sarcina va fi rulată # și ce comandă pentru a rula pentru sarcină # # Pentru a defini timpul în care puteți furniza valori concrete pentru # minute (m ), ora (h), ziua lunii (dom), luna (mon), # și ziua săptămânii (dow) sau folosiți "*" în aceste câmpuri. bazată pe noțiunea de daemon a sistemului cron și a zonelor de timp și de fus orar. # # Ieșirea joburilor crontab (inclusiv erorile) este trimisă prin # e-mail către utilizatorul în care aparține fișierul crontab (dacă nu este redirecționat). # # De exemplu, puteți rula o copie de rezervă a tuturor conturilor dvs. de utilizator # la ora 5 am în fiecare săptămână cu: # 0 5 * * 1 tar -zcf /var/backups/home.tgz / home / # # Pentru mai multe informații, consultați paginile de manual ale crontab (5) și cron (8) # # mh dom mon dow comanda * / 3 * * * * wget -O / dev / null http://meetingplanner.io/daemon/frequent * / 15 * * wget -O / dev / null http://meetingplanner.io/daemon/quarter 0 * * * * wget -O / dev / null http://meetingplanner.io/daemon/hourly 15 1 * * * wget -O / dev / null http://meetingplanner.io/daemon/overnight 40 2 * * * / usr / sbin / automysqlbackup 15 3 * * 5 wget -O / dev / null http://meetingplanner.io/daemon/weekly 30 2 * * 1 / opt / letsencrypt / letsencrypt-auto reînnoi >> /var/log/le-renew.log

Partea din stânga specifică activarea acestor sarcini la fiecare 3 sau 15 minute sau zilnic la miezul nopții etc., iar partea dreaptă este scriptul pentru a rula. Vezi si Programarea sarcinilor cu Cron Jobs (Envato Tuts +).

Observați cum scriptul Let's Encrypt este o comandă unică a consolei. Se execută din linia de comandă de pe serverul nostru. Cu toate acestea, toate sarcinile mele Planificator de întâlniri de mai sus rulează prin intermediul wget. Aceasta se comportă ca și cum un robot se afla într-un browser web, la un moment dat, executând cereri împotriva aplicației noastre web care îndeplinește sarcini de fundal.

În plus față de cheltuielile generale pe care le cere o solicitare web externă și limitările de timp pentru scripturile de pe servere, trebuie să vă asigurați aceste puncte de acces. Iată un exemplu despre modul în care reușește Planificatorul de întâlniri:

// numai activitățile cron și administratorii pot rula funcțiile publice ale acțiunii publice, înainte de acțiune ($ action) // codul dvs. personalizat aici, dacă doriți ca codul să ruleze înainte de filtrele de acțiune, // care sunt declanșate în [[EVENT_BEFORE_ACTION]] eveniment, de exemplu PageCache sau AccessControl dacă (! Parent :: beforeAction ($ action)) return false;  // alt cod personalizat aici dacă (($ _SERVER ['REMOTE_ADDR'] == $ _SERVER ['SERVER_ADDR']) || (! \ Yii :: $ app-> user-> isGuest && \ common \ models \ User :: findOne (Yii: $ app-> user-> getId ()) -> isAdmin ())) return true;  return false; // sau false pentru a nu executa acțiunea

Verifică faptul că utilizatorul este fie logat ca administrator sau rulează local pe server la o adresă IP identică de Internet.

Implementarea comenzilor Cron bazate pe console

Alex Makarov, unul dintre principalii voluntari din spatele dezvoltării Cadrului Yii, a fost de ajutor în a răspunde la întrebări pentru mine, așa cum scriu în mod regulat despre cadrul pentru Envato Tuts +. După ce am citit episodul meu de securitate, el a întrebat de ce nu foloseam capacitatea consolei Yii2 inerente pentru slujbe cron. Practic, nu știam despre asta.

Așa cum am avut un /frontend/controllers/DaemonController.php, am creat un /console/controllers/DaemonController.php. Pentru acest tutorial, voi face acest lucru pentru serviciul web mai mic și mai simplu, Twixxr.

Sunt obișnuit să folosesc consola pentru a rula migrarea bazei de date (de ex. ./ yii migrați / urcați 7), dar asta e tot. Am vrut să încerc să-l folosesc pentru activități de bază.

Așa cum am scris despre un tutorial mai devreme, site-ul meu nou-născut Twixxr necesită procese extinse de fundal pentru a rota în mod regulat apelurile API pentru toate solicitările utilizatorilor de a se fi afiliat la conturile Twitter importante deținute de femei. 

Iată cum arată pagina de pornire:

Așa că am crezut că Twixxr ar face un testament excelent pentru a rula un controler cron bazat pe console.

Noua DaemonController.php

Iată nucleul noului meu DaemonController.php bazat pe console:

proces ($ TIME_START); $ time_end = microtime (adevărat); ecou "Prelucrare pentru". ($ time_end- $ time_start). ' secunde;  funcția publică funcțiaQuarter () // a sunat la fiecare cincisprezece minute $ x = new \ frontend \ models \ Twixxr (); $ X-> loadProfiles ();  funcția publică funcțieHurly () // la fiecare oră $ current_hour = data ('G'); dacă $ current_hour% 4) // la fiecare patru ore dacă ($ curent_hour% 6) / la șase ore

Observați că este destul de identică cu structura controlerului meu bazat pe front, dar este inaccesibil pentru web deoarece este în arborele / consola. Niciun site de pe serverul Apache nu este configurat pentru a naviga în această zonă.

Deci, în exemplul de mai sus, actionFrequent () va fi chemat la fiecare două până la trei minute. Ea procesează un alt set de solicitări de prietenie Twixxr. Pe de altă parte, actionQuarter () este apelată la fiecare 15 minute și actualizează informațiile despre profil pentru conturile de navigare. Să vedem cum funcționează programarea în fișierul cron.

Fișierul nou Crontab

În esență, în fișierul meu crontab, înlocuiesc wget cu un script direct Linux așa cum este arătat mai sus pentru Let's Encrypt renewals.

Scrieți sudo crontab -e pentru a edita sau -L pentru a lista conținutul său. Iată fișierul meu Twixxr cron:

$ sudo crontab -l # mh dom mon dow comanda * / 3 * * * * / var / www / twixxr / yii daemon / frecvente * / 15 * * * * / var / www / twixxr / yii daemon / trimestru 0 * * * / var / www / twixxr / yii daemon / oră 15 1 * * * / var / www / twixxr / yii daemon / peste noapte 15 3 * * 5 / var / www / twixxr / yii daemon / * / usr / sbin / automysqlbackup 30 2 * * 1 / usr / bin / letsencrypt reinnoi >> /var/log/le-renew.log

E destul de simplu. Partea stângă a lui / var / www / twixxr / yii daemon / frecvente este calea în care trăiește interpretul yii, iar partea dreaptă este controlerul consolei și metoda de apel.

Totul a funcționat destul de bine. Nu am schimbat Planificatorul de Întâlniri peste încă, deoarece vreau să fac mai multe teste. Atunci când sarcinile de fundal se sparg, este dificil de știut și dificil de depanat (deși logarea erorilor Sentry ajută foarte mult).

Probleme de luat în considerare

Un element pe care l-am întâlnit este că spațiul de nume al consolei este diferit de spațiul de nume din față-așa că, de exemplu, componenta SiteHelper.php pe care am creat-o în tutorialul meu, care a descris mai multe site-uri dintr-o singură bază de cod, a eșuat când am invocat aceasta. Eliminarea a funcționat, dar a trebuit să rulez teste pentru a vă asigura că codul fundal de bază a funcționat în continuare. Cu toate acestea, cea mai mare parte a trecerii a avut loc fără probleme.

La fel ca orice altă modificare a codului, testați și monitorizați cu atenție.

Ce urmeaza

Privind în perspectivă, voi explora construirea API-urilor REST în cadrul Yii2 Framework, care se bazează, în mod coincidențial, pe crearea unui sub-copac distinct, cum ar fi copacul de consolă, dar pentru API-urile externe. Desigur, acest lucru aduce probleme complexe de autentificare și securitate ... deci va fi distractiv să le explorați cu dvs. Mă voi uita la API din mai multe unghiuri. De fapt sunt destul de încântat de asta. 

Urmăriți tutorialele viitoare din programul meu de programare cu seria Yii2, deoarece continuam să scufundăm în diferite aspecte ale cadrului. Vă rugăm să explorați, de asemenea, Building Your Startup cu seria PHP, care documentează procesul de construire Simple Planner și Meeting Planner.

Dacă doriți să știți când vine următorul tutorial Yii2, urmați-mă @reifman pe Twitter sau verificați pagina instructorului meu pentru actualizări. 

Link-uri conexe

  • Yii2 Developer Exchange, site-ul meu de resurse Yii2
  • Sarcini de planificare cu Cron Jobs (Envato Tuts +)
  • Cum se implementează cron în Yii2 (Documentația Yii)
  • Twixxr, serviciul web eșantion menționat în document
Cod