У меня массив мобильных номеров, около 50 000. Я пытаюсь обрабатывать и отправлять массовые SMS на эти номера, используя сторонний API, но браузер замерзает в течение нескольких минут. Я ищу лучший вариант.
Обработка данных включает проверку типа мобильного номера (например, CDMA), назначение уникальных идентификаторов всем номерам для дальнейших ссылок, проверка уникальных сборов за сеть / страну и т. Д.
Я думал о очередности данных в базе данных и использовании cron для отправки около 5 тыс. Партиями каждую минуту, но это займет много времени, если будет много сообщений. Каковы мои другие варианты?
Я использую Codeigniter 2 на сервере XAMPP.
Я бы написал два сценария:
Файл 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>
Файл 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
в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
-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
Я предполагаю, что эти числа находятся в базе данных, поэтому вам следует добавить новый столбец под названием isSent (или как вам нравится).
Этот следующий параграф, который вы набрали, должен быть поставлен в очередь и, возможно, сделан ночью / еженедельно / в случае необходимости. Если у вас нет определенной причины, это не должно делаться навалом по требованию. Вы даже можете добавить столбец в db, чтобы увидеть, когда он был последний раз проверен, чтобы, если число не было проверено, по крайней мере, за X дней, вы можете выполнить проверку этого числа по требованию.
Обработка данных включает проверку типа мобильного номера (например, CDMA), назначение уникальных идентификаторов всем номерам для дальнейших ссылок, проверку уникальных сборов за сеть / страну и т. Д.
Но это все еще возвращает вас к тому же вопросу о том, как это сделать для 50 000 номеров одновременно. Поскольку вы упомянули задания cron, я предполагаю, что у вас есть SSH-доступ к вашему серверу, что означает, что вам не нужен браузер. Эти задания cron могут выполняться через командную строку как таковую:
/ usr / bin / php /home/username/example.com/myscript.php
Моя рекомендация состоит в том, чтобы обрабатывать 1000 номеров за раз каждые 10 минут через cron и время, сколько времени потребуется, а затем сохранить его в БД. Поскольку вы используете задание cron, похоже, что это не чувствительные к времени SMS-сообщения, поэтому они могут быть распространены. Как только вы узнаете, сколько времени понадобилось для запуска этого скрипта 50 раз (50 * 1000 = 50 тыс.), Вы можете обновить свое задание cron, чтобы работать чаще / реже.
$time_start = microtime(true); set_time_limit(0); function doSendSMS($phoneNum, $msg, $blah); $time_end = microtime(true); $time = $time_end - $time_start; saveTimeRequiredToSendMessagesInDB($time);
Кроме того, возможно, вы заметили set_time_limit (0), это скажет PHP не истекать тайм-аут после 30 секунд. Если вы можете изменить файл PHP.ini, вам не нужно вводить эту строку кода. Даже если вы можете редактировать файл PHP.ini, я по-прежнему рекомендую не изменять эту функцию, так как вы можете захотеть, чтобы другие страницы были в тайм-ауте.
Если это не одноразовая ситуация, подумайте над разработкой лучшего решения.
То, что вы в основном хотите, это очередь, которую может обрабатывать связанный с браузером процесс, и рабочие процессы 1-N могут читать и обновлять.
Помещение работы в очередь должно быть довольно недорогим – возможно, множество простых инструкций INSERT для SQL RDBMS.
Затем у вас может быть демона или два (или 100, распределенных на нескольких серверах), которые считываются из очереди и обрабатываются. Вы захотите быть осторожными здесь и избегать двух рабочих, которые берут на себя ту же задачу, но это не сложно скопировать.
Таким образом, ваш рабочий процесс, связанный с браузером, – это: нажмите кнопку, которая заставит кучу вещей быть добавленными в очередь, а затем перенаправляется на какой-то интерфейс «статус очереди», где пользователь может наблюдать за системой, чтобы пережевывать всю свою работу.
Такая система хороша, потому что ее легко масштабировать по горизонтали.
EDIT: ответ Christian Sciberras идет в этом направлении, за исключением того, что браузер заканчивает движение с обеих сторон (он добавляет в очередь, затем управляет рабочим процессом)
Cronjob был бы вашим лучшим выбором, я не понимаю, почему это займет больше времени, чем делать это в браузере, если ваша единственная проблема на данный момент – это время выхода браузера.
Если вы настаиваете на том, чтобы сделать это через браузер, то другое решение будет делать это в партиях, скажем 1000 и перенаправляясь на один и тот же сценарий, но с некоторой ссылкой на то, где он встал до последнего времени в переменной $ _GET.