2

私のウェブサイトは、誰かが PM (プライベート メッセージ) を送信するたびに、私のユーザーに電子メールを送信します。「SITE NAMEで誰かがあなたにメッセージを送信しました。ログインして表示してください」という行に沿って何かが表示されます。

現時点では、私のサイトはあまり人気がないので、これを行う私の現在の方法は、パフォーマンスに関して問題はありませんでした:

    // code that sends pm here...

    // code that stores pm in messages table here...

    // notify user by emailing them right away
    mail($user_email, $subject, $message);

基本的には、PM が送信されるたびにメール機能が実行され、その場でメッセージが送信されます。したがって、100 件のメッセージが送信されるたびに、mail() が 100 回呼び出されます。

私のサイトの人気が高まり、より多くのユーザーがより多くの PM を訪れるようになると予想しているため、現在の方法ではパフォーマンスの悪夢になると思います。だから私は代わりにこのようにすることを考えていました:

// get the last message that was accounted for by the last cron
$query = mysql_query(" SELECT `last_checked_id` FROM `settings` ");
$last_checked_id = mysql_fetch_array($query);


$user_emails = array();

// get all messages that were added to this table since the last time this cron ran
$query = mysql_query(" SELECT `recipient_id`, `message_id` FROM `messages` WHERE `message_id` > '$last_checked_id' ");

$i = 0;
while($row = mysql_fetch_array($query)) {

    if($i == 0) {
        // set this as the last message processed
        mysql_query(" UPDATE `settings` WHERE `last_checked_id` = '". $row['message_id'] ."' ");
    }

    // only put this user in the to email list if he hasn't been added already (since there can be multiple messages for the same user but we need to notify him only once) 
    if(!in_array($row['recipient_id'], $user_emails)) {
        array_push($user_emails, $row['recipient_id']);     
    }
}
$i++;

// send email to all users at one
mail(implode(',', $user_emails), $subject, $message);

このスクリプトを cron として設定し、1 時間ごとに実行することができます。すべての電子メールは一度に送信され、メール関数は 1 回だけ呼び出されます。唯一の欠点は、ユーザーが PM を受信して​​もすぐには通知されず、1 時間以内に 1 回通知されることです。しかし、それは大したことではなく、私が一緒に暮らすことができるものではありません.

私の質問は次のとおりです。

  • cron メソッドの方がパフォーマンスが大幅に優れているか、それとも増加は無視できるか
  • これはほとんどの大規模サイトが行う方法ですか? または、より良い方法がありますか、確立されたライブラリのメイバイですか?

ありがとう。

4

3 に答える 3

1

メールをmysqlテーブルに挿入できます(emailoutgoing)

また、「3」分ごとに実行される cron ジョブを使用すると、未送信 (100 件?) のメールをテーブルから取得し、送信して、行を送信済みとしてマークできます。

于 2012-04-18T20:11:31.983 に答える
0

まず、マイクBのコメントのリンクを読んでください。

第二に、あなたのコードにはいくつかの面白い失敗モードがあります-それは失敗する可能性があり、すべてのメールを送信済みとしてマークし、誰も知ることはありません。CRONおよびその他の無人プロセス(一般的なWebサイトを含む)の重要な点は、問題が発生したときにそれを知る必要があるということです。メールを送信した後、最後に「update」ステートメントを配置することを検討します。何が起こっているかを追跡できるように、ある種のログを記録します。

第三に、このメールを「宛先」フィールドのこれらすべての人に送信しないでください。ミロが言うように、これはスパムの餌ですが、ユーザーはおそらく持っているはずの情報よりも多くの情報にさらされます。彼らはランダムな他のメールアドレスを知っています。たまたま1時間以内にPMを持っていたあなたのサイトのユーザー。あなたが出会い系サイトやソーシャルネットワークを構築しているなら、それはほぼ間違いなく人々を怒らせるでしょう。

最後に、私が取り組んだ他の同様の要件を持つサイトには、デーモン/サービススタイルのプロセスによって監視される「イベント」テーブルがある傾向がありました。デーモンは、何をすべきかについて賢明な決定を下します。実際にはこれは必要ありませんでしたが、複数のスレッド、さらには複数のマシンでの実行に適したソリューションを設計しました。

したがって、次のような「イベント」テーブルがある場合があります。

eventID    eventDate    eventType     eventStatus     eventMeta
-------------------------------------------------------------------
1          1 Feb 2012        PM           NEW         <from>bob@banana.com</from><to>alice@passionfruit.com</to>
2          1 Mar 2012        PM           COMPLETE    <from>fred@pear.com</from><to>jennifer@avocado.com</to> 

デーモンは、eventStatusがNEWであるレコードを常にスキャンし、それらを「進行中」に設定し、それらを処理してから、ステータスを完了に設定します。

これにより、システムで何が起こっているかを確認できます。レコードが1秒以上「進行中」の場合、何かが壊れています。「NEW」レコードの数が増え続け、「complete」レコードの数が増えない場合は、何かが壊れています。

于 2012-04-18T23:55:37.323 に答える
0

私の理解が正しければ、すべての人にまったく同じメールを送信することになりますか? その場合、電子メール アドレスに bcc フィールドを使用する必要があります。そうしないと、全員が他の受信者を見ることになりますが、その場合、スパム対策エンジンで問題が発生する可能性があります。 to または cc フィールドに)。

ただし、ユーザーごとにパーソナライズされたメールを送信することを検討する必要があります (メッセージの送信者やメッセージの一部にスニーク プレビューを追加すると、ユーザーはより熱心になります)。

于 2012-04-18T22:29:07.257 に答える