【问题标题】:On Heroku, using Ruby on Rails, I want to identify individual web servers在 Heroku 上,使用 Ruby on Rails,我想识别单个 Web 服务器
【发布时间】:2015-10-13 08:34:08
【问题描述】:

当 Heroku 上的应用程序重新启动时,我想运行一些设置任务。但是,我只希望它们运行一次。

如果我将任务放在初始化程序中并且我设置了多个网络测功机,那么每个测功机都会运行该任务。

是否可以识别单个网络测功机,也许哪个是第一个启动的?

【问题讨论】:

  • 你说的是 rake 任务吗?这些设置任务会影响数据库吗?如果您手动运行这些任务,您将如何运行它们?

标签: ruby-on-rails ruby heroku


【解决方案1】:

我怀疑您是否可以有效地(阅读:轻松)为任何 Web 进程分配任务管理的唯一所有权,因为您永远不知道哪个 Dyno 将首先关闭以及在生成新的 Dyno 之前多长时间。

即:

  • 如果要生成的第一个 Dyno 是所有者,则任务管理上的“锁定”可能会永远存在......即使第一个 Dyno 关闭并且其他 Dyno 继续工作。

    李>
  • 如果最后生成的 Dyno 是所有者,如果所有者死亡,则在生成新的 Dyno 之前不会执行任何任务(这可能需要一段时间)。

另一方面,您的任务似乎已经在持久存储中。

如果任务是使用数据库事务签出的,或者(对于非 SQL 存储)使用单线程数据库(例如带有 List 的 Redis),您可能会让所有 Dynos 执行任务,而不会执行任何任务超过一次。

...

另一个因简单性和可管理性而备受青睐的选择是使用单个工作人员 Dyno 来执行后台任务。这个 Dyno 将运行一个单独的脚本,可能会与 web dynos 共享一些代码(也可能不会)。

如果我为多个网络 Dynos 支付 Heroku,那么只有为这些任务部署一个工作人员 Dyno 才有意义。

EDIT(你可以忽略这个,这只是一些想法)

尽管最好的解决方案可能是使用单个工作人员 Dyno,但这里还有一些想法。

运行时标志

我想到了这个想法,因为您暗示能够缩小到单个 Dyno 会很好......

您可以使用在Procfile 中设置的运行时标志,这将告诉特定 Dyno 处理任务或不处理任务。在运行时,您可以检查 ARGV 数组中的标志。

这里是一个实验性的例子 Procfile 与 Rails 应用程序的这种区别:

web: bundle exec rails server -p $PORT run_tasks
onlyweb: bundle exec rails server -p $PORT

缩放时,确保只缩放运行 Dynos 的非任务:

heroku ps:scale web=1 onlyweb=4

在您的应用程序中,您可以在运行时检查:

if ARGV.include? 'run_tasks'
   # initialize tasks for background handling.
end

用于激活任务处理的 API

另一种可能性是使用Kernel.at_exit 和 HTTP API 调用的组合。

这个方案有点像设置“标签”的数字游戏,大概应该包括以下几个步骤:

  1. 创建一个接受“标签”的 HTTP 路由。收到此类请求后,接收 Dyno 将成为执行 Dyno 的任务(将变为“IT”),初始化他们的任务堆栈并将其 UUID 存储在数据库中(您可以为此使用require 'securerandom'; SecureRandom.uuid)。

  2. 在每个任务之间,让“IT”测功机通过检查其 UUID 是否仍然是数据库中的 UUID 来检查它是否仍然是“IT”。

  3. 创建一个初始化序列,其中最后一个网络 Dyno 接管任务处理(新玩家总是变成“IT”)。

  4. 使用Kernel.at_exit 设置回调,如果退出的 Dyno 是执行 Dyno(“IT”)的任务,它将尝试“标记”新的 Dyno...

这些步骤应确保始终存在执行 Dyno 的任务,即使在动态放大或缩小时也是如此。

但是,现在我想到了,这可能被认为是初始事务概念的变体,因为对 UUID 的审查和从任务堆栈中签出的任务可能都发生在事务中:-/

【讨论】:

  • 谢谢,很好的答案。在理想的世界中,单独的工人将是最佳选择。但是,能够将单个测功机与 Heroku 一起使用也很好...... ;)
  • 使用事务的想法很好,我花了一些时间探索。它仍然存在不知道测功机何时被破坏的问题。但这超出了问题的范围。
  • 接受,因为它是对问题的可靠答案。
  • 不过,我越想越觉得你是对的。我正在尝试做的不适合多网络测功机/无工人测功机模型。
  • 感谢您的反馈。我认为如果所有 Dynos 都在轮询任务,一次使用事务执行一项任务,它们都可以一起工作,无论哪个关闭或何时关闭都没有关系......但我想它对你不起作用...... ..我还有两个想法,我会尽快更新我的答案。
猜你喜欢
  • 1970-01-01
  • 2011-06-22
  • 2016-08-06
  • 2011-01-02
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 2014-07-29
相关资源
最近更新 更多