Cronjobs (periodieke taken) instellen


Tags: SSH

Als technisch beheerder is er een reeks aan taken die je eens in de zoveel tijd uitvoert om je website up-to-date te houden. Denk hierbij aan het updaten van alle productinformatie, het legen van de cache van de site etc. Je kunt deze taken natuurlijk handmatig telkens uitvoeren, maar het is makkelijker dit automatisch uit te voeren. Hiervoor zijn cronjobs (periodieke taken) bedacht; opdrachten die via de Shell server automatisch worden uitgevoerd.

In dit artikel leggen we uit hoe je cronjobs instelt en geven we enkele praktische voorbeelden hiervan.

More information in English about configuring cronjobs in Magento can be found in the Hypernode knowledgebase

 

Handmatig cronjobs instellen via Shell

Het is ook mogelijk om via Shell cronjobs in te stellen. Hiervoor werk je met een programma genaamd crontab. Crontab is een editor waarmee je makkelijk cronjobs kunt instellen, bewerken en verwijderen. Hoe dat precies werkt kun je hieronder lezen.

Werken in crontab

Een nog niet ingestelde crontab afb. 2 Een nog niet ingestelde crontab

Let op! Als eerst is het belangrijk om te weten dat je voor het instellen van cronjobs toegang tot Shell nodig hebt. Mocht je meer informatie daarover willen hebben, kijk dan op de pagina Shell.

Wanneer je ingelogd bent op de Shell server gebruik je het volgende commando om je crontab te openen:

crontab -e

Je bent nu in een editor waar je taken kunt opgeven of wijzigen (zie afbeelding 2). Wanneer je nog nooit cronjobs hebt toegevoegd ziet je crontab eruit als in afbeelding 2. Je kunt je wijzigingen opslaan door op je toetsenbord op “CTRL-X” te drukken en vervolgens op “y”, en “enter”. Als je nu de onderstaande regel te zien krijgt is je taak succesvol opgeslagen.

crontab: installing new crontab

Wanneer je snel wilt zien welke taken er gepland zijn, gebruik je het volgende commando:

crontab –l

Wanneer je alle taken wilt wissen, gebruik je het volgende commando:

crontab –r

Let op! Wanneer je het bovenstaande commando gebruikt, zijn al je taken verwijderd en dien je deze opnieuw handmatig in te stellen.

Instellen van je cronjob

Een cronjob bestaat uit twee onderdelen; een tijdsaanduiding en de taak. Bekijk hiervoor het onderstaande voorbeeld:

# m  h  dom mon dow   command 
10 5   *   *   *     php5 /(pad naar homedirectory)/domein.nl/dotasks.php

Tijdsaanduiding opgeven

In het voorbeeld zie je in het linkergedeelte (10 5 * * *) wanneer de taak uitgevoerd dient te worden. Rechts zie je om welke taak het gaat. Om te achterhalen hoe de tijdsaanduiding precies werkt bekijken we de onderstaande tabel:

m minuten na het hele uur (0-59)
h uur van de dag (0-23)
dom dag van de maand (1-31)
mon maand van het jaar (1-12)
dow dag van de week (mon,tue,wed,thu,fri,sat,sun)
command het uit te voeren commando

In het voorbeeld zien we dus m = 10 en h = 5. Dat wil zeggen dat de taak om 05:10 uitgevoerd wordt. In het onderstaande voorbeeld wordt de taak uitgevoerd op vrijdag om 17:30.

# m  h  dom mon dow   command 
30 17   *   *   fri     php5 /(pad naar homedirectory)/domein.nl/dotasks.php

Let op! Het is heel belangrijk dat je goed kijkt naar de tijdsaanduiding van je cronjob. De ervaring leert dat de meeste problemen met cronjobs ontstaan doordat de tijdsaanduiding in de crontab niet goed ingesteld staat!

De taak specificeren

In het eerste voorbeeld zagen we de volgende taak beschreven:

php5 /pad naar homedirectory/domein.nl/dotasks.php

Dit gedeelte bestaat uit twee belangrijke gedeeltes; het programma dat je gebruikt en de locatie van het bestand dat je wilt uitvoeren. Het hele commando zegt eigenlijk het volgende:

Voer het bestand dotasks.php uit dat op de locatie /pad naar homedirectory/domein.nl/ staat.

Aangezien het een PHP script is, gebruik je php5 om het script uit te laten voeren via de SSH server. Belangrijk bij deze regel is het pad waar het bestand in staat. Je geeft het volledige “pad naar de homedirectory” op want anders weet de crontab niet om welk bestand het gaat.

Dit pad kun je vinden onder het tabblad “Administratief” en dan de optie Domein Informatie. Als voorbeeld nemen we het domein wikibyte.nl .
Het pad naar de homedirectory is dan /home/users/wikicftp/ . De complete taak wordt dan als volgt:

30 17   *   *   fri     php5 /home/users/wikicftp/wikibyte.nl/dotasks.php

Je kunt dit ook achterhalen door te navigeren naar de locatie waar het bestand staat en dan het pwd commando te gebruiken.

Output van de cronjob mailen

De output van je script worden niet standaard verzonden. Door een enkele toevoeging aan je crontab toe te voegen zal de output naar een opgegeven e-mailadres gemaild worden. Dit ziet er dan als volgt uit:

# m  h  dom mon dow   command
MAILTO=email@adres.nl 
10 5   *   *   *     php5 /home/users/wikicftp/wikibyte.nl/dotasks.php

Wanneer je alleen e-mail wilt ontvangen als er zich een fout in je cronjob voor doet, voeg je het volgende stukje toe aan je crontab:

> /dev/null

Het eerder genoemde voorbeeld ziet er dan als volgt uit:

# m  h  dom mon dow   command
MAILTO=email@adres.nl 
10 5  *   *   *     php5 /home/users/wikicftp/wikibyte.nl/dotasks.php > /dev/null

Meer uitleg en voorbeelden nodig?

Kijk dan eens hier, hier of hier!

Voorkom performance issues met Lockrun

Wij adviseren voor elke cronregel lockrun toe te voegen. Lockrun wordt vaak gebruikt bij zware cronjobs die elke minuut of vaker draaien. Op het moment dat geen lockrun toegepast is, kunnen deze taken elkaar namelijk gaan overlappen.

Wat doen cronjobs zonder lockrun?

Het kan dus zijn dat taken elkaar overlappen als er 1 cronjob vastloopt. Bijvoorbeeld: een cronjob die elke minuut loopt kan zichzelf inhalen op het moment dat hij gestart wordt terwijl het vorige proces (dezelfde cron een minuut eerder) nog niet afgesloten is.

Op dat moment beginnen de cronjobs op te stapelen, omdat het steeds langer duurt om ze uit te laten lopen, en er elke minuut een proces bij gestart wordt. Het gevolg is dat cronjobs gekilled worden en dat kan potentieel gevolgen hebben voor de werking van het script (in verband met eventuele synchronisatiefouten, lockfiles etc.). Met lockrun wordt gekeken of de cron die gestart gaat worden misschien al loopt. Zo ja, dan wordt deze job geen tweede keer gestart. Bijvoorbeeld:

* * * * * echo test

Deze cronjob zegt elke minuut “test”. Niet een bijster zware klus, maar laten we zeggen dat hij er twee minuten over doet. Dat kan nooit goed gaan met een cron die elke minuut loopt. We voegen in het onderstaande voorbeeld een lockrun toe aan de cronjob.

* * * * * lockrun -L .lockfile -- echo test

Dat gaat al een stuk beter. In dit geval start hij elke minuut het programma lockrun, welke een lockfile met de naam .lockfile wegzet alvorens het commando (echo test) uit te voeren. Mocht de lockfile nog bestaan, omdat er nog een vorige cronjobs bezig is, zal lockrun dit melden en de cronjob niet nogmaals starten.

Let op! Wanneer je een cronjob vaker in het uur laat draaien en je daar nog geen lockrun op hebt staan, zal een automatisch script van ons alsnog een lockrun aan je cronjob toevoegen. Dit doen wij om de stabiliteit van ons platform te waarborgen. Daarnaast zal de kwaliteit van de cronjob erbij gebaat zijn.

Gebruik lockrun voor elke cronjob

Wil je bovengenoemde performance issues voorkomen, dan adviseren we lockrun voor elke cronregel te plaatsen. Geef dan iedere cronjob een unieke lockfile naam.

Bijvoorbeeld ‘.lock1’ ‘.lock2’ etc. lock files worden in de homepage geplaatst. Mocht je de lockfile in een andere locatie willen opslaan dan moet dit wel een relatief pad zijn ten opzichte van de homedir

* * * * * lockrun -L .lock1 -- echo test
* * * * * lockrun -L .lock2 -- echo test2

Stille werking

Standaard geeft lockrun een melding als er al een cronjob loopt, welke je per e-mail ontvangt. Heb je geen behoefte aan deze meldingen? Geef dan een -Q (–quiet) als argument mee.

* * * * * lockrun -Q -L .lockfile -- echo test

Voeg een timeout toe aan je cronjob

Wanneer je cronjob een lockrun heeft maar ergens blijft hangen zal de eerst volgende cronjob niet gestart worden als deze gebruik maakt van dezelfde lockfile. Door een timeout op te geven zal een job na een specifieke tijd stoppen met draaien, zal de lockfile verwijderd worden en kan de eerst volgende cronjob wel gedraaid worden. In het onderstaande voorbeeld hebben we onze cronjob een timeout van een uur meegegeven:

* * * * * timeout 3600 lockrun -L .lockfile -- echo test

Foutmelding: run is locked

Deze foutmelding komt voor wanneer je op een cron job een lock run hebt ingesteld en de eerste taak is blijven hangen. Een tweede cronjob wilt dan ook gebruik maken van de lockrun, maar omdat de lockrun nog gebruikt wordt voor de eerste taak, krijg je de foutmelding run is locked.

Dit probleem is op te lossen door te achterhalen welk proces er achter de schermen is blijven hangen. Hiervoor kun je het commando ‘ps faux’ gebruiken. Hiermee krijg je alle lopende processen te zien en kun je achterhalen welk proces is blijven hangen. Wanneer je dit proces dan “killed” zal de lockfile weer beschikbaar zijn voor een volgende cronjob.

Je kunt een proces killen door het commando kill 12343 te gebruiken, waarbij je 12343 aanpast naar hetgeen je bij PID ziet. Kijk goed welk proces dat van je cronjob is (je ziet welk bestand er aangeroepen wordt) en schiet deze vervolgens af.

Let op! Wanneer je het hangende proces hebt gevonden raden we je aan om te achterhalen waarom dat proces is blijven hangen. Zo voorkom je dat dit probleem in de toekomst nog een keer voorkomt.

Automatische Magento product import

Met een cronjob kun je je Magento product import automatiseren. Dat is bijvoorbeeld handig als je gebruik maakt van een data warehousing systeem die producten en voorraden exporteert. Deze kun je vervolgens automatisch importeren in je webshop. Hoe je dit doet lees je op de pagina Magento Product Import Met Cronjob.

3