1

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

手动方式(不好):去你的主页看看是否有效。看看htop。跟踪日志。手动杀死独角兽。缺点:容易忘记。日志被污染,CPU 在你反应的时候被加载。

另一种解决方案:使用独角兽的preload_app true. 这将导致主进程快速失败。缺点:快乐场景中的内存消耗更高。

最佳实践: - ???

有什么方法可以巧妙地检测到独角兽大师无用地试图产生失败的孩子并阻止它?

4

2 回答 2

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 检测到它无法为您的新代码库生成任何进程时,它将停止尝试生成您的新版本并无限期地保留旧版本的进程,直到您手动给出可以的信号为新版本生成进程。同时它将所有错误记录到日志文件中,以便您分析问题。

于 2012-10-23T23:38:02.223 回答
2

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

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

它的要点是:

  1. 向独角兽主进程发送 USR2 信号,这将分叉主进程。
  2. 然后将 WINCH 发送到创建的旧主进程,这将杀死每个工人。
  3. 然后您可以向旧的主进程发送 QUIT 信号。

独角兽信号

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

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

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

独角兽控制脚本示例

于 2012-10-30T00:38:24.927 回答