【问题标题】:How do I update code running as a daemon with zero downtime?如何以零停机时间更新作为守护进程运行的代码?
【发布时间】:2013-06-06 14:46:52
【问题描述】:

我有一个 Ruby 守护程序正在运行,它正在收集数据,比如温度。它每隔几秒钟收集一次,一旦达到一分钟,它就会计算出高、低和平均值,然后将它们保存到数据库中。在此步骤中还将进行进一步的计算。

现在我想更新 Ruby 代码并通过 Capistrano 魔法进行部署。

现在的问题是,如果我只是停止守护进程,我不会将当前分钟保存到数据库中。如果我现在启动新的守护进程,那一分钟已经开始了,所以我认为第一分钟是“脏”的,将等待下一个完整的分钟。所以,基本上,我现在有一个差距。

我可以启动一个新的进程/守护进程,开始收集数据。一旦获得足够的数据,它就会告诉旧的守护进程关闭。但是我怎样才能在这两个守护进程之间进行通信呢?

如果有人能指出我对此的想法,我会很酷。

Rails 应用程序也可用,可在浏览器中使用。理想情况下,我也可以与之交谈。

【问题讨论】:

  • 您是否考虑过使用队列,这个队列服务器应该有良好的正常运行时间,并且有一个服务只是写入这个队列,所以其他进行计算的进程可能会有一点停机时间......跨度>

标签: ruby-on-rails ruby daemon


【解决方案1】:

规则一:如果您要收集的数据要在崩溃和重新启动时保留,请不要将其存储在内存中。尽快将它从您的代码中取出并放到磁盘上或更持久的地方。

将您的数据存储在数据库中。不必花哨,它可以是一个简单的磁盘上的 SQLite 数据库。

我强烈建议您查看Sequel ORM gem,它可以轻松处理大量 DBM。

以下是开始使用基于磁盘的 SQLite 数据库的简单方法:

require 'sequel'
DB = Sequel.connect('sqlite://temps.db')

如果您有权访问另一个 DBM,请使用它。 Sequel 让事情变得简单,只需从代码中取出数据并存储起来。

我个人有两个表和应用程序,一个用于捕获数据并将其写入原始数据表的守护程序,另一个用于读取原始数据、对其进行汇总并将其写入汇总表。第二个应用程序将定期启动,可能作为一项 cron 作业,汇总自上次汇总以来收到的所有数据,然后退出。

两个表都有时间戳字段,因此很容易检查新数据。

剩下的你自己猜。


您可以考虑使用 RabbitMQ 之类的东西作为后端,并从捕获节点向其发送消息,并让另一个节点读取消息。我认为这基本上是一个简单问题的过度设计,但这将是另一种确保数据不会在重新启动后丢失并提供使用数据库的替代方法,但没有以数据库为中心的任何优势设计。


关于即时启动新代码:

这是可能的,但我仍然会使用两个或多个应用程序与上面提到的数据库通信,以划分捕获和分析功能。这样,您就可以在不同的地方运行多个捕获应用程序,而不会让它们踩到另一个的汇总活动。一个应用程序将负责汇总数据,无论是一百万个还是一百万个捕获应用程序。这样一来,您可以取下一端或另一端,而整个应用程序仍然可以运行。

使用Signal.trap,您可以设置一个中断处理程序,例如 HUP,并通过exec 立即重新启动正在运行的代码。我会从以下内容开始:

Signal.trap('HUP') { exec($0, ARGV) }

如果您想合并您的 Rails 应用程序,请通过您的 Rails 应用程序使用的支持数据库来完成。将捕获和分析所需的表添加到该数据库,将几个模型以及关联的表单/报告/页面添加到 Rails 应用程序,并让您的守护程序和摘要代码将这些表写入他们的核心内容。

【讨论】:

  • 关于这种情况,我什至可以在另一个地方运行第二个收集守护进程,如果第一个不可用,我可以查询它......我会看看续集。
  • 我认为它仍然是最好的解决方案——我已经部分实施了。我希望有更直接的方法。我仍然可以使用“客户端”应用程序作为守护程序/循环来快速获取新数据,而不是使用 cronjob。
  • 请随意提出有关此问题的新问题,并在评论中引用我的标签以引起我的注意。祝你好运。
  • @Jan-HendrikHeuing,我添加了一些额外的 cmets 如何处理您问题的其他方面。
  • 我有原始源将数据导出到 csv。然后像想访问这些文件的网络服务。在我的应用程序中,我有一个收集守护进程,用于写入本地数据库,还有一个用于处理其他任何事情的第二个守护进程。所以我基本上可以关闭任何组件。
猜你喜欢
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 2015-07-12
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多