Best way to dynamically schedule reminder email? Anything better than cron?

核能气质少年 提交于 2019-12-03 16:00:06

Use first variant.

it may take over a minute to send out all the emails

  1. Check, if file_exists('mailing.q'); If still exists - terminate execution.
  2. Create file mailing.q
  3. send emails
  4. unlink('mailing.q');

And don't think about overhead - not in this case.

You can have a PHP script that remains running. Every set interval, query the database for emails that need to be sent in the next interval. Break that down into an array with one group for every minute. So if you choose 15 minutes, you would have an array with 15 entries, each entry having all emails that need to be sent out at that time.

You can then use forking to split the process, one handles sending the emails, the other sleeps until the next minute and splits again. To scale, you could fork multiple processes with each process handling a certain number of emails.

In a nutshell, one process manages the queue and forks other processes to handle the sending. When the queue is "empty" it gets more. You could have a cron running periodically to make sure the process hasn't died.

There is nothing particularly wrong with using cron in the options #1 and #2, I don't know what kind of app you are using, but giving users the ability to schedule to the exact minute may not be necessary. Even then, it probably wouldn't be a problem if your script marks the status of reminder as "pending" or such and any new instances of the script only send ones that aren't "pending" or "sent".

You could use Hudson or a similar app which could help with script management and would enable you to keep an eye on failures, etc. It can even send out notices when there are failures. It supports it's own java-based cron system.

If the app does get large, you certainly might want to offload this process to a separate server from your web server. You also may want to look into 3rd-party tools for sending mail, if you are not already using an external SMTP service, and see what integration tools they might have. This should also improve delivery rates, etc.

Don't confuse queuing a mail to send and actually sending the mail.

Your mail server might need fifteen minutes to send a single email. But it takes my mail(1) only 0.036s to queue a mail message for sending.

And even if you do wind up with more than 1600 emails to send per minute (good work!) you could tweak your code a little bit to start sending reminder emails probabilistically several minutes earlier, in anticipation of 'spikes' -- say, looking ahead in your database by five minutes to see if there were >1000 mails to deliver, and start queuing them with 1/5th probability, 1/4th probability, 1/3 probability, 1/2 probability, then queuing the remainders.

There is a command hostman which allows you to call a function at a specific time. That should do what you want.


This was my original suggestion:

What about a combination?

  1. Have a cron job run once a <timespan>.
  2. Have it populate a file with a timestamp => list reflecting whether there is an email before <current time> + <timespan>.
  3. Have a second cron run every minute, if the time is found in the email list file, then run the email sending script.
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!