Taken plannen met Cron-taken

Cron-taken worden gebruikt voor het plannen van taken om op de server uit te voeren. Ze worden het meest gebruikt voor het automatiseren van systeemonderhoud of -beheer. Ze zijn echter ook relevant voor de ontwikkeling van webtoepassingen. Er zijn veel situaties waarin een webtoepassing bepaalde taken nodig heeft om periodiek te worden uitgevoerd. Vandaag gaan we de fundamenten van Cron Jobs verkennen.

Definities

Laten we eerst de termen in verband met dit onderwerp leren kennen.

"Cron" is een op de tijd gebaseerde taakplanner in Unix-achtige besturingssystemen (Linux, FreeBSD, Mac OS enz ...). En deze taken of taken worden "Cron-taken" genoemd.

Er is een cron "daemon" die op deze systemen wordt uitgevoerd. Een daemon is een programma dat de hele tijd op de achtergrond draait, meestal geïnitieerd door het systeem. Deze cron-daemon is verantwoordelijk voor het op schema zetten van deze cron-taken.

Het schema bevindt zich in een configuratiebestand met de naam "crontab". Dat is waar alle taken en hun timers worden vermeld.

Waarom Cron-banen gebruiken?

Serverbeheerders gebruiken cron-taken al heel lang. Maar aangezien de doelgroep van dit artikel webontwikkelaars is, laten we eens kijken naar enkele use cases van cron-taken die relevant zijn in dit gebied:

  • Als u een lidmaatschapssite heeft, waarbij accounts vervaldatums hebben, kunt u cron-taken plannen om regelmatig accounts te deactiveren of te verwijderen die voorbij hun vervaldatums zijn.
  • U kunt dagelijkse nieuwsbrief-e-mails versturen.
  • Als u samenvattende tabellen (of gematerialiseerde weergaven) in uw database hebt, kunnen deze regelmatig worden bijgewerkt met een cron-taak. U kunt bijvoorbeeld elke treffer op een webpagina opslaan in een tabel, maar een andere samenvattende tabel kan dagelijkse verkeerssamenvattingen bevatten.
  • U kunt in de loop van een bepaald interval verlopen gegevensbestanden in de cache wissen en wissen.
  • U kunt de inhoud van uw website automatisch controleren op kapotte koppelingen en u krijgt regelmatig een rapport per e-mail toegestuurd.
  • U kunt langdragende taken zo plannen dat ze worden uitgevoerd vanaf een opdrachtregelscript, in plaats van deze uit een webscript uit te voeren. Zoals het coderen van video's of het versturen van massale e-mails.
  • U kunt zelfs iets eenvoudigs uitvoeren als het ophalen van uw meest recente tweets, om te worden opgeslagen in een tekstbestand.

Syntaxis

Hier is een eenvoudige cron-taak:

 10 * * * * / usr / bin / php /www/virtual/username/cron.php> / dev / null 2> & 1

Er zijn twee hoofdonderdelen:

  1. Het eerste deel is "10 * * * *". Dit is waar we de timer plannen.
  2. De rest van de regel is de opdracht zoals deze zou lopen vanaf de opdrachtregel.

Het commando zelf in dit voorbeeld bestaat uit drie delen:

  1. "/ Usr / bin / php". PHP-scripts zijn meestal niet zelf uitvoerbaar. Daarom moeten we het door de PHP-parser leiden.
  2. "/Www/virtual/username/cron.php". Dit is slechts het pad naar het script.
  3. "> / dev / null 2> & 1". Dit deel behandelt de uitvoer van het script. Hierover later meer.

Timing syntaxis

Dit is het eerste deel van de cron-jobstring, zoals hierboven vermeld. Het bepaalt hoe vaak en wanneer de cron-taak wordt uitgevoerd.

Het bestaat uit vijf delen:

  1. minuut
  2. uur
  3. dag van de maand
  4. maand
  5. dag van de week

Hier is een illustratie:

Asterisk

Heel vaak ziet u een asterisk (*) in plaats van een cijfer. Dit vertegenwoordigt alle mogelijke nummers voor die positie. Bijvoorbeeld, asterisk in de minuutpositie zou het elke minuut laten lopen.

We moeten een paar voorbeelden bekijken om deze Syntax volledig te begrijpen.

Voorbeelden:

Deze cron-taak wordt elke minuut uitgevoerd, altijd:

 * * * * * [opdracht]

Deze cron-taak wordt uitgevoerd op minuut nul, elk uur (dat wil zeggen een cron-taak per uur):

 0 * * * * [opdracht]

Dit is ook een cron-baan per uur, maar wordt in plaats daarvan op minuut 15 uitgevoerd (d.w.z. 00:15, 01:15, 02:15 etc.):

 15 * * * * [opdracht]

Deze wordt eenmaal per dag om 2:30 uur uitgevoerd:

 30 2 * * * [opdracht]

Deze wordt eenmaal per maand uitgevoerd, op de tweede dag van de maand om middernacht (d.w.z. 2 januari 12:00 uur, 2 februari 12:00 uur, enz.):

 0 0 2 * * [opdracht]

Dit loopt op maandag, elk uur (dat wil zeggen 24 keer op een dag, maar alleen op maandag):

 0 * * * 1 [opdracht]

U kunt meerdere nummers gebruiken, gescheiden door komma's. Deze wordt driemaal per uur uitgevoerd, op minuten 0, 10 en 20:

 0,10,20 * * * * [opdracht]

Divisie-operator wordt ook gebruikt. Dit loopt 12 keer per uur, d.w.z. elke 5 minuten:

 * / 5 * * * * [opdracht]

Dash kan worden gebruikt om een ​​bereik op te geven. Deze loopt eenmaal per uur tussen 05:00 en 10:00 uur:

 0 5-10 * * * [opdracht]

Er is ook een speciaal trefwoord waarmee u elke keer dat de server opnieuw wordt opgestart een cron-taak uitvoert:

 @reboot [opdracht]

Cron-taken instellen en beheren

Er zijn een paar verschillende manieren om uw cron-taken te maken en te beheren.

Controle panelen

Veel webhostingbedrijven bieden control panels voor hun klanten. Als u een van hen bent, kunt u mogelijk een sectie in uw configuratiescherm vinden om uw cron-taken te beheren.

De Crontab bewerken

Als u deze opdracht uitvoert, wordt vi (teksteditor) gestart en kunt u de inhoud van de crontab bewerken:

 crontab -e

Dus het zou helpen om bekend te zijn met de basis vi-commando's, omdat het heel anders is dan elke andere tekstverwerker waar je mee gewerkt hebt.

Als u alleen de bestaande crontab wilt zien zonder deze te bewerken, kunt u deze opdracht uitvoeren:

 crontab -l

Om de inhoud van de crontab te verwijderen:

 crontab -r

Een bestand laden

U kunt al uw cron-taken in een bestand schrijven en vervolgens in de crontab duwen:

 crontab cron.txt

Wees voorzichtig, want dit overschrijft alle bestaande cron-taken met deze bestandsinhoud, zonder waarschuwing.

Comments

U kunt opmerkingen toevoegen gevolgd door het teken #.

 # Deze cron-taak doet iets heel belangrijks 10 * * * * / usr / bin / php /www/virtual/username/cron.php> / dev / null 2> & 1

De e-mail instellen

Zoals ik eerder al zei, wordt standaard de uitvoer van de crons verzonden via e-mail, tenzij je ze verwijdert of doorverwijst naar een bestand. Met de MAILTO-instelling kun je instellen of wijzigen naar welk e-mailadres ze moeten worden verzonden:

 MAILTO = "[email protected]" # Deze cron-taak doet iets heel belangrijks 10 * * * * / usr / bin / php /www/virtual/username/cron.php> / dev / null 2> & 1

De PHP-parser gebruiken

CGI-scripts zijn standaard uitvoerbaar, maar PHP-scripts zijn dat niet. Ze moeten de PHP-parser doorlopen. Daarom moeten we het pad naar de parser vóór het pad van het script plaatsen.

 * * * * * / usr / bin / php [pad naar php-script]

Soms is het mogelijk onder een andere locatie zoals: "/ usr / local / bin / php". Om dit te weten te komen, kunt u proberen dit op de opdrachtregel uit te voeren:

 welke php

Omgaan met de uitvoer

Als u de uitvoer van het cron-script niet verwerkt, worden deze als e-mails naar uw gebruikersaccount op de server verzonden.

Uitvoer verwijderen

Als u "> / dev / null 2> & 1" aan het einde van de cron-opdracht (of een opdracht) plaatst, wordt de uitvoer weggegooid.

De sluitbeugel (>) wordt gebruikt voor het omleiden van de uitvoer. "/ dev / null" is als een zwart gat voor uitvoer. Alles wat daar komt, wordt genegeerd door het systeem.

Dit gedeelte "2> en 1" zorgt ervoor dat de uitvoer STDERR (fout) wordt omgeleid naar de uitvoer STDOUT (normaal). Dus dat komt ook in de "/ dev / null" terecht.

Uitvoeren naar een bestand

Om de cron-uitvoer in een bestand op te slaan, gebruikt u nogmaals de sluitingshaak (>):

 10 * * * * / usr / bin / php /www/virtual/username/cron.php> /var/log/cron.log

Dat zal het uitvoerbestand elke keer herschrijven. Als u de uitvoer aan het einde van het bestand wilt toevoegen in plaats van een volledige herschrijving, gebruikt u in plaats daarvan dubbele sluitingshaak (>>):

 10 * * * * / usr / bin / php /www/virtual/username/cron.php >> /var/log/cron.log

Uitvoerbare scripts

Normaal gesproken moet u de parser aan het begin van de opdracht opgeven zoals we al deden. Maar er is eigenlijk een manier om je PHP-scripts uitvoerbaar te maken vanaf de commandoregel zoals een CGI-script.

U moet het pad naar de parser toevoegen als de eerste regel van het script:

 #! / Usr / local / bin / php 

Zorg er ook voor dat u de juiste chmod instelt (zoals 755) om het bestand uitvoerbaar te maken.

Wanneer u een uitvoerbaar script hebt, kan de cron-taak op deze manier korter zijn:

 10 * * * * /www/virtual/gebruikersnaam/hello.php

Voorkomen van Cron Job Collision

In sommige gevallen kunt u vaak cron-taken uitvoeren en wilt u misschien niet dat ze in botsing komen als ze langer duren om te draaien dan de frequentie zelf.

U kunt bijvoorbeeld elke minuut een cron-taak uitvoeren. Toch kan het zo nu en dan langer duren dan een minuut om te rennen. Hierdoor kan een ander exemplaar van hetzelfde cron-script worden gestart voordat de vorige is voltooid. Je kunt op deze manier te veel drukke processen maken en mogelijk de server laten crashen als ze elkaar blijven vertragen, waardoor er na verloop van tijd nog meer processen worden gemaakt ...

Dit probleem kan worden opgelost via bestandsvergrendeling en meer specifiek het niet-blokkerende (LOCK_NB) type bestandssloten. (Als u niet bekend bent met bestandsvergrendeling, raad ik u aan er eerst over te lezen.)

U kunt deze code toevoegen aan het cron-job-script:

 $ fp = fopen ('/ tmp / lock.txt', 'r +'); if (! flock ($ fp, LOCK_EX | LOCK_NB)) echo 'Kon geen vergrendeling verkrijgen'; exit (-1);  / * ... * / fclose ($ fp);

Met normale bestandsvergrendelingen zou de functieaanroep van de koppel () het script blokkeren als er een bestaande vergrendeling is. En het zou loslaten zodra het slot is verdwenen. Met een niet-blokkerende vergrendeling, zoals in de bovenstaande code, stopt de functie aanroep het script echter niet, maar retourneert het ONWAAR onmiddellijk als er een bestaande vergrendeling is. In dit geval kunnen we het script onmiddellijk afsluiten wanneer we zien dat er een bestaand slot is, wat aangeeft dat er momenteel een andere cron-taak actief is.

Webtoegang blokkeren voor Cron-taken

Wanneer u een cron-taak in een scripttaal op internet, zoals PHP, schrijft, kunt u ervoor zorgen dat niemand het kan uitvoeren door het gewoon vanuit hun browser te laden. Een eenvoudige optie is om dit script buiten uw webmap op te slaan. Dit is echter mogelijk niet praktisch of verkiesbaar voor sommige ontwikkelaars, als ze hun cron-taakscripts recht willen houden in hun webtoepassingsmappen..

Als u alle cron-taakscripts in een map plaatst, blokkeert u de toegang door deze regel in een .htaccess-bestand te plaatsen:

 ontken van iedereen

Of u kunt ook de toegang tot scripts op individuele basis weigeren door deze regel aan het begin te zetten:

 if (isset ($ _ SERVER ['REMOTE_ADDR'])) sterven ('Permission denied.');

Dit zorgt ervoor dat wanneer het script wordt geopend via internet, het onmiddellijk wordt afgebroken.

Conclusie

Bedankt voor het lezen. Ook al lijken cron-taken slechts een hulpmiddel voor systeembeheerders, ze zijn zelfs relevant voor vele soorten webtoepassingen.

Laat uw opmerkingen en vragen achter en geniet van een geweldige dag!

Schrijf een Plus-zelfstudie

Wist je dat je tot $ 600 kunt verdienen voor het schrijven van een PLUS tutorial en / of screencast voor ons?? We zijn op zoek naar diepgaande en goed geschreven tutorials over HTML, CSS, PHP en JavaScript. Als je van het vermogen bent, neem dan contact op met Jeffrey via [email protected].

Houd er rekening mee dat de daadwerkelijke compensatie afhankelijk is van de kwaliteit van de laatste zelfstudie en screencast.

  • Volg ons op Twitter of abonneer je op de Nettuts + RSS Feed voor de beste tutorials voor webontwikkeling op internet.