Heroku - 由于多个 Dynos 导致的问题

发布于 2024-10-21 01:53:39 字数 312 浏览 1 评论 0原文

在我的 Rails 应用程序中,我使用 SendGrid 解析 API 将邮件发送到我的服务器。 SendGrid 的 Parse API 有时会提交同一封电子邮件两次。

当我收到一封已发布的邮件时,我将其放入 IncomingMail 模型中。因此,为了防止这种双重提交问题,我在处理时查看每个传入邮件,以查看最后一分钟内表中是否有重复项。这在开发上测试得很好,它捕获了所有的双重提交。

现在我把它推送到了 Heroku,在那里我有 2 个以上的测功机,但它不起作用。我的猜测是它与复制有关。那么既然如此,具有多个服务器的可扩展站点如何处理这样的事情呢?

谢谢

In my rails app, I'm using the SendGrid parse API which posts mail to my server. Every now and then SendGrid's Parse API submits the same email twice.

When I get a posted mail I place it in the IncomingMail model. so in order to prevent this double submitting issue, I look at each IncomingMail when processing to see if there is a duplicate in the table within the last minute. That tested great on development, it caught all the double submissions.

Now I pushed that live to heroku, where I have 2+ dynos and it didn't work. My guess being that it has something to do with replication. So that being the case, how can scalable sites with multiple server deal with something like this?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤还要旧人安 2024-10-28 01:53:39

您应该考虑使用后台作业队列。 Heroku 有“Workers”(即延迟作业)。您不是立即发送电子邮件,而是将其推送到队列中。然后需要将一名或多名 Heroku “工人”添加到您的帐户中,每个工人都会按顺序拉取作业。这意味着在发送电子邮件之前可能会有短暂的延迟(取决于负载),但这种延迟不会呈现给用户,并且如果有大量电子邮件要发送,您只需添加更多工作人员即可。

在每个用户操作上等待电子邮件提供商等外部服务是危险的,因为任何网络问题都会导致您的网站瘫痪,因为多个用户必须“等待”他们的 HTTP 请求得到响应,而 Heroku 会被这些第三方调用阻止。

在这种情况下,对于工人来说,每项工作都会失败,但会重试并最终成功。

You should look at using a background job queue. Heroku has "Workers" (which was Delayed Job). Rather than sending the email immediately, you push it onto the queue. Then one or more Heroku 'workers' need to be added to your account, and each one will pull jobs in sequence. This means there can be a short delay (depending on load) before the email is sent, but this delay is not presented to the user, and should there be a lot of email to send you just add more workers.

Waiting for an external service like an email provider on each user action is dangerous because any network problem will take down your site as several users have to 'wait' for their HTTP requests to be responded to while Heroku is blocked with these third party calls.

In this situation with workers each job would fail but would be retried and eventually succeed.

绅士风度i 2024-10-28 01:53:39

这听起来可能是交易问题。如果您有多个工作人员同时运行,他们的操作可能会“交错”。例如,这一系列事件将导致发送 2 封邮件。

Worker A:检查现有记录,但没有找到
Worker B:检查现有记录,但没有找到
工作人员 A:发布到 Sendgrid
Worker B:发布到 Sendgrid

您可以将所有内容包装在事务中以防止这种情况发生。像这样的事情应该可以做到。

class IncomingMail < ActiveRecord::Base

  def check_and_send(email_address)
    transaction do
      # your existing code for preventing duplicates and sending
    end
  end

end

This sounds like it could be a transaction issue. If you have multiple workers running simultaneously their operation may be 'interleaved'. For instance this sequence of events would result in 2 mails being sent.

Worker A : Checks for an existing record and doesn't find one
Worker B : Checks for an existing record and doesn't find one
Worker A : Post to Sendgrid
Worker B : Post to Sendgrid

You could wrap everything in a transaction to keep this from happening. Something like this should do it.

class IncomingMail < ActiveRecord::Base

  def check_and_send(email_address)
    transaction do
      # your existing code for preventing duplicates and sending
    end
  end

end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文