2011-12-29 13 views
9

प्रबंधित करने के लिए अपस्टार्ट का उपयोग करना ठीक है, यह मेरे दिमाग को पिघल रहा है। इस तथ्य के साथ ऐसा कुछ हो सकता है कि मुझे अपस्टार्ट को समझ में नहीं आता है और साथ ही मुझे चाहिए। लंबे सवाल के लिए अग्रिम में खेद है।यूनिकॉर्न w/rbenv + bundler binstubs w/ruby-local-exec shebang

मैं रेल ऐप की यूनिकॉर्न मास्टर प्रक्रिया को प्रबंधित करने के लिए अपस्टार्ट का उपयोग करने का प्रयास कर रहा हूं। यूनिकॉर्न्स ऊपर महान शुरू -

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 

कि बस ठीक काम करता है: यहाँ मेरे वर्तमान /etc/init/app.conf है। इतना अच्छा नहीं है कि पीआईडी ​​का पता लगाया गया यूनिकॉर्न मास्टर का नहीं है, यह sh प्रक्रिया है। यह स्वयं में और इतना बुरा नहीं है, या तो - अगर मैं ऑटोमैटिकल यूनिकॉर्न शून्य-डाउनटाइम परिनियोजन रणनीति का उपयोग नहीं कर रहा था। क्योंकि मेरे यूनिकॉर्न मास्टर में -USR2 भेजने के कुछ ही समय बाद, एक नया मास्टर उगता है, और बूढ़ा व्यक्ति मर जाता है ... और sh प्रक्रिया भी करता है। तो अपस्टार्ट सोचता है कि मेरी नौकरी की मृत्यु हो गई है, और मैं इसे restart के साथ पुनरारंभ नहीं कर सकता या इसे stop से रोकूं यदि मैं चाहता हूं।

मैंने यूनिकॉर्न लाइन (जैसे: $APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production -D) को यूनिकॉर्न को डिमनेनाइज़ करने के लिए -D को जोड़ने की कोशिश कर कॉन्फ़िगरेशन फ़ाइल के साथ खेला है, और मैंने expect daemon लाइन जोड़ा, लेकिन यह भी काम नहीं करता था। मैंने expect fork भी कोशिश की है। उन सभी चीजों के विभिन्न संयोजन start और stop को लटकने का कारण बन सकते हैं, और फिर अपस्टार्ट नौकरी की स्थिति के बारे में वास्तव में भ्रमित हो जाता है। फिर मुझे इसे ठीक करने के लिए मशीन को पुनरारंभ करना होगा।

मुझे लगता है कि कल का नवाब का पता लगाने क्योंकि मैं अपने $APP_ROOT/bin/unicorn लिपि में rbenv + ruby-local-exec कुटिया उपयोग कर रहा हूँ जब/अगर यूनिकॉर्न forking है समस्या हो रही है। संदेश यह है:

#!/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') 

साथ ही, 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 "[email protected]" 

तो वहाँ है कि मैं बारे में चिंतित हूँ वहाँ में एक exec है। यह एक रूबी प्रक्रिया को सक्रिय करता है, जो यूनिकॉर्न को फायर करता है, जो खुद को डिमनीकृत कर सकता है या नहीं, जो सभी पहले sh प्रक्रिया से होता है ... जो मुझे इस बकवास को ट्रैक करने के लिए अपस्टार्ट की क्षमता को गंभीरता से संदेह करता है।

क्या मैं भी ऐसा करने की कोशिश कर रहा हूं? जो मैं समझता हूं, उससे अधिकतम 12 फोर्क की अपेक्षा करने के लिए अपस्टार्ट में expect स्टैन्ज़ा को केवल (daemon या fork के माध्यम से) बताया जा सकता है।

उत्तर

15

आपके अपस्टार्ट नौकरी को कॉन्फ़िगर करने की आवश्यकता है ताकि अपस्टार्ट जानता है कि यह कितनी बार फोर्क करता है। और यह केवल एक या दो बार कांटा जा सकता है, और नहीं।

यूनिक्स भूमि में दो प्रमुख सिस्टम कॉल हैं जो चल रहे प्रोग्रामों की सुविधा प्रदान करते हैं: fork और exec

fork इसे कॉल करने वाली प्रक्रिया की प्रतिलिपि बनाता है। एक प्रक्रिया fork पर कॉल करती है, और यह दो प्रक्रियाओं पर नियंत्रण वापस लौटाती है। प्रत्येक प्रक्रिया को यह पता होना चाहिए कि यह फोर्क द्वारा लौटाए गए मूल्य से (माता-पिता या बच्चा) है (विवरण के लिए मैन पेज देखें)।

execexec नामक प्रक्रिया को प्रतिस्थापित करते हुए एक नया प्रोग्राम चलाता है।

जब आप केवल एक खोल में एक कमांड चलाने के लिए, हुड के नीचे खोल fork कॉल का अपना आईडी के साथ एक नई प्रक्रिया बनाने के लिए, और कहा कि नई प्रक्रिया (कुछ सेटअप के बाद) तुरंत exec कॉल आदेश आपके द्वारा लिखे गए शुरू करने के लिए । इस प्रकार अधिकांश प्रोग्राम चलाए जाते हैं, चाहे शैल या आपके विंडो मैनेजर या जो भी हो। सी में system फ़ंक्शन देखें, जिसमें अधिकांश स्क्रिप्टिंग भाषाओं में वेरिएंट भी हैं।

यदि आपको लगता है कि यह अक्षम है, तो आप शायद सही हैं। इस तरह यह पहले के दिनों से यूनिक्स में किया गया है, और स्पष्ट रूप से कोई भी इसे बदलने के लिए गेम नहीं है। कारणों में से एक यह है कि पर कई चीजें हैं जो exec पर बदल दी गई हैं, जिनमें कभी-कभी खुली फ़ाइलें, और प्रक्रिया के उपयोगकर्ता और समूह आईडी शामिल हैं। आधुनिक Unixes में (सीपीयू की मदद से) fork वास्तव में प्रतियां बहुत प्रक्रिया के छोटे -

एक और कारण यह है कि प्रयास के एक बहुत fork कुशल बनाने में खर्च किया गया है, और वे वास्तव में इसके बारे में एक बहुत अच्छा काम किया है । मुझे लगता है कि कोई भी उस काम को फेंकना नहीं चाहता।

और, (प्रभाव के लिए रोकें) प्रक्रिया पिड।

प्रदर्शित करने के लिए:

[email protected]:~$ echo $$ 
3652 
[email protected]:~$ bash 
[email protected]:~$ echo $$ 
6545 
[email protected]:~$ exec bash 
[email protected]:~$ echo $$ 
6545 
[email protected]:~$ exit 
exit 
[email protected]:~$ echo $$ 
3652 

लोकप्रिय भाषाओं में से अधिकांश कांटा और कार्यकारी, खोल, सी, पर्ल, माणिक और अजगर सहित के रूपांतरों की है। लेकिन जावा नहीं।

तो यह सब कुछ ध्यान में रखते हुए, आपको अपने अपस्टार्ट नौकरी के काम को करने के लिए क्या करना है, यह सुनिश्चित कर लें कि यह उतनी ही बार फोर्क करता है जितना कि यह सोचता है कि यह करता है।

रूबी-स्थानीय-निष्पादन में exec लाइन वास्तव में एक अच्छी बात है, यह एक कांटा को रोकती है। load एक नई प्रक्रिया शुरू नहीं करता है, यह केवल मौजूदा रूबी दुभाषिया में कोड लोड करता है और इसे चलाता है।

हालांकि इस पंक्ति में अपने खोल स्क्रिप्ट कांटे:

$APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production # >> /tmp/upstart.log 2>&1 

इसे रोकने के लिए आप इसे

exec $APP_ROOT/bin/unicorn -c $APP_ROOT/config/unicorn.rb -E production # >> /tmp/upstart.log 2>&1 

लिए आपको लगता है कि, AFAICT गेंडा बिल्कुल कांटा नहीं करना चाहिए करते हैं बदल सकते हैं, और आपको एक कांटा की उम्मीद करने के लिए अपस्टार्ट बताने की आवश्यकता नहीं होगी।

+0

बहुत बढ़िया, इसके लिए धन्यवाद। – codykrieger

+0

एक विस्तृत उत्तर के लिए धन्यवाद! यह सिर्फ मुझे समान स्थिति में भगवान + अपस्टार्ट स्थापित करने में मदद की। – dreikanter

संबंधित मुद्दे