2011-04-03 17 views
13

Mam tablicę numerów mobilnych, około 50 000. Próbuję przetwarzać i wysyłać masowe wiadomości SMS na te numery, korzystając z interfejsu API innej firmy, ale przeglądarka zawiesi się na kilka minut. Szukam lepszej opcji.Przetwarzanie dużych ilości danych w PHP bez limitu czasu przeglądarki

Przetwarzanie danych polega na sprawdzeniu mobilną typ numeru (np CDMA), przypisywanie unikatowych identyfikatorów do wszystkich numerów do dalszego odwoływania, sprawdź sieciowych/kraju unikalnych opłat itp

myślałem kolejkowania danych w bazy danych i używanie crona do wysyłania około 5k co kilka minut, ale to zajmie trochę czasu, jeśli pojawi się wiele wiadomości. Jakie są moje inne opcje?

Używam Codeigniter 2 na serwerze XAMPP.

Odpowiedz

36

chciałbym napisać dwa scenariusze:

plików 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> 

pliku 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

Wspaniała odpowiedź, dziękuję bardzo. // Kontynuuj, nawet jeśli użytkownik ściąga wtyczkę (bardzo zabawne) – elf1984

+0

@Christian Rozwiązanie działa lepiej na FireFox i IE, ale Google Chrome zamarzł, czy nie ma innego wyjścia? – elf1984

+1

Safari Webkit (również używa din Chrome) ma pewne problemy z funkcją postępu PHP. Znalazłem poprawkę, wrócę do ciebie z tym ... ** Edycja: ** Naprawiono. – Christian

1

Jestem zakładając te liczby są w bazie danych, jeśli tak, należy dodać nowa kolumna zatytułowana isSent (lub cokolwiek innego).

Ten napisany przez ciebie akapit powinien znajdować się w kolejce i być może być wykonywany noc/tydzień/w razie potrzeby. Jeśli nie masz konkretnego powodu, nie należy go wykonywać zbiorczo na żądanie. Możesz nawet dodać kolumnę do bazy danych, aby zobaczyć, kiedy był ostatnio sprawdzany, więc jeśli liczba nie została zaznaczona co najmniej X dni, możesz sprawdzić tę liczbę na żądanie.

Przetwarzanie danych polega na sprawdzeniu numeru telefonu komórkowego typu (np CDMA), przypisywanie unikatowych identyfikatorów do wszystkich numerów do dalszego odwoływania, sprawdź sieciowych/kraju unikalnych opłat itp

ale wciąż prowadzi cię z powrotem do tego samego pytania, jak to zrobić dla 50 000 liczb na raz. Ponieważ wspomniałeś o pracach crona, zakładam, że masz dostęp do serwera SSH, co oznacza, że ​​nie potrzebujesz przeglądarki. Te crona mogą być wykonywane za pomocą wiersza poleceń, takich jak:

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

Moja rada jest taka, aby przetworzyć 1000 numerów w czasie każdego 10 minut przez cron i do czasu, jak długo to trwa, a następnie zapisz go do DB. Ponieważ używasz zadania cron, nie wydaje się, że są to wiadomości SMS o czasie ważności, więc można je rozłożyć. Kiedy już wiesz, ile czasu zajmie uruchomienie tego skryptu 50 razy (50 * 1000 = 50k), możesz zaktualizować swoje zadanie cron, aby działało częściej/rzadziej.

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

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

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

Również można zauważyli set_time_limit (0), to powie PHP nie czas, po domyślnych 30 sekund. Jeśli możesz zmodyfikować plik PHP.ini, nie musisz wpisywać tego wiersza kodu. Nawet jeśli jesteś w stanie edytować plik PHP.ini, nadal nie zalecamy zmiany tej funkcji, ponieważ możesz chcieć, aby inne strony przestały działać.

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

0

cronjob byłoby najlepiej, nie widzę dlaczego zajęłoby dłużej niż robi to w przeglądarce, jeśli jedynym problemem w tej chwili jest czas na przeglądarkę.

Jeśli nalegasz na zrobienie tego za pomocą przeglądarki, to drugim rozwiązaniem będzie robienie tego w partiach po 1000 i przekierowanie do tego samego skryptu, ale z pewnym odniesieniem do miejsca, w którym doszło do ostatniej chwili w zmiennej $ _GET.

1

Jeśli nie jest to sytuacja jednorazowa, rozważ zaprojektowanie lepszego rozwiązania.

To, czego zasadniczo potrzebujesz, to kolejka, do której może pisać Twój proces związany z przeglądarką, i że procesy robocze 1-N mogą odczytywać i aktualizować.

Umieszczenie pracy w kolejce powinno być raczej niedrogie - być może kilka prostych instrukcji INSERT do SQL RDBMS.

Następnie możesz mieć demona lub dwa (lub 100, rozproszone na wielu serwerach), które czytają z kolejki i przetwarzają rzeczy. Będziesz tu chciał zachować ostrożność i unikać dwóch pracowników podejmujących to samo zadanie, ale nie jest to trudne do zakodowania.

Przepływ pracy związany z przeglądarką to: kliknięcie przycisku, który powoduje dodanie kilku rzeczy do kolejki, a następnie przekierowanie do interfejsu "stanu kolejki", w którym użytkownik może obserwować, jak system przeszukuje całą swoją pracę .

System taki jak ten jest ładny, ponieważ łatwo jest skalować w poziomie.

EDIT: Odpowiedź Christian Sciberras' idzie w tym kierunku, z wyjątkiem przeglądarka kończy się jazda po obu stronach (to dodaje do kolejki, a następnie napędza proces roboczy)

Powiązane problemy