2011-04-03 19 views
13

Ho una serie di numeri di cellulare, circa 50.000. Sto cercando di elaborare e inviare SMS di massa a questi numeri utilizzando API di terze parti, ma il browser si bloccherà per alcuni minuti. Sto cercando un'opzione migliore.Elaborazione di grandi quantità di dati in PHP senza timeout del browser

trattamento dei dati consiste nel verificare il tipo numero di cellulare (ad es CDMA), l'assegnazione di ID univoci a tutti i numeri per un ulteriore riferimento, verificare la presenza di network/paese oneri unici, ecc

ho pensato di fare la coda dei dati in il database e l'utilizzo di cron per inviare circa 5k per batch ogni minuto, ma ci vorrà del tempo se ci sono molti messaggi. Quali sono le mie altre opzioni?

Sto utilizzando Codeigniter 2 sul server XAMPP.

risposta

36

vorrei scrivere due script:

file index.php:

<iframe src="job.php" frameborder="0" scrolling="no" width="1" height="1"></iframe> 
<script type="text/javascript"> 
    function progress(percent){ 
     document.getElementById('done').innerHTML=percent+'%'; 
    } 
</script><div id="done">0%</div> 

File job.php:

set_time_limit(0);     // ignore php timeout 
ignore_user_abort(true);    // keep on going even if user pulls the plug* 
while(ob_get_level())ob_end_clean(); // remove output buffers 
ob_implicit_flush(true);    // output stuff directly 
// * This absolutely depends on whether you want the user to stop the process 
// or not. For example: You might create a stop button in index.php like so: 
//  <a href="javascript:window.frames[0].location='';">Stop!</a> 
//  <a href="javascript:window.frames[0].location='job.php';">Start</a> 
// But of course, you will need that line of code commented out for this feature to work. 

function progress($percent){ 
    echo '<script type="text/javascript">parent.progress('.$percent.');</script>'; 
} 

$total=count($mobiles); 
echo '<!DOCTYPE html><html><head></head><body>'; // webkit hotfix 
foreach($mobiles as $i=>$mobile){ 
    // send sms 
    progress($i/$total*100); 
} 
progress(100); 
echo '</body></html>'; // webkit hotfix 
+2

risposta meravigliosa, grazie mille. // continua anche se l'utente estrae la presa (Molto divertente) – elf1984

+0

@Christian La soluzione funziona meglio su FireFox e IE, ma google Chrome freezed, in qualsiasi altro modo? – elf1984

+1

Safari Webkit (utilizza anche din Chrome) presenta alcuni problemi con la funzione di avanzamento di PHP. Ho trovato una soluzione, ti ricontatterò ... ** Modifica: ** Risolto. – Christian

1

Sto assumendo questi numeri sono in un database, se così si dovrebbe aggiungere una nuova colonna intitolata isSent (o qualsiasi altra cosa vogliate).

Questo paragrafo che hai digitato dovrebbe essere messo in coda e probabilmente fatto notte/settimana/quando appropriato. A meno che tu non abbia una ragione specifica, non dovrebbe essere fatto alla rinfusa su richiesta. È anche possibile aggiungere una colonna al db per vedere quando è stata controllata l'ultima volta in modo che se un numero non è stato controllato in almeno X giorni, è possibile eseguire un controllo su quel numero su richiesta.

trattamento dei dati consiste nel verificare mobili tipo di numero (ad esempio, CDMA), l'assegnazione di ID univoci a tutti i numeri per un ulteriore riferimento, verificare la presenza di network/paese oneri unici, ecc

ma che ancora ti riporta alla stessa domanda su come eseguire questa operazione per 50.000 numeri contemporaneamente. Dato che hai citato i cron job, suppongo tu abbia un accesso SSH al tuo server, il che significa che non hai bisogno di un browser. Questi posti di lavoro cron possono essere eseguiti tramite la riga di comando in quanto tale:

/usr/bin/php /home/username/example.com/myscript.php

La mia raccomandazione è di elaborare 1.000 numeri alla volta ogni 10 minuti tramite cron e per calcolare il tempo necessario, quindi salvarlo in un DB. Dal momento che stai utilizzando un cron job, non sembra che questi siano messaggi SMS sensibili al tempo in modo che possano essere distribuiti. Una volta compreso il tempo di esecuzione di questo script per 50 volte (50 * 1000 = 50k), è possibile aggiornare il cron job per eseguirlo più o meno frequentemente.

$time_start = microtime(true); 
set_time_limit(0); 

function doSendSMS($phoneNum, $msg, $blah); 

$time_end = microtime(true); 
$time = $time_end - $time_start; 
saveTimeRequiredToSendMessagesInDB($time); 

Inoltre, potreste aver notato un set_time_limit (0), questo vi dirà PHP per non timeout dopo i 30 secondi di default. Se si è in grado di modificare il file PHP.ini, non è necessario inserire questa riga di codice. Anche se sei in grado di modificare il file PHP.ini, ti consiglio comunque di non modificare questa funzione in quanto potresti desiderare il timeout di altre pagine.

http://php.net/manual/en/function.set-time-limit.php

0

cronjob sarebbe la soluzione migliore, non vedo il motivo per cui ci vorrebbe più che farlo nel browser se il vostro unico problema al momento è la tempistica del browser fuori.

Se si insiste a farlo tramite il browser, l'altra soluzione lo farebbe in gruppi di dire 1000 e reindirizzando allo stesso script ma con qualche riferimento a dove si è alzato fino all'ultima volta in una variabile $ _GET.

1

Se questo non è un tipo di situazione una tantum, considerare la progettazione di una soluzione migliore.

Ciò che in sostanza si desidera è una coda a cui il processo associato al browser può scrivere e che i processi di lavoro 1-N possono leggere e aggiornare.

Il lavoro in coda dovrebbe essere piuttosto economico, forse un po 'di semplici istruzioni INSERT su un RDBMS SQL.

Quindi è possibile avere un daemon o due (o 100, distribuiti su più server) che leggono dalla coda e elaborano le cose. Dovrai stare attento qui ed evitare che due lavoratori assumano lo stesso compito, ma non è difficile da codificare.

Quindi il flusso di lavoro del browser-bound è: clicca qualche tasto che provoca un sacco di roba per essere aggiunto alla coda, quindi reindirizzare a qualche interfaccia "stato della coda", dove l'utente può vedere il sistema di masticare attraverso tutto il loro lavoro .

Un sistema come questo è bello, perché è facile scalare orizzontalmente in un certo senso.

EDIT: risposta cristiana Sciberras' sta andando in questa direzione, ad eccezione del browser finisce per guidare entrambi i lati (si aggiunge alla coda, poi guida il processo di lavoro)

Problemi correlati