使用USR2重启Unicorn似乎无法重新加载production.rb的设置。

24

我正在运行独角兽(unicorn)并尝试实现零停机重启。

到目前为止,一切都很顺利,主进程分叉并启动了4个新的工作进程,然后杀死旧的进程,所有人都很开心。

我们的脚本发送以下命令来重启独角兽:

kill -s USR2 `cat /www/app/shared/pids/unicorn.pid`
表面上一切看起来都很好,但事实证明独角兽没有重新加载production.rb。(每次部署时,我们都将config.action_controller.asset_host的值更改为一个带有预编译资产的新CDN容器端点。)
用这种方式重新启动独角兽后,资产主机仍指向旧版本。进行“真正”的重启(即:停止主进程,然后从头开始再次启动独角兽)可获取新的配置更改。
在我们的独角兽配置文件中设置了preload_app为true。
你有何想法?

你的 unicorn.rb 配置是否尝试在 .oldbin 上终止进程?请参考解决方案:http://jessewolgamott.com/blog/2012/01/02/the-one-where-unicorn-does-not-update/ - Jesse Wolgamott
一旦重启完成并且工作进程已准备就绪,ps -ef | grep unicorn 只会显示主进程和四个工作进程,这绝对杀死了旧的主进程。在发出USR2信号之前,主进程的pid与旧的主进程的pid不同。 - Michael Shimmins
2个回答

24

我猜想你的独角兽进程是在旧的生产目录而不是新的生产目录中重新启动的——换句话说,如果你在 unicorn.rb 中的工作目录是 <capistrano_directory>/current,你需要确保在尝试重新启动独角兽之前进行符号链接。

这就解释了为什么手动停止和启动它们可以正常工作:你很可能是在 post-deploy 时进行的操作,这导致它们在正确的目录中启动。

你在部署过程的哪个阶段重启独角兽呢?你应该确保在新的发布目录被链接为当前目录后发送 USR2 信号。

如果这样做没有帮助,请分享你的 unicorn.rb 和 deploy.rb 文件到 gist 上,这将有助于更轻松地调试这个问题。


5
感谢您间接回答了我的问题!符号链接完成后,重启正在进行,但是您让我找对了地方。Unicorn配置文件中的工作目录设置为File.expand语句,该语句解析为符号链接的目标而不是符号链接本身。我将其更改为符号链接的绝对路径,现在可以完美运行。 - Michael Shimmins
嗨,如果我从shell手动发送USR2信号,但新配置没有被采用,可能是什么原因? - Phương Nguyễn
@MichaelShimmins你能发一下具体的修改内容吗?我有点困惑。我已经尝试了大约一天,但仍然无法让它工作。 - Anirudhan J
@AnirudhanJ - 虽然已经有一段时间了(将近两年),但我查看了git历史记录,似乎这是更改内容:`- working_directory File.expand_path('../..', FILE)
  • working_directory '/www/lexim/current'`。
- Michael Shimmins
谢谢Michael。我尝试了各种方法,最终硬编码了working_directory的绝对路径。我很想知道是否有任何方法可以保持working_directory的动态性。 - Anirudhan J
显示剩余2条评论

7
请记住: unicorn.rb中的工作目录应该是: /your/cap/directory/current
不应该是: File.expand_path("../..", FILE)
因为unicorn和Linux软链接分叉错误:软链接不能正常工作。
例如:
cd current #current是指向另一个目录的软链接
... ...
当我们获取我们的工作目录时,我们得到的是绝对路径而不是“current”中的路径。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接