我在生产服务器上遇到了一个相当奇怪的独角兽问题。 虽然配置文件声明preload_app为true,但是将USR2发送到主进程不会产生任何响应,并且似乎独角兽完全忽略了该信号。 在另一台发送USR2的服务器上,将主进程更改为和(旧)状态,并成功启动新的主进程。 有问题的服务器正在使用RVM&捆绑,所以我假设它以某种方式相关(另一个是香草红宝石)。 发送USR2以外的信号(QUIT,HUP)工作正常。 有没有办法追踪幕后发生的事情? Unicorn的日志文件完全是空的。
答案 0 :(得分:10)
我怀疑你的问题可能是你的Gemfile已经改变,但是你没有以允许USR2使用新Gemfile的方式启动你的独角兽。因此,当您尝试重新启动应用程序时会崩溃。
检查/log/unicorn.log
以了解可能失败的详细信息。
如果您使用的是Capistrano,请将BUNDLE_GEMFILE指定为符号链接,例如:
run "cd #{current_path} && BUNDLE_GEMFILE=#{current_path}/Gemfile bundle exec unicorn -c #{config_path} -E #{unicorn_env} -D"
Here's a PR说明了这一点。
答案 1 :(得分:5)
我遇到了类似的问题,但我的日志清楚地确定了问题:发送USR2最初会在部署上工作,但随着部署得到清理,Unicorn主机最初启动的版本将被删除,因此尝试发送USR2信号似乎什么都不做/失败,错误日志说明:
分叉的孩子重新执行... 53 /var/www/application/releases/153565b36021c0b8c9cbab1cc373a9c5199073db/vendor/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/http_server.rb:439:in `exec':没有这样的文件或目录 - /var/www/application/releases/153565b36021c0b8c9cbab1cc373a9c5199073db/vendor/bundle/ruby/1.9.1/bin/unicorn (错误:: ENOENT)
独角兽文件在http://unicorn.bogomips.org/Sandbox.html提到了这个潜在的问题:“清理旧的修订版会导致独角兽的修订版本安装丢失而升级失败”,在我的情况下,USR2似乎“什么都不做” ”。
我正在使用Chef的应用程序配方来部署应用程序,这会创建一个跨部署共享的符号链接的vendor_bundle目录,但是调用bundle exec unicorn
仍然导致原始的Unicorn主持有包含特定版本目录的路径引用
要修复它,我必须调用bundle exec /var/www/application/shared/vendor_bundle/ruby/1.9.1/bin/unicorn
以确保Unicorn主机有一个二进制路径,从一个部署到下一个部署是有效的。一旦完成,我可以向我部署内容,kill -USR2 PID
将按宣传的方式工作。
Unicorn文档提到你可以手动更改二进制路径引用,方法是在Unicorn配置文件中设置以下内容并发送HUP以重新加载Unicorn,然后再发送USR2来分叉新的主服务器:Unicorn::HttpServer::START_CTX[0] = "/some/path/to/bin/unicorn"
对于类似情况下的某些人来说,这可能是有用的,但是我没有实现它,因为它看起来指定共享的unicorn二进制文件的绝对路径就足够了。
答案 2 :(得分:0)
我在VDS上遇到过类似的问题。 Strace'ing透露了原因:
write(2, "E, [2011-07-23T04:40:27.240227 #19450] ERROR -- : Cannot allocate memory - fork(2) (Errno::ENOMEM) <...>
尝试增加内存大小,XEN内存按需限制(在我的情况下它们太难),或者可能打开overcommit,通过后者可能会有一些严重的不良副作用,所以要小心。