Il vostro lavoro cron di WHMCS è davvero in esecuzione? Come risolvere i problemi di cron processi bloccati e sovrapposti

Il lavoro cronizzato WHMCS è una di quelle operazioni che di solito funzionano in sottofondo senza creare particolari problemi — finché non lo fanno.
Le fatture, i promemoria di rinnovo, la sincronizzazione dei domini, le sospensioni automatiche, le escalation dei ticket e dozzine di altre attività automatizzate dipendono da questo. Per questo motivo, la raccomandazione standard di WHMCS è di eseguire cron.php ogni pochi minuti.
Per esempio:
*/5 * * * * /usr/local/bin/php -q /path/to/whmcs/crons/cron.php
Ma c'è una distinzione importante:
il fatto che un cron job venga avviato ogni cinque minuti non significa necessariamente che avvenga con successo ogni cinque minuti.
Un processo può iniziare correttamente e poi rimanere bloccato durante l’esecuzione. Cinque minuti dopo, potrebbe essere avviato un altro processo. Quindi un altro ancora.
Non molto tempo dopo, invece dell'automazione, avrai una piccola collezione di processi PHP che aspettano pazientemente la fine dell'universo.
Questo articolo mostra un modo semplice per scoprire cosa sta realmente accadendo.
Il problema: “il cron è in esecuzione” non basta
Nel risolvere i problemi relativi all’automazione di WHMCS, una delle prime cose che di solito controlliamo è se il cron del sistema sia configurato correttamente.
E potrebbe davvero essere configurato correttamente.
Il sistema operativo può eseguire con precisione:
php -q /path/to/whmcs/crons/cron.php
ogni cinque minuti.
Questo dimostra che il processo inizio.
Non dimostra che il processo precedente sia stato corretto concluso.
Questa distinzione diventa particolarmente importante quando un'operazione di automazione WHMCS rimane sospesa a causa di un'API esterna, di un timeout della rete, di un modulo problematico, di un problema al database o di qualche codice personalizzato.
Quello che vogliamo davvero sapere è:
- Quando è iniziato il cron di WHMCS?
- Quando è finita?
- Quali attività di automazione sono state eseguite?
- Quale compito è iniziato ma non è mai stato completato?
- Quanto ha imposto l'intera procedura di esecuzione cron?
- Sono molteplici
cron.phpprocessi in esecuzione simultaneamente?
Fortunatamente, i hook di WHMCS ci offrono un modo conveniente per indagare.
Passo 1: Registrare l'inizio e la fine del crono WHMCS
Il WHMCS offre due hook particolarmente utili:
PreCronJob
Dopo CronJob
PreCronJob viene eseguito quando l'automazione cron avvia il processo, mentre Dopo CronJob viene eseguito dopo che le attività di automazione pianificate sono terminate.
Crea il seguente file:
/includes/hooks/cron_debug.php
e aggiungo:
>> CRON START'
. ' | PID: ' . getmypid()
. ' | Time: ' . date('Y-m-d H:i:s')
. ' | Memory: ' . round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
);
});
/**
* Cron completed
*/
add_hook('AfterCronJob', 1, function ($vars) {
logActivity(
'[CRON DEBUG] <<< CRON END'
. ' | PID: ' . getmypid()
. ' | Time: ' . date('Y-m-d H:i:s')
. ' | Memory: ' . round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
);
});
Ora controllate il registro delle attività di WHMCS.
In condizioni normali, dovresti vedere qualcosa di simile a:
[CRON DEBUG] >>> CRON START | PID: 17432 | Ora: 29 agosto 2026 13:30:01 | Memoria: 18 MB
[CRON DEBUG] <<< CRON END | PID: 17432 | Ora: 29 agosto 2026 13:30:14 | Memoria: 24 MB
Cinque minuti dopo:
[CRON DEBUG] >>> CRON START | PID: 17501 | Ora: 29 agosto 2026 13:35:01 | Memoria: 18 MB
[CRON DEBUG] <<< CRON END | PID: 17501 | Data: 29 agosto 2026 13:35:09 | Memoria: 23 MB
Tutto sembra sano.
Ma supponiamo di trovare:
13:30:01 >>> INIZIO DELLA CORSA | PID: 17432
13:35:01 >>> INIZIO DELLA CORSA | PID: 17501
13:40:01 >>> INIZIO DELLA CURVA | PID: 17588
senza corrispondenza CRON END.
Ora le cose diventano interessanti.
Il tuo programma di lavoro sta facendo esattamente quello che hai chiesto.
Il WHMCS, tuttavia, non tornerà più.
Passo 2: Trova la task di automazione WHMCS che si blocca
Sapendo che cron.php Gli appesi sono utili.
Conoscere dove Se è appeso è molto meglio.
Il WHMCS fornisce due ulteriori hook che possono essere utili:
PreAutomationTask
PostAutomationTask
Possiamo quindi estendere il nostro hook di debug:
<?php
if (!defined("WHMCS")) {
die("This file cannot be accessed directly");
}
/**
* WHMCS Cron Debug
*/
add_hook('PreCronJob', 1, function ($vars) {
logActivity(
'[CRON DEBUG] >>> CRON START'
. ' | PID: ' . getmypid()
. ' | Time: ' . date('Y-m-d H:i:s')
. ' | Memory: ' . round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
);
});
add_hook('PreAutomationTask', 1, function ($vars) {
$task = $vars['task'] ?? null;
$taskName = 'UNKNOWN';
if (is_object($task)) {
try {
$taskName = method_exists($task, 'getName')
? $task->getName()
: get_class($task);
} catch (\Throwable $e) {
$taskName = get_class($task);
}
}
logActivity(
'[CRON DEBUG] --> TASK START'
. ' | Task: ' . $taskName
. ' | PID: ' . getmypid()
. ' | Time: ' . date('Y-m-d H:i:s')
. ' | Memory: ' . round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
);
});
add_hook('PostAutomationTask', 1, function ($vars) {
$task = $vars['task'] ?? null;
$completed = $vars['completed'] ?? null;
$taskName = 'UNKNOWN';
if (is_object($task)) {
try {
$taskName = method_exists($task, 'getName')
? $task->getName()
: get_class($task);
} catch (\Throwable $e) {
$taskName = get_class($task);
}
}
logActivity(
'[CRON DEBUG] <-- TASK END'
. ' | Task: ' . $taskName
. ' | Completed: ' . var_export($completed, true)
. ' | PID: ' . getmypid()
. ' | Time: ' . date('Y-m-d H:i:s')
. ' | Memory: ' . round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
);
});
add_hook('AfterCronJob', 1, function ($vars) {
logActivity(
'[CRON DEBUG] <<< CRON END'
. ' | PID: ' . getmypid()
. ' | Time: ' . date('Y-m-d H:i:s')
. ' | Memory: ' . round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB'
);
});
Ora il registro delle attività diventa molto più utile:
>>> CRON START
--> INIZIA LA TASK | Task: ProcessRenewals
INIZIA LA TASK | Task: AutoSuspensions
FINE DEL LAVORO | Obiettivo: Auto-sospensioni
--> INIZIA LA TASK | Task: DomainSync
E poi... niente.
Cinque minuti dopo:
>>> CRON START
Questo è un indizio molto valido.
Se DomainSync comincia ma il suo corrispettivo PostAutomationTask se non compare mai, è il primo posto da indagare.
Il problema potrebbe non essere necessariamente interno a WHMCS stesso. La procedura potrebbe richiedere l’attesa di un’API per i registrar, un servizio DNS, un gateway di pagamento, un modulo di provisioning o un altro servizio esterno.
Ma almeno ora sappiamo da dove iniziare a scavare.
Che, in termini di debugging, equivale a circa il 90% della battaglia.
Passo 3: Non fidatevi solo di WHMCS — osservate il processo da fuori
C'è una limitazione all'approccio precedente.
Stiamo utilizzando WHMCS per indagare su WHMCS.
È utile, ma da un punto di vista filosofico è discutibile.
Se PHP si blocca, WHMCS non funziona fin dall’inizio dell’inizializzazione o l’esecuzione rimane bloccata in un punto diverso dagli hook monitorati, il nostro sistema di registrazione potrebbe non avere mai l’opportunità di dirci cosa è successo.
Per questo motivo, possiamo aggiungere un secondo livello di monitoraggio al di fuori di WHMCS.
Crea uno script shell come questo:
cron_debug.sh
con:
#!/bin/bash
LOG="/home/USER/cron_debug.log"
echo "========================================" >> "$LOG"
echo "$(date '+%Y-%m-%d %H:%M:%S') START cron - wrapper PID $$" >> "$LOG"
START=$(date +%s)
/usr/local/bin/php -q /path/to/whmcs/crons/cron.php >> "$LOG" 2>&1
EXITCODE=$?
END=$(date +%s)
DURATION=$((END - START))
echo "$(date '+%Y-%m-%d %H:%M:%S') END cron - exit=$EXITCODE duration=${DURATION}s" >> "$LOG"
Fai sì che sia eseguibile:
chmod +x cron_debug.sh
In seguito, sostituite temporaneamente il vostro normale comando cron con:
*/5 * * * * /home/USER/cron_debug.sh
Ora monitoriamo il processo PHP dal punto di vista del sistema operativo.
Un'esecuzione normale potrebbe produrre:
29 agosto 2026 13:30:01 START cron - wrapper PID 3345 29 agosto 2026 13:30:14 END cron - exit=0 durata=13s
29 agosto 2026 13:35:01 START cron - wrapper PID 3401 29 agosto 2026 13:35:11 END cron - exit=0 durata=10s
Molto meglio.
Sappiamo ora che PHP ha effettivamente restituito il controllo allo shell.
Ma questo:
13:30:01 START cron - wrapper PID 3345
13:30:14 FINE cron - exit=0 durata=13s
13:35:01 START cron - wrapper PID 3401
13:40:01 START cron - wrapper PID 3478
13:45:01 START cron - wrapper PID 3532
Non è molto confortante.
Il processo del 13:35 non è mai stato ripreso.
E ora dietro a questo processo si accumulano ulteriori processi cron.
Passo 4: Verifica l'esistenza di processi cron sovrapposti
Su un server Linux un altro test estremamente semplice è:
grep -af cron.php
In alternativa:
ps aux | grep cron.php
Durante un'esecuzione normale del crono, potrebbe capitare di vedere qualcosa del genere:
12345 php -q /home/user/whmcsdata/crons/cron.php
Qualche secondo dopo, dovrebbe scomparire.
Invece ho trovato questo:
12345 php -q /home/user/whmcsdata/crons/cron.php 12401 php -q /home/user/whmcsdata/crons/cron.php 12488 php -q /home/user/whmcsdata/crons/cron.php 12542 php -q /home/user/whmcsdata/crons/cron.php
è un chiaro indicatore che qualcosa non funziona come previsto.
Molti processi cron possono causare una miriade di problemi divertenti:
- conflitto di database;
- Richieste API eseguite simultaneamente;
- operazioni duplicate;
- automazione ritardata;
- consumo eccessivo di memoria;
- serrature;
- time-out;
- apparentemente guasti casuali.
“Interessante”, ovviamente, nel senso molto specifico di “system administrator” del termine.
Passo 5: Misurare quanto tempo impiega ogni attività WHMCS
Una volta risolti i problemi di base, si può apportare un'ulteriore miglioria utile: misurare il tempo di esecuzione delle singole attività di automazione.
Questo aiuta a identificare le attività che, tecnicamente parlando, sono già completate, ma che richiedono un tempo inaspettatamente lungo.
Per esempio:
Processo di rinnovo ............... 0,82 secondi Auto sospensioni ............... 1,14 secondi Tasse di sospensione ............. 0,31 secondi Processo di attivazione dei domini .
In questo caso nulla è tecnicamente “bloccato”.
Ma DomainSync Sembra certamente meritevole di una tazza di caffè e di un po' di attenzione.
Una semplice implementazione può memorizzare il timestamp di inizio per ogni task e calcolare il tempo trascorso durante il processo. PostAutomationTask incendi.
Per il debug temporaneo, anche informazioni di base sulla cronologia dei tempi possono rivelarsi estremamente utili poiché ci permettono di distinguere tra:
una missione che non finisce mai e una missione che finisce, ma che impiega un tempo infinito.
Questi sono due problemi molto diversi.
Cosa può causare il blocco del crono di WHMCS?
Una volta identificata la task problematico, la prossima domanda è perché.
Non esiste una risposta univoca, ma alcuni sospettati comuni sono:
API esterne. I moduli di registrazione, i gateway di pagamento, i sistemi di provisioning e altre integrazioni potrebbero essere in attesa di un server remoto che non risponde correttamente.
Problemi di rete. Gli errori di risoluzione del DNS, i problemi del firewall, la perdita della connettività IPv6 o i problemi di routing possono rendere la richiesta HTTP molto più lunga del previsto.
Limiti di esecuzione del PHP. Verifica max_execution_time, Limite di memoria e configurazione PHP specifica per la CLI. Ricordate che la configurazione PHP utilizzata dalla CLI può essere diversa da quella utilizzata dal vostro server web.
Problemi con il database. Le query lente, gli accessi alla tabella o l'esaurimento delle risorse del database possono trasformare una semplice attività automatizzata in un processo molto lungo.
Moduli WHMCS di terze parti. Gli hook e i moduli aggiuntivi eseguono il codice all'interno di WHMCS. Una integrazione non corretta può quindi influire sull'intero processo di automazione.
I vostri propri ganci. Sì, purtroppo.
Quel bel hook di 300 righe che hai scritto alle 2 di notte perché “è solo una soluzione temporanea” fa ora parte dell’elenco dei sospettati.
Benvenuti nello sviluppo di software.
La frequenza cronologica e quella delle attività non sono la stessa cosa
C'è un altro aspetto importante che talvolta causa confusione.
Corso:
*/5 * * * *
Non significa che ogni attività di automazione WHMCS venga eseguita ogni cinque minuti.
Significa che l'automazione WHMCS è invocato ogni cinque minuti.
Successivamente WHMCS determina quali attività programmate devono essere eseguite durante tale esecuzione particolare.
Questo è importante durante la risoluzione dei problemi intermittenti.
Se il cron normalmente si avvia in dieci secondi ma, misteriosamente, rimane in sospeso una volta al giorno, non biasimate immediatamente il cronogramma di cinque minuti.
Guarda quale attività di automazione viene eseguita solo durante l'esecuzione problematico.
Spesso è lì che inizia la parte interessante.
Una strategia utile per il debug
Quando indagiamo su un cron cron cron di WHMCS sospetto, normalmente desideriamo una visibilità a tre livelli diversi:
Sistema operativo
↓
Processo cron.php di PHP
↓
Attività di automazione WHMCS
La shell wrapper ci dice se il processo PHP viene effettivamente avviato e terminato.
PreCronJob e Dopo CronJob diteci se l'automazione di WHMCS entra e esce normalmente.
PreAutomationTask e PostAutomationTask diteci cosa succede all'interno del ciclo di automazione.
Unite i tre elementi e otterrete un rapporto vagamente simile a quello:
“A volte il crono di WHMCS sembra rimanere bloccato.”
può diventare qualcosa di molto più utile:
13:35:01 cron.php avviato
13:35:03 Il servizio DomainSync è iniziato
13:40:01 è iniziato un altro processo cron.php
13:45:01 ha iniziato un altro processo cron.php
Il servizio DomainSync non è mai stato ripristinato.
Ora abbiamo qualcosa che possiamo davvero analizzare.
Considerazioni finali
I problemi con Cron sono particolarmente fastidiosi perché l'automazione dovrebbe essere invisibile.
Quando tutto funziona, nessuno se ne accorge.
Quando qualcosa non funziona, il primo sintomo può comparire ore dopo, sotto forma di fattura mancante, di un promemoria di rinnovo non inviato o di un’attività automatizzata che non è stata eseguita misteriosamente.
Per questo motivo, durante la debugginte dell’automazione WHMCS, non chiedete solo:
“Ha iniziato cron?”
Domanda:
“È finita?”
E poi:
“Cosa è successo esattamente tra quei due eventi?”
I computer sono creature straordinariamente letterali.
Se li si pone le domande giuste (e si registrano le risposte), di solito alla fine confessano.