Wenn Sie fragen: "Was ist Yii?" Schauen Sie sich mein früheres Tutorial an: Einführung in das Yii-Framework, Hier werden die Vorteile von Yii beschrieben und ein Überblick über die Neuerungen in Yii 2.0 (Oktober 2014) gegeben.
In dieser Programmierserie mit Yii2 leite ich die Leser beim Einsatz des Yii2-Frameworks für PHP. Im heutigen Tutorial werde ich Ihnen mitteilen, wie Sie die Konsolen-Kapazität von Yii nutzen können, um Cron-Jobs auszuführen.
In der Vergangenheit habe ich wget in meinen cron-Jobs verwendet - eine Web-zugängliche URL würde meine Hintergrundaufgaben ausführen. Dies führte zu Sicherheitsproblemen und hatte einige Leistungsprobleme. Während ich in den Sicherheits-Episoden unserer Startreihe einige Möglichkeiten zur Risikominimierung angesprochen habe, hatte ich gehofft, auf konsolengesteuerte Befehle umzusteigen. Und mit Yii2 ist das ziemlich einfach.
Für das heutige Beispiel werde ich auf meiner Twixxr-Site konsolenbasierte cron-Befehle demonstrieren, die ich in dieser Twitter-API-Episode beschrieben habe. Aufgrund von Ratenbegrenzungen und Problemen beim Leistungsmanagement ist die Twitter-API in hohem Maße von effizienten, zuverlässigen Cron-Aufgaben abhängig. Es ist also ein großartiges Beispiel, um es mit Ihnen zu teilen.
Bevor ich anfange, möchte ich noch einmal sagen: Ich freue mich immer über Ihre Ideen und Ihr Feedback. Wenn Sie einen Fragen- oder Themenvorschlag haben, schreiben Sie bitte Ihre Kommentare in die nachstehenden Kommentare. Sie können mich auch direkt auf Twitter @reifman erreichen.
Wikipedia beschreibt cron als "zeitbasierten Job-Scheduler in Unix-ähnlichen Computer-Betriebssystemen". Und das ist ziemlich genau. Grundsätzlich führt cron alle Hintergrundaufgaben aus, die wir zum Ausführen von Web-Services benötigen, von der Protokollverwaltung und der Sicherung über API-Anforderungen bis zur Datenbankbereinigung.
Um Ihre vorhandenen Cron-Jobs auf einem Server anzuzeigen, geben Sie normalerweise Folgendes ein Sudo Crontab -l
und so etwas sehen:
# Bearbeiten Sie diese Datei, um die von cron auszuführenden Aufgaben einzuführen. # # Jede auszuführende Aufgabe muss durch eine einzige Zeile definiert werden #, die mit verschiedenen Feldern angibt, wann die Aufgabe ausgeführt wird # und welcher Befehl für die Aufgabe ausgeführt werden soll # # Um die Zeit festzulegen, können Sie konkrete Werte für # Minute angeben (m ), Stunde (h), Tag des Monats (dom), Monat (Mo), # und Wochentag (Dow) oder verwenden Sie '*' in diesen Feldern (für 'beliebig'). # # Beachten Sie, dass Aufgaben gestartet werden basierend auf dem System des crons # daemons von zeit und zeitzonen. # # Die Ausgabe der Crontab-Jobs (einschließlich Fehler) wird über # email an den Benutzer gesendet, zu dem die Crontab-Datei gehört (sofern nicht umgeleitet). Sie können z. B. jede Woche um 5 Uhr eine Sicherungskopie aller Ihrer Benutzerkonten erstellen: # 0 5 * * 1 tar -zcf /var/backups/home.tgz / home / # # Weitere Informationen finden Sie im Handbuchseiten von crontab (5) und cron (8) # # mh dom mon dow Befehl * / 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-automatische Erneuerung >> /var/log/le-renew.log
Die linke Seite gibt an, dass diese Aufgaben alle 3 oder 15 Minuten oder täglich um Mitternacht usw. aktiviert werden sollen, und die rechte Seite ist das auszuführende Skript. Siehe auch Planen von Aufgaben mit Cron-Jobs (Envato Tuts +).
Beachten Sie, dass das Let's Encrypt-Skript ein eindeutiger Konsolenbefehl ist. Es läuft von der Befehlszeile auf unserem Server. Alle meine oben genannten Meeting Planner-Aufgaben werden jedoch über wget ausgeführt. Dies wirkt so, als ob ein Roboter zu einem bestimmten Zeitpunkt in einem Webbrowser war und Anforderungen an unsere Webanwendung ausführte, die Hintergrundaufgaben ausführen.
Neben dem Overhead, den eine externe Webanforderung erfordert, und Einschränkungen für das Zeitlimit für Skripts auf Servern, müssen Sie diese Zugriffspunkte sichern. Hier ein Beispiel, wie Meeting Planner dies tut:
// Nur Cronjobs und Admins können die Aktionen public dieser Funktion vor der Aktion ausführen ($ action) // hier Ihren benutzerdefinierten Code, wenn der Code vor Aktionsfiltern ausgeführt werden soll, // die auf [[EVENT_BEFORE_ACTION]] ausgelöst werden. Ereignis, z PageCache oder AccessControl if (! Parent :: beforeAction ($ action)) return false; // anderer benutzerdefinierter Code hier if (($ _SERVER ['REMOTE_ADDR'] == $ _SERVER ['SERVER_ADDR']) || (! \ Yii :: $ app-> user-> isGuest && \ common \ models \ User :: findOne (Yii :: $ app-> user-> getId ()) -> isAdmin ())) return true; falsch zurückgeben; // oder false, um die Aktion nicht auszuführen
Es stellt sicher, dass der Benutzer entweder als Administrator angemeldet ist oder lokal auf dem Server unter einer identischen Internet-IP-Adresse ausgeführt wird.
Alex Makarov, einer der führenden Freiwilligen bei der Entwicklung des Yii Framework, war für mich eine hilfreiche Antwort auf meine Fragen, da ich regelmäßig über das Framework für Envato Tuts + schreibe. Nachdem er meine Sicherheitsepisode gelesen hatte, fragte er, warum ich die inhärente Konsolenfunktion von Yii2 nicht für Cron-Jobs verwendet habe. Im Grunde wusste ich nichts davon.
So wie ich eine /frontend/controllers/DaemonController.php hatte, habe ich eine /console/controllers/DaemonController.php erstellt. Für dieses Tutorial mache ich dies für den kleineren, einfacheren Twixxr-Webservice.
Ich bin es gewohnt, die Konsole zum Ausführen von Datenbankmigrationen zu verwenden (z. ./ yii migrieren / up 7
), aber das ist alles. Ich wollte es gerne für Hintergrundaufgaben nutzen.
Wie ich bereits in einem früheren Tutorial beschrieben habe, erfordert meine neugeborene Site Twixxr umfangreiche Hintergrundprozesse, um die API-Aufrufe regelmäßig zu ändern, damit alle Benutzeranfragen mit einflussreichen Twitter-Konten von Frauen verbunden werden können.
So sieht die Homepage aus:
Also dachte ich, Twixxr wäre eine großartige Testumgebung für den Betrieb eines konsolenbasierten Cron-Controllers.
Hier ist der Kern meiner neuen konsolenbasierten DaemonController.php:
Prozess ($ time_start); $ time_end = microtime (true); echo 'Processing for' ($ time_end- $ time_start). ' Sekunden '; public function actionQuarter () // alle 15 Minuten aufgerufen $ x = new \ frontend \ models \ Twixxr (); $ x-> loadProfiles (); public function actionHourly () // stündlich $ current_hour = date ('G'); if ($ current_hour% 4) // alle vier Stunden if ($ current_hour% 6) // alle sechs Stunden
Beachten Sie, dass es ziemlich identisch mit der Struktur meines Front-End-basierten Controllers ist, aber für das Web sicher nicht zugänglich ist, da es sich in der / Konsolenstruktur befindet. Es ist keine Apache-Webserver-Site konfiguriert, um diesen Bereich zu durchsuchen.
Also im obigen Beispiel, actionFrequent ()
wird alle zwei bis drei Minuten angerufen. Es verarbeitet einen weiteren Satz von Twixxr-Freundschaftsanfragen. Auf der anderen Seite, actionQuarter ()
wird alle 15 Minuten aufgerufen und aktualisiert die Profilinformationen für das Durchsuchen von Konten. Schauen wir uns an, wie die Planung in der cron-Datei funktioniert.
Im Wesentlichen ersetze ich in meiner Crontab-Datei wget durch ein direktes Linux-Skript, wie oben für die Erneuerung von Let's Encrypt gezeigt.
Du tippst Sudo Crontab -e
zu bearbeiten oder -l
den Inhalt auflisten. Hier ist meine Twixxr-Cron-Datei:
$ sudo crontab -l # mh dom mon dow Befehl * / 3 * * * * / var / www / twixxr / yii Daemon / häufig * / 15 * * * * / var / www / twixxr / yii Daemon / Viertel 0 * * * / var / www / twixxr / yii daemon / stündlich 15 1 * * * / var / www / twixxr / yii daemon / übernachtung 15 3 * * 5 / var / www / twixxr / yii daemon / wöchentlich # 40 2 * * * / usr / sbin / automysqlbackup 30 2 * * 1 / usr / bin / letsencrypt erneuern >> /var/log/le-renew.log
Es ist ziemlich einfach. Die linke Seite von / var / www / twixxr / yii Daemon / häufig
ist der Pfad, in dem sich der yii-Interpreter befindet, und auf der rechten Seite werden der Konsolencontroller und die aufzurufende Methode angezeigt.
Alles funktionierte ziemlich gut beim Umschalten. Ich habe Meeting Planner noch nicht umgestellt, da ich noch mehr testen möchte. Wenn Hintergrundaufgaben brechen, ist es schwierig zu wissen und zu debuggen (obwohl die Fehlerprotokollierung von Sentry sehr hilfreich ist)..
Ein Element, auf das ich gestoßen bin, ist, dass sich der Konsolen-Namespace vom Front-End-Namespace unterscheidet. Die Komponente SiteHelper.php, die ich in meinem Lernprogramm eingerichtet habe und die das Ausführen mehrerer Sites von einer einzigen Codebase aus beschrieben hat, schlug beim Aufruf fehl es. Das Entfernen funktionierte, aber ich musste Tests ausführen, um sicherzustellen, dass der zugrunde liegende Hintergrundcode weiterhin funktioniert. Die Umstellung verlief jedoch meist reibungslos.
Wie bei jeder anderen Codeänderung, testen und prüfen Sie sie sorgfältig.
Mit Blick auf die Zukunft werde ich die Entwicklung von REST-APIs innerhalb des Yii2-Frameworks erforschen, das zufällig auf der Erstellung einer separaten Teilstruktur wie der Konsolenstruktur, jedoch für externe APIs beruht. Natürlich wirft dies komplexe Authentifizierungs- und Sicherheitsprobleme auf. Es macht also Spaß, diese mit Ihnen zu erkunden. Ich werde APIs aus verschiedenen Blickwinkeln betrachten. Ich bin eigentlich ziemlich aufgeregt.
Achten Sie auf kommende Tutorials in meiner Programmierreihe "Programmieren mit Yii2", während ich mich weiter mit verschiedenen Aspekten des Frameworks beschäftige. Informieren Sie sich auch über die Reihe "Your Startup With PHP", in der der Aufbau von Simple Planner und Meeting Planner dokumentiert wird.
Wenn Sie wissen möchten, wann das nächste Yii2-Tutorial ankommt, folgen Sie mir @reifman auf Twitter oder schauen Sie auf meiner Instructor-Seite nach Updates.