如何检测和防止产生失败的独角兽工人

时间:2012-10-19 13:00:27

标签: ruby-on-rails unicorn

情况:我正在使用Rails + Unicorn,与Capistrano一起部署。有时Rails应用程序无法以生产模式启动(尽管它不是真正的生产,而是一个临时环境)。这通常是由于部署脚本或配置中的错误(因此通常无法通过测试检测到)而发生的。当发生这种情况时,独角兽主进程会杀死失败的工作者,并生成一个新的,也会失败,依此类推。在那段时间里,独角兽会消耗大量CPU并使用相同的消息污染日志。

手动方式(不太好):转到您的主页以查看其是否有效。看看htop。记录日志。手动杀死独角兽。 缺点:容易忘记。日志被污染,CPU在你做出反应时被加载。

另一种解决方案:使用独角兽的preload_app true。这将导致主进程快速失败。 缺点:在愉快的情况下更高的内存消耗。

最佳做法: - ???

有没有办法聪明地发现独角兽大师无用地试图产生失败的孩子并阻止它?

2 个答案:

答案 0 :(得分:2)

你的Capistrano剧本中有类似“独角兽开始”的东西吗?在调用该命令后立即使您的Capistrano脚本ping Unicorn。如果Unicorn在超时内没有返回预期的响应,那么您就知道出现了问题,您可以选择回滚部署或执行其他操作。

至于如何ping Unicorn,这取决于。如果您有Unicorn侦听TCP套接字,那么您可以使用curl。如果您有Unicorn侦听Unix域套接字,那么您必须编写一个连接它的小脚本,如下所示:

require 'socket'
sock = UNIXSocket.new('/path-to-unicorn.sock')
sock.write("HEAD / HTTP/1.0\r\n")
sock.write("Host: www.foo.com\r\n")
sock.write("Connection: close\r\n")
sock.write("\r\n")
if sock.read !~ /something/
  exit 1
end

但听起来像Phusion Passenger Enterprise可以很好地解决你的问题。它具有称为“部署错误抵抗”的此功能。当您部署新版本并且Phusion Passenger检测到它无法为您的新代码库生成任何进程时,它将停止尝试生成您的新版本并无限期地保留旧版本的进程,直到您手动发出信号表明它没问题为新版本生成进程。同时,它会将所有错误记录到日志文件中,以便您可以分析问题。

答案 1 :(得分:2)

我建议刷掉你的bash技能。您需要的功能已经在Unicorn中,因为它利用了Unix-y主/工作进程。

您需要一个init.d脚本。或者至少是godrb或monit。我推荐init.d脚本路由AND监控。它更复杂,但它可以更容易地被您的监控软件利用,并且还可以在重启时自动启动。

它的要点是:

  1. 将USR2信号发送到unicorn主进程,这将分叉主进程。
  2. 然后将WINCH发送到创建的旧主进程,这将终止每个worker。
  3. 然后你可以发送旧的主进程QUIT信号。
  4. Unicorn Signals

    这将启动运行新代码的新主进程,并将旧代码标记为(旧)。如果失败,旧的应该返回到先前的状态,你不应该中断,只是重启错误。这就是独角兽的美丽。您几乎可以立即部署代码。

    我使用了很多对冲词,因为我在一年多前在我的应用上做了这项工作,所以楼上有很多蜘蛛网。希望这有帮助!

    这绝不是正确的脚本。它是一个很好的起点......如果你能改进它,请随时更新要点! : - )

    Example Unicorn Control Script