如何以零停机时间更新作为守护程序运行的代码?

时间:2013-06-06 14:46:52

标签: ruby-on-rails ruby daemon

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

现在我想更新Ruby代码并通过一些Capistrano魔术部署它。

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

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

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

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

1 个答案:

答案 0 :(得分:0)

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

将数据存储在数据库中。它不一定是花哨的,它可以是磁盘上的简单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应用程序,以及关联的表单/报告/页面,并让您的守护程序和摘要代码根据其内容写入这些表。