13

私は約50,000の携帯電話番号の配列を持っています。サードパーティのAPIを使用してこれらの番号に一括SMSを処理して送信しようとしていますが、ブラウザが数分間フリーズします。より良いオプションを探しています。

データの処理には、携帯電話番号の種類(CDMAなど)の確認、さらに参照するためにすべての番号に一意のIDを割り当てる、ネットワーク/国の固有料金の確認などが含まれます。

データベース内のデータをキューに入れ、cronを使用して毎分約5kをバッチで送信することを考えましたが、メッセージが多い場合は時間がかかります。私の他のオプションは何ですか?

XAMPPサーバーでCodeigniter2を使用しています。

4

4 に答える 4

38

私は2つのスクリプトを書きます:

ファイル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
于 2011-04-03T23:21:34.730 に答える
1

これらの番号はデータベースにあると思います。その場合は、isSent(または好きなもの)というタイトルの新しい列を追加する必要があります。

入力したこの次の段落はキューに入れられ、場合によっては夜間/毎週/適切なときに実行される必要があります。特別な理由がない限り、オンデマンドで一括して行うべきではありません。dbに列を追加して、最後にチェックされた日時を確認することもできます。これにより、番号がX日以上チェックされていない場合は、オンデマンドでその番号のチェックを実行できます。

データの処理には、携帯電話番号の種類(CDMAなど)の確認、さらに参照するためにすべての番号に一意のIDを割り当てる、ネットワーク/国の固有料金の確認などが含まれます。

しかし、それでも、一度に50,000の番号に対してこれを行う方法についての同じ質問に戻ります。cronジョブについて言及したので、サーバーへのSSHアクセスがあると想定しています。つまり、ブラウザーは必要ありません。これらのcronジョブは、次のようにコマンドラインから実行できます。

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

私の推奨事項は、cronを介して10分ごとに一度に1,000の数値を処理し、これにかかる時間を計測してから、DBに保存することです。cronジョブを使用しているため、これらは時間に敏感なSMSメッセージではないように思われるため、拡散する可能性があります。このスクリプトが50回(50 * 1000 = 50k)実行されるのにかかった時間がわかれば、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)に気付いたかもしれません。これにより、デフォルトの30秒後にタイムアウトしないようにPHPに指示されます。PHP.iniファイルを変更できる場合は、このコード行を入力する必要はありません。PHP.iniファイルを編集できる場合でも、他のページがタイムアウトになる可能性があるため、この機能を変更しないことをお勧めします。

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

于 2011-04-04T00:36:58.290 に答える
1

これが1回限りの状況ではない場合は、より優れたソリューションのエンジニアリングを検討してください。

基本的に必要なのは、ブラウザーにバインドされたプロセスが書き込むことができるキューであり、1-Nワーカープロセスが読み取りおよび更新できるキューです。

作業をキューに入れるのはかなり安価なはずです-おそらくSQLRDBMSへの単純なINSERTステートメントの束です。

次に、キューから読み取り、処理を行うデーモンを1つまたは2つ(または100、複数のサーバーに分散)にすることができます。ここでは注意して、2人のワーカーが同じタスクを引き受けるのを避けたいと思うでしょうが、それをコーディングするのは難しくありません。

つまり、ブラウザにバインドされたワークフローは次のとおりです。ボタンをクリックすると、大量のデータがキューに追加され、「キューステータス」インターフェイスにリダイレクトされます。このインターフェイスで、ユーザーはシステムがすべての作業を噛み砕くのを見ることができます。

このようなシステムは、水平方向にかなり簡単にスケーリングできるので便利です。

編集:Christian Sciberrasの答えはこの方向に進んでいますが、ブラウザーが最終的に両側を駆動することになります(キューに追加されてから、ワーカープロセスが駆動されます)

于 2011-04-04T03:39:11.533 に答える
0

cronjobが最善の策です。現時点での唯一の問題がブラウザのタイムアウトである場合、ブラウザで実行するよりも時間がかかる理由はわかりません。

ブラウザを介してそれを行うことを主張する場合、他の解決策は、たとえば1000のバッチでそれを行い、同じスクリプトにリダイレクトしますが、$_GET変数で最後に起きた場所を参照します。

于 2011-04-04T01:43:20.400 に答える