【问题标题】:Sending emails asynchronously: spool, queue, and cronjob/daemon异步发送电子邮件:假脱机、队列和 cronjob/daemon
【发布时间】:2012-11-24 16:28:14
【问题描述】:

我想异步发送电子邮件以获得更快、更轻松的 http 响应,但我正在为许多新概念而苦苦挣扎。

例如,文档谈到了spool。它说我应该使用带有文件的假脱机,然后使用命令发送电子邮件。但是我应该如何运行该命令?如果我将 cronjob 设置为每 1 分钟执行一次该命令(cron 中可用的最小值),用户将不得不平均等待 30 秒才能发送他们的电子邮件(例如,注册电子邮件)。

所以我想改用队列。我已经在使用RabbitMQBundle 进行图像处理(例如,缩略图创建)。但我只定期使用这个,所以它是在 cronjob 中使用的。

也许我应该创建一个daemon,它始终等待新邮件到达电子邮件队列并尽快发送?

【问题讨论】:

  • 延迟 30 秒有什么问题?就像你说的那样:一个cron作业每1分钟执行一个命令,命令本身会详细说明队列。
  • @Gremo 问题是如果服务器负载不大,我应该可以立即发送注册邮件。图像处理也是如此,想象一下我接受用户上传的图像。让他们为每次提交等待 30 秒(更不用说 1 分钟)会损害用户体验。
  • 那么我认为不需要恶魔。您可以从 PHP 本身以异步方式立即假脱机并触发命令。
  • @Gremo 这会为每封电子邮件创建一个进程,不好。

标签: symfony rabbitmq daemon amqp swiftmailer


【解决方案1】:

解决方案是将每封电子邮件发送到一个队列,然后通过服务使用该队列。我的服务非常简单,它只是将项目从队列中取出,其中每个项目都是一个包含 from、to、body 等的数组,然后发送该电子邮件。我正在使用使 Rabbit 更易于使用的 Thumper:github.com/videlalvaro/Thumper。我确保服务始终使用“sv”(来自 Runit):smarden.org/runit/sv.8.html。您可以使用您喜欢的任何其他服务或守护程序管理器。

【讨论】:

    【解决方案2】:

    我遇到了和你一样的问题。你最后是怎么解决你的问题的?

    目前我在 crontab 中运行一个小脚本以便循环运行:

    <?php
    include('/var/www/vendor/symfony/symfony/src/Symfony/Component/Filesystem/LockHandler.php');
    use Symfony\Component\Filesystem\LockHandler;
    
    $lock = new LockHandler('mailer:loop');
    if ($lock->lock()) {
        system('cd /var/www && php app/console swiftmailer:spool:send');
        sleep(1);
        $lock->release();
        shell_exec('cd /var/www && php LoopMailer.php > /dev/null 2>/dev/null &');
    }
    

    它不是很干净,但它可以完成他的工作。

    【讨论】:

    • 是的,我通过使用我提到的 Rabbit 消息队列解决了这个问题。任何异步的我都会将它发送到一个队列,该队列由 cronjob 或守护进程(我使用 linux 程序“sv”管理)使用。
    • 就我而言,我没有看到任何使用 RabbitMQ 的理由。使用它的目的是什么,数据库不够用吗?我也没有看到 RabbitMQ 与解决 1 分钟问题有什么关系?
    • 使用 RabbitMQ,我会在邮件在队列中消耗后立即发送,而不是每 1 分钟一次。
    • 但是 RabbitMQ 不能发送电子邮件,它是一个简单的排队系统。因此你必须有一个服务消费这个队列?我真的不明白...
    • 是的,这就是“守护进程”的意思。
    【解决方案3】:

    您需要 2 项服务,一项用于假脱机消息,另一项用于发送即时电子邮件。检查this

    【讨论】:

    • 谢谢,但这不是我想要的。我想假脱机/排队所有电子邮件,以避免在触发发送电子邮件的每个请求上注入 switfmailer(它非常重)。我认为理想的解决方案是向 Rabbit 消息队列添加一条消息,由守护进程负责发送电子邮件。这样,如果我说每 5 秒只有 1 个电子邮件请求,队列将工作得非常快,并且会立即发送电子邮件。如果我在 1 秒内突然收到 999 个电子邮件请求,我的服务器不会受到影响:用户将不得不等待他们的电子邮件,但 http 响应仍然会非常快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 2022-08-13
    • 1970-01-01
    • 2011-05-06
    相关资源
    最近更新 更多