Come programmare con Yii2 esecuzione di servizi cron

Cosa starai creando

Se stai chiedendo "Cos'è Yii?" guarda il mio tutorial precedente: Introduzione al framework Yii, che rivede i vantaggi di Yii e include una panoramica delle novità in Yii 2.0, rilasciata nell'ottobre 2014.

In questa serie di programmazione con Yii2, guido i lettori all'uso di Yii2 Framework per PHP. Nel tutorial di oggi, condividerò con voi come sfruttare la capacità della console di Yii per eseguire lavori cron.

In passato, ho usato wget nei miei lavori cron: un URL accessibile al Web avrebbe eseguito le mie attività in background. Ciò ha sollevato problemi di sicurezza e presenta alcuni problemi di prestazioni. Mentre ho affrontato alcuni modi per mitigare i rischi negli episodi di sicurezza della nostra serie di startup, avevo sperato di passare ai comandi guidati dalla console. E con Yii2 è abbastanza semplice.

Per l'esempio di oggi, mostrerò i comandi cron basati su console sul mio sito Twixxr che ho descritto in questo episodio dell'API di Twitter. A causa dei limiti di velocità e dei problemi di gestione delle prestazioni, l'API di Twitter dipende molto da attività cron efficienti ed affidabili. Quindi è un ottimo esempio da condividere con te.

Prima di iniziare, ripeterò: apprezzo sempre le tue idee e i tuoi feedback. Se hai una domanda o un suggerimento sull'argomento, per favore pubblica i tuoi pensieri nei commenti qui sotto. Puoi anche raggiungermi su Twitter direttamente @reifman.

Che cos'è Cron?

Wikipedia descrive cron come "un programmatore di lavoro basato sul tempo in sistemi operativi per computer come Unix". E questo è abbastanza preciso. Fondamentalmente, cron esegue tutte le attività in background di cui abbiamo bisogno per eseguire servizi Web, dalla gestione dei log e backup alle richieste API alla pulizia del database.

Per vedere i tuoi cron job esistenti su un server, di solito scrivi sudo crontab -l e vedere qualcosa di simile a questo:

# Modifica questo file per introdurre le attività che devono essere eseguite da cron. # # Ogni attività da eseguire deve essere definita attraverso una singola riga # che indica con campi diversi quando l'attività verrà eseguita # e quale comando eseguire per l'attività # # Per definire l'ora è possibile fornire valori concreti per # minuto (m ), ora (h), giorno del mese (dom), mese (mon), # e giorno della settimana (dow) o usare '*' in questi campi (per 'qualsiasi'). # # Si noti che le attività verranno avviate basato sulla nozione di tempo e fusi orari del demone # del sistema di cron. # # L'output dei lavori crontab (inclusi gli errori) viene inviato tramite # email all'utente a cui appartiene il file crontab (a meno che non sia reindirizzato). # # Ad esempio, è possibile eseguire un backup di tutti i tuoi account utente # alle 5 del mattino ogni settimana con: # 0 5 * * 1 tar -zcf /var/backups/home.tgz / home / # # Per ulteriori informazioni vedere il pagine di manuale di crontab (5) e cron (8) # # mh comando dom dow * / 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 renew >> /var/log/le-renew.log

Il lato sinistro specifica di attivare queste attività ogni 3 o 15 minuti o ogni giorno a mezzanotte, ecc. E il lato destro è lo script da eseguire. Guarda anche Pianificazione delle attività con i lavori Cron (Envato Tuts +).

Si noti come lo script Let's Encrypt sia un comando console univoco. Funziona dalla riga di comando sul nostro server. Tuttavia, tutte le mie attività di Meeting Planner sono eseguite tramite wget. Ciò si comporta come se un robot si trovasse in un browser Web in un momento specifico in cui venivano eseguite richieste contro la nostra applicazione Web che eseguiva attività in background.

Oltre al sovraccarico che richiede una richiesta Web esterna e limitazioni di timeout sugli script sui server, è necessario proteggere questi punti di accesso. Ecco un esempio di come funziona Meeting Planner:

// solo i lavori cron e gli amministratori possono eseguire le azioni pubbliche di questo controllore funzione beforeAction ($ action) // qui il tuo codice personalizzato, se vuoi che il codice venga eseguito prima dei filtri azione, // che sono attivati ​​su [[EVENT_BEFORE_ACTION]] evento, ad es PageCache o AccessControl if (! Parent :: beforeAction ($ action)) return false;  // altro codice personalizzato qui if (($ _SERVER ['REMOTE_ADDR'] == $ _SERVER ['SERVER_ADDR']) || (! \ Yii :: $ app-> utente-> isGuest && \ common \ models \ User :: findOne (Yii :: $ app-> user-> getId ()) -> isAdmin ())) return true;  return false; // o false per non eseguire l'azione

Verifica che l'utente abbia effettuato l'accesso come amministratore o eseguito localmente sul server a un indirizzo IP Internet identico.

Implementazione dei comandi di Cron basati su console

Alex Makarov, uno dei principali volontari dietro lo sviluppo di Yii Framework, mi ha aiutato a rispondere alle domande mentre scrivevo regolarmente sul framework di Envato Tuts +. Dopo aver letto il mio episodio di sicurezza, mi ha chiesto perché non stavo usando la capacità della console di Yii2 per i lavori di cron. Fondamentalmente, non lo sapevo.

Proprio come ho avuto un /frontend/controllers/DaemonController.php, ho creato un /console/controllers/DaemonController.php. Per questo tutorial, lo farò per il più piccolo, più semplice servizio web Twixxr.

Sono abituato ad usare la console per eseguire migrazioni di database (ad es. ./ yii migrate / up 7), ma questo è tutto. Ero impaziente di provare a usarlo per le attività in background.

Come ho scritto in un precedente tutorial, il mio sito appena nato Twixxr richiede lunghi processi in background per ruotare regolarmente le chiamate API per tutte le richieste degli utenti di fare amicizia con account di Twitter influenti detenuti dalle donne. 

Ecco come appare la pagina iniziale:

Quindi pensavo che Twixxr sarebbe diventato un ottimo banco di prova per l'esecuzione di un controller cron basato su console.

The New DaemonController.php

Ecco il nocciolo del mio nuovo DaemonController.php basato su console:

processo ($ TIME_START); $ time_end = microtime (true); echo 'In elaborazione per'. ($ time_end- $ time_start). ' secondi;  public function actionQuarter () // chiamato ogni quindici minuti $ x = new \ frontend \ models \ Twixxr (); $ X-> loadProfiles ();  public function actionHourly () // ogni ora $ current_hour = date ('G'); if ($ current_hour% 4) // ogni quattro ore if ($ current_hour% 6) // ogni sei ore

Si noti che è abbastanza identico alla struttura del mio controller basato su front-end, ma è sicuramente inaccessibile al web perché è nella struttura / console. Nessun sito Web del server Apache è configurato per esplorare quest'area.

Quindi, nell'esempio sopra, actionFrequent () sarà chiamato ogni due o tre minuti. Elabora un'altra serie di richieste di amicizia Twixxr. D'altro canto, actionQuarter () viene chiamato ogni 15 minuti e aggiorna le informazioni del profilo per gli account di navigazione. Diamo un'occhiata a come funziona la pianificazione nel file cron.

Il nuovo file di Crontab

Essenzialmente, nel mio file crontab, sostituisco wget con uno script Linux diretto come mostrato sopra per Let's Encrypt renewals.

Tu digiti sudo crontab -e modificare o -l per elencarne il contenuto. Ecco il mio file cron di Twixxr:

$ sudo crontab -l # mh comando dom dow * / 3 * * * * / var / www / twixxr / yii daemon / frequente * / 15 * * * * / var / www / twixxr / yii daemon / quarter 0 * * * * / var / www / twixxr / yii daemon / ora 15 1 * * * / var / www / twixxr / yii daemon / overnight 15 3 * * 5 / var / www / twixxr / yii daemon / settimanale # 40 2 * * * / usr / sbin / automysqlbackup 30 2 * * 1 / usr / bin / letsencrypt rinnova >> /var/log/le-renew.log

È piuttosto semplice Il lato sinistro di / var / www / twixxr / yii daemon / frequente è il percorso in cui vive l'interprete yii e il lato destro è il controller della console e il metodo da chiamare.

Tutto ha funzionato abbastanza bene passando. Non ho ancora modificato Meeting Planner perché voglio fare ancora più test. Quando le attività in background si interrompono, è difficile conoscerle e è difficile eseguirne il debug (anche se la registrazione degli errori di Sentry aiuta molto).

Problemi da considerare

Un elemento a cui mi sono imbattuto è che lo spazio dei nomi della console è distinto dal namespace front-end, quindi, ad esempio, il componente SiteHelper.php che ho impostato nel mio tutorial, che descriveva l'esecuzione di più siti da una singola base di codice, non è riuscito quando ho richiamato esso. Rimozione ha funzionato, ma avevo bisogno di eseguire test per assicurarsi che il codice di sfondo sottostante funzionasse ancora. Tuttavia, per lo più il passaggio è andato liscio.

Come per qualsiasi altro cambiamento di codice, testare e monitorare a fondo.

Qual'è il prossimo

In prospettiva, esplorerò la costruzione di API REST all'interno di Yii2 Framework, che si basa per caso sulla creazione di un sottoalbero distinto come la struttura della console ma per le API esterne. Ovviamente, questo solleva complessi problemi di autenticazione e sicurezza ... quindi sarà divertente esplorarli con voi. Vedrò le API da diversi punti di vista. Sono davvero piuttosto entusiasta di questo. 

Guarda le prossime esercitazioni nella mia serie Programming with Yii2 mentre continuo a immergermi nei diversi aspetti del framework. Si prega di esplorare anche la creazione della propria startup con la serie PHP, che documenta il processo di costruzione di Simple Planner e Meeting Planner.

Se vuoi sapere quando arriverà il prossimo tutorial di Yii2, seguimi @reifman su Twitter o controlla la mia pagina per gli istruttori per gli aggiornamenti. 

Link correlati

  • Yii2 Developer Exchange, il mio sito di risorse Yii2
  • Pianificazione delle attività con lavori Cron (Envato Tuts +)
  • Come implementare cron in Yii2 (documentazione Yii)
  • Twixxr, il servizio web di esempio menzionato all'interno