Uw boekhoudkundige exportcron wordt “elk uur” uitgevoerd. Op een ochtend ontvangt de boekhouding twee identieke bestanden met dubbele boekingen. Graven: de taak van 08:00 uur was nog niet klaar toen de taak van 09:00 uur begon - hetzelfde script, dezelfde tijdelijke tabel, geen mutex.
Op een enkele VPS is het klassiek. Op een schaalbare infrastructuur is het nog erger: twee servers draaien dezelfde crontab omdat niemand de planner heeft gecentraliseerd.
Waarom crons elkaar overlappen
| Oorzaak | Scenario | Symptoom |
|---|---|---|
| Taak te lang | Importeren > interval | Duplicaten, impasses DB |
| Handmatig opnieuw opstarten | Beheerder+cron | Twee parallelle processen |
| Meerdere servers | crontab gekopieerd naar 2 VPS | Dubbele facturatie van klanten |
| Host opnieuw | Time-out PHP kill + herstart | Gedeeltelijke vastlegging × 2 |
Een cron is niet standaard “idempotent” – je moet hem bewijzen of vergrendelen.
kudde: bestandsvergrendeling op een enkele host
* * * * * kudde -n /var/lock/sync.lock /usr/local/bin/sync.sh >> /var/log/sync.log 2>&1
-n: niet-blokkerend — overslaan als de vergrendeling is ingesteld (bij voorkeur boven een oneindige wachtrij).- Vergrendeling op lokale schijf gedeeld als meerdere gebruikers — geen NFS instabiel voor kritieke vergrendelingen.
PHP-alternatief:
$fp = fopen('/var/lock/job.lock', 'c');
als (!flock($fp, LOCK_EX | LOCK_NB)) {
uitgang(0);
}
// werk...
Gedistribueerde vergrendeling: Redis en PostgreSQL
Redis (kort patroon, TTL vereist):
SET-vergrendeling: exporteer $(uuid) NX EX 3600
Geef vrij met het Lua-vergelijk-en-del-script om te voorkomen dat de vergrendeling van een ander proces wordt verwijderd.
PostgreSQL-adviesslot — handig als de taak al invloed heeft op de DB:
SELECTEER pg_try_advisory_lock(12345);
De vergrendeling wordt aan het einde van de sessie opgeheven: handig voor lange SQL-taken.
Architectuur: cron-trigger versus enkele werknemer
Voor zware taken zijn er alleen cron-wachtrijen:
- Cronminuut → taak-ID naar Redis-wachtrij pushen.
- Slechts één werkconsument verwerkt de wachtrij.
- Time-out voor zichtbaarheid van het bericht bij een crash.
Laravel Horizon, Sidekiq, Celery beat – hetzelfde principe. De cron wordt een wake-up call, niet de uitvoering zelf.
Monitoring en logboeken
Begin en einde van het logboek met PID, duur en status. Correleer met databasestatistieken: impasses en dubbele rijen zijn vaak het eerste signaal. Controleer bij gedeeld de tijdzone van de server en de PHP-limieten voordat u de code vastlegt.
De top: idempotence vervangt het slot niet – het vult het aan
De twee houden samen de nacht van Black Friday.
Beslis en ga vooruit zonder blinde vlek
Controleer elke geplande cron: vergelijk de waargenomen maximale duur met het geconfigureerde interval. Voeg Flock onmiddellijk toe aan elke single-node VPS. Centraliseer de planner als u meerdere servers heeft: één cron-node of een gedeelde Redis-lock. Begin en eindig het logboek met PID om duplicaten te correleren. Raadpleeg onze hostinggids voor cron- en PHP-limieten, afhankelijk van het aanbod.
Veelgestelde vragen
Is kudde genoeg om een cron bash te vergrendelen?
Ja op een enkele server: Flock -n /var/lock/myjob.lock /path/script.sh voorkomt een tweede gelijktijdige instantie. De vergrendeling verdwijnt als het proces stopt. Controleer of het script niet splitst zonder de vergrendeling op te heffen.
Hoe kan ik een cron op meerdere servers vergrendelen?
Gebruik een gedistribueerd slot: Redis SET NX EX, PostgreSQL-adviesslot of DynamoDB-slot. kudde werkt niet tussen machines.
Wat te doen als de vorige taak langer duurt dan het cron-interval?
Vergroot het interval, of laat overslaan toe (flock -n, wat 0 oplevert), of zet de taak in de wachtrij (enkele werknemer). Laat nooit twee enorme importen elkaar overlappen.
Hebben gedeelde crons specifieke valkuilen?
Ja: servertijd versus lokale tijd, verschillende PHP-paden, stille kill-time-out en meerdere knooppunten zonder coördinatie als de host de infrastructuur schaalt zonder u dit te vertellen.
Een cron zonder slot is als roulette: de ene dag wordt de taak twee keer voltooid — de dag dat je niet naar de logboeken kijkt.
