cod*_*ger 9 ruby ruby-on-rails upstart unicorn
好吧,这正在融化我的大脑.这可能与我不理解Upstart以及我应该理解的事实有关.提前抱歉,这个问题很长.
我正在尝试使用Upstart来管理Rails应用程序的Unicorn主进程.这是我目前的/etc/init/app.conf
:
description "app"
start on runlevel [2]
stop on runlevel [016]
console owner
# expect daemon
script
APP_ROOT=/home/deploy/app
PATH=/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:$PATH
$APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production # >> /tmp/upstart.log 2>&1
end script
# respawn
Run Code Online (Sandbox Code Playgroud)
这很好 - 独角兽开始很棒.不太好的是,检测到的PID不是独角兽大师,而是一个sh
过程.这本身并不是那么糟糕 - 如果我没有使用自动化的Unicorn零停机时间部署策略.因为我发送-USR2
给我的独角兽大师后不久,一个新的主人产生了,旧的主人死了......这个sh
过程也是如此.所以Upstart认为我的工作已经死了,如果我愿意,我不能再用它重新启动restart
或停止它stop
.
我玩过配置文件,试图将-D添加到Unicorn线(如下$APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production -D
:)以守护Unicorn,我添加了这expect daemon
条线,但这也没有用.我也试过expect fork
了.所有这些事情的各种组合都可能导致start
和stop
挂起,然后Upstart对工作状态感到困惑.然后我必须重新启动机器来修复它.
我认为Upstart在检测何时/如果Unicorn正在分叉时遇到问题,因为我ruby-local-exec
在我的$APP_ROOT/bin/unicorn
脚本中使用了rbenv + shebang .这里是:
#!/usr/bin/env ruby-local-exec
#
# This file was generated by Bundler.
#
# The application 'unicorn' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path('unicorn', 'unicorn')
Run Code Online (Sandbox Code Playgroud)
此外,ruby-local-exec
脚本如下所示:
#!/usr/bin/env bash
#
# `ruby-local-exec` is a drop-in replacement for the standard Ruby
# shebang line:
#
# #!/usr/bin/env ruby-local-exec
#
# Use it for scripts inside a project with an `.rbenv-version`
# file. When you run the scripts, they'll use the project-specified
# Ruby version, regardless of what directory they're run from. Useful
# for e.g. running project tasks in cron scripts without needing to
# `cd` into the project first.
set -e
export RBENV_DIR="${1%/*}"
exec ruby "$@"
Run Code Online (Sandbox Code Playgroud)
所以exec
我在那里担心.它启动了一个Ruby进程,它启动了Unicorn,它可能会或可能不会自我守护,这一切都是从一个sh
进程发生的......这让我严重怀疑Upstart跟踪所有这些废话的能力.
我正在努力做甚么可能吗?根据我的理解,expect
Upstart中的节只能告诉(通过daemon
或fork
)期望最多两个叉子.
Mic*_*ade 15
您的新贵作业需要进行配置,以便新贵真正知道它分叉的次数.它只能分叉一次或两次,不能再分叉.
在unix land中,有两个关键的系统调用,便于运行程序:fork
和exec
.
fork
复制调用它的进程.一个进程调用fork
,它将控制权返回给两个进程.每个进程必须从fork返回的值中识别它(父对象或子对象)(有关详细信息,请参见手册页).
exec
运行一个新程序,替换调用的进程exec
.
当你只是在shell中运行一个命令时,shell调用fork
创建一个具有自己id的新进程,并且新进程(在某些设置之后)立即调用exec
以启动你键入的命令.这是大多数程序运行的方式,无论是shell还是窗口管理器或其他任何程序.请参阅C中的系统函数,该函数在大多数脚本语言中也有变体.
如果你认为它效率低下,你可能是对的.这就是自从以前几天在unix中完成它的方式,而且很明显没人会改变游戏.其中一个原因是有很多东西没有被替换exec
,包括(有时)打开的文件,以及进程的用户和组ID.
另一个原因是花了很多精力来提高fork
效率,而且他们实际上做得非常好 - 在现代的unix中(在CPU的帮助下)fork
实际上只复制了很少的过程.我想没有人愿意把所有的工作扔掉.
并且,(暂停效果)进程pid.
展示:
mslade@mickpc:~$ echo $$
3652
mslade@mickpc:~$ bash
mslade@mickpc:~$ echo $$
6545
mslade@mickpc:~$ exec bash
mslade@mickpc:~$ echo $$
6545
mslade@mickpc:~$ exit
exit
mslade@mickpc:~$ echo $$
3652
Run Code Online (Sandbox Code Playgroud)
大多数流行语言都有fork和exec的变体,包括shell,C,perl,ruby和python.但不是java.
因此,考虑到所有这一切,您需要做的是让新手工作正常工作,确保它与upstart认为的那样分叉次数相同.
在exec
Ruby中,本地高管行实际上是一件好事,它可以防止叉.也load
没有启动新进程,它只是将代码加载到现有的ruby解释器中并运行它.
但是你的shell脚本在这行中分叉:
$APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production # >> /tmp/upstart.log 2>&1
Run Code Online (Sandbox Code Playgroud)
为了防止这种情况,您可以将其更改为
exec $APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production # >> /tmp/upstart.log 2>&1
Run Code Online (Sandbox Code Playgroud)
如果你这样做,AFAICT独角兽根本不应该分叉,你也不需要告诉新贵要求分叉.
归档时间: |
|
查看次数: |
3990 次 |
最近记录: |