2011-12-22 12 views
6

मैंने पॉल डीक्स की पुस्तक सेवा-ओरिएंटेड डिजाइन को RoR के साथ पढ़ना अभी समाप्त कर दिया है और मैं एक रेल 3 वेब ऐप आधारित बनाना चाहता हूं जो मैंने अभी सीखा है उस पर।एक सर्वर पर एकाधिक रेल सेवाओं को होस्ट करना + एपीआई सक्षम वेबसाइट की वास्तुकला

मुझे लगता है कि मुझे मूल आर्किटेक्चर सही मिला है, लेकिन एक साधारण सवाल मुझे अवरुद्ध कर रहा है: मुझे एक ही सर्वर पर कई आरईएसटी सेवाओं को कैसे होस्ट करना है?

यहां बताया गया है मैं पल के लिए चीजों को देखने के:

  • बनाएं * सेवा क्षुधा (UserService, XYZFeatureService, ...) सिनात्रा (मुझे लगता है) है, जो उन संसाधनों तक पहुंच के लिए बाकी अंतिमबिंदुओं प्रदान के आधार पर
  • नियंत्रक/विचार/... के साथ फ्रंट-एंड रेल ऐप रखें जो विभिन्न सेवाओं से डेटा का उपभोग करता है। उदाहरण के लिए अंतिम उपयोगकर्ता इसे http://www.myapp.com के माध्यम से एक्सेस करेंगे।
  • और आखिरकार एक बाहरी एपीआई प्रकाशित करने के लिए https://api.myapp.com/* या https://www.myapp.com/api/* पर कॉल को संभालने के लिए एक स्टैंडअलोन "एपीआई" ऐप है जो संभावित प्रमाणीकरण, थ्रॉटलिंग और इसी तरह के साथ समान सेवाओं का उपभोग करेगा।

क्या यह आपके लिए अच्छी शुरुआत की तरह लगता है?

जहां तक ​​कार्यान्वयन होता है, मैंने पुस्तक में जो पढ़ा है, उससे मैं रेल ऐप और सेवाओं के बीच संचार को संभालने के लिए रत्न बनाने की योजना बना रहा हूं (मैं कुछ खरगोश एमक्यू में फेंक सकता हूं लेकिन यह एक और कहानी है)।

हालांकि, जैसा कि मेरे पास केवल एक भौतिक सर्वर है, मैं सोच रहा हूं कि मैं उन सभी ऐप्स/सेवाओं को एक साथ कैसे रहने जा रहा हूं? मेरा पहला अनुमान स्थानीय सेवा पर प्रत्येक सेवा ऐप लॉन्च करना है: xxxx जहां xxxx प्रत्येक सेवा के लिए एक अलग अनधिकृत बंदरगाह है। मैं उन बंदरगाहों का उपयोग करने के लिए अपने रेल ऐप में प्रत्येक क्लाइंट मणि को कॉन्फ़िगर कर सकता हूं।

इसके साथ-साथ, मैं शायद रेलवे फ्रंट एंड एंड एपीआई सेवा की सेवा के लिए अपाचे 2 + पैसेंजर चलाऊंगा, जैसे कि रैक :: URLMap (या सबडोमेन का उपयोग करते हुए वर्चुअल होस्ट) का उपयोग करके अनुरोधों को प्रत्यक्ष करने के लिए सही ऐप क्या मुझे अपने पर्यावरण को उत्पादन वातावरण में चलाने के लिए पैसेंजर का उपयोग करना चाहिए?

क्या यह सही तरीका है ?! यह जो मैंने पढ़ा और सीखा है उसके साथ संगत लगता है, और यदि आवश्यक हो तो भी आसानी से कई भौतिक सर्वरों में विभाजित हो जाता है, लेकिन मैं यह सुनिश्चित करना चाहता हूं कि मुझे कुछ याद नहीं आ रहा है। क्या आप चीजों को अलग-अलग बनायेंगे?

धन्यवाद आपके इनपुट के लिए बहुत कुछ!

अद्यतन

मुख्य सवाल है मैं एक चाहते हैं जवाब देखने के लिए कर रहे हैं:

  • वर्णित वास्तुकला बाहरी API अंतिम बिंदुओं के साथ एक वेब अनुप्रयोग का निर्माण करने के लिए उचित है?
  • क्या यह अलग-अलग बंदरगाहों पर एक सर्वर पर चल रही सेवाओं के लिए ठीक है?

धन्यवाद!

+0

http://confreaks.net/videos/709-rubyconf2011-threading-versus- को देखने के बाद देखें कि आप jRuby में बदलना चाहते हैं। यात्री के साथ nginx जाने के लिए एक और आम रास्ता है। – drhenner

+0

@ user458221 धन्यवाद, मुझे इस वीडियो पर एक नज़र डालेंगे :) हालांकि मेरी चिंता इस पल के लिए वास्तुकला और डिजाइन विकल्पों के बारे में अधिक है! लेकिन मुझे लगता है कि प्रदर्शन के बारे में चिंता करने योग्य भी है ^^ –

उत्तर

0

तो इस सवाल यह है कि थोड़ा अधिक से अधिक 3 वर्ष, और मुझे लगता है कि यह एक उचित उद्देश्य से लाभ हो सकता है।

यह प्रश्न फिर से पढ़ने के लिए मजाकिया है और इसे हाल ही में ऊपर उठाया गया है जब सरल, "उच्च स्तर" उत्तर बस है: जो भी आप चाहते हैं/करना चाहते हैं!

निरीक्षण करने के लिए कोई जादू नियम नहीं है, हालांकि मुझे लगता है कि मैं उस समय की तलाश में था। कर रहे हैं, हालांकि, कुछ महत्वपूर्ण बातें ध्यान में रखने की कोशिश करने के लिए:

  • एक सर्विस ओरिएंटेड आर्किटेक्चर डिजाइनिंग मतलब है कि हम स्केलिंग के लिए तैयारी कर रहे हैं। प्रत्येक सेवा अपने आप को चलाने के लिए है और स्टैक की अन्य सेवाओं के समान सर्वर पर चलने पर निर्भर नहीं है। मत जोड़े को अपनी सेवाओं, वे

  • हालांकि "अति-तैयार" नहीं है यह स्वतंत्र रहने की जरूरत है: प्रलोभन सही वास्तुकला डिजाइन करने में बहुत समय खर्च करने के लिए अधिक है, जब क्या आप वास्तव में करने की जरूरत है क्या आपका वी 1 जहाज है!

  • जब आप अलग-अलग सेवाओं का निर्माण कर रहे हों, तो इसे आवश्यकतानुसार अधिक जटिल न बनाएं: आरईएसटी (जैसे) अंतराल के साथ एक साधारण वेब स्टैक संभवतः शुरू करने के लिए पर्याप्त होगा। RabbitMQ और अन्य संदेश कतार भी बहुत अच्छी हैं, लेकिन वे उन समस्याओं को हल करते हैं जो आपके पास वास्तव में नहीं हो सकती हैं।

  • जहां तक ​​सर्वर का संबंध है, अच्छी तरह से ... एक आदर्श दुनिया में आप प्रति सेवा एक सर्वर चाहते हैं, सभी डेटासेंटर में, एक दूसरे (या अधिक!) पर प्रतिकृति के साथ अन्य शारीरिक रूप से अलग डेटासेंटर ... इसे स्थापित करने और बनाए रखने के लिए समय और धन की आवश्यकता होती है। यदि आप एक बड़े संगठन में हैं जो ठीक हो सकता है, लेकिन यदि ऐसा है तो आपको शायद इस उत्तर को पढ़ने की आवश्यकता नहीं है।
    तो हाँ, आप छोटे से शुरू कर सकते हैं! एक या दो सर्वर, या वर्चुअलाइज्ड सर्वर के साथ "बड़ा"। यह सब चीज को प्रशासित करने या sysadmin की भर्ती में आपके आत्मविश्वास पर निर्भर करता है। एक मशीन पर्याप्त हो सकती है, और इस पर कई सेवाओं को चलाने में संकोच नहीं करते हैं, बशर्ते वे सभी एक ही सिस्टम और मेमोरी साझा कर सकें।
    आज, मैं शायद बंदरगाहों या बंदरगाहों के आधार पर सही सेवाओं के अनुरोधों को प्रेषित करने के लिए nginx का उपयोग करता हूं, और उन बंदरगाहों के बाहर से अनुरोधों को अवरुद्ध करने के लिए फ़ायरवॉल (उदाहरण के लिए शोरवाल) के साथ विभिन्न बंदरगाहों पर निजी सेवाएं चलाता हूं।

इसमें है ... जैसे मैंने कहा, वहाँ कोई जादुई जवाब है, लेकिन समाधान प्रत्येक समस्या के लिए हल करने के लिए वहाँ है वसीयत करने के लिए। जो मैंने पिछले 3 वर्षों के दौरान सीखा है, ज्यादातर मध्यम/बड़ी परियोजनाओं पर अकेले काम करना, यह है कि सरल शुरुआत करना महत्वपूर्ण है।

1

मैं अपाचे-पैसेंजर कॉम्बो और एक स्क्रिप्ट का उपयोग करता हूं (नीचे देखें) लेकिन मैंने नोड को धक्का देने वाले बेंचमार्क के बारे में बहुत कुछ पढ़ा।एक Nginx लोड-बैलेंसर के पीछे जेएस - और कम से कम webservices एपीआई प्रदान करने के लिए, यह समझ में आता है।

मेरी स्क्रिप्ट है:

def build_a_new_oxenserver() 
    site = siteurl.gsub(/\./,"_") 
    system("rake add_site['#{siteurl}','#{site}','#{id}']") if Rails.env.production? 
    default_tmpl = open(File.expand_path(Rails.root + "public/default_template.html")).read 
    tmpl = Template.create(:ox_id=>id, :name=>"first template", :content=>default_tmpl) 
    pg=Page.create(:ox_id=>id, :language_id=>1, :template_id=>tmpl.id, :title=>"Home", :menu_label=>"Zu Hause", :ancestry=>nil, :root=>true) 

    # add the Paragraph element to this ox's toolbox 
    self.elements << Element.find(1) 

    # add an Article, a Paragraph, and a Post 
    pe = PageElement.create(:element_id => Element.find(1)) 
    pe.elementable = Paragraph.create(:content=>"This is written *in bold* -") 
    pe.save 
    pg.page_elements << pe 


end 

add_site रेक उत्पादन सर्वर पर एक दूरस्थ काम करता है - आवश्यक फ़ोल्डर्स, विन्यास फाइल और लिंक की गई स्क्रिप्ट बनाने के लिए एक नया 'उदाहरण' चलाने के लिए। इस तरह से मैं अपनी सेवाओं का विस्तार करने में सक्षम हूं और थोड़ा प्रयास करके, मैं लोड-बैलेंसिंग क्षमताओं का विस्तार भी कर पाऊंगा।

कृपया देख सकते हैं कि इस समाधान एक 'साझा स्रोत' संस्करण

रेक स्क्रिप्ट इस तरह दिखता है:

# 
# rake add_site["www.domain.tld", "www_domain_tld", 131] 
desc "Task for adding new oxenserver site" 
task :add_site, :domain, :site, :ox_id do |t, args| 
    service_path = /data/www/html/app_service 
    site_string = %{ 
    <VirtualHost *:80> 
     ServerName #{args[:domain]} 
     DocumentRoot #{service_path}/sites/#{args[:site]}/public 
     PassengerAppRoot #{service_path}/sites/#{args[:site]} 
     SetEnv OX_ID #{args[:ox_id]} 
     <Directory #{service_path}/sites/#{args[:site]}/public> 
       AllowOverride all 
       Options -MultiViews 
     </Directory> 
    </VirtualHost> 
    } 
    File.open("tmp/#{args[:site]}.conf", "w") do |f| 
    f.write site_string 
    end 

    site_start = %{ 
    mv #{service_path}/current/tmp/#{args[:site]}.conf /data/apache/conf.d/#{args[:site]}.conf 
    service httpd restart 
    } 

    File.open("tmp/#{args[:site]}.sh", "w") do |f| 
    f.write site_start 
    end 

    # 
    sites_dir = "#{service_path}/sites/#{args[:site]}" 
    shared_sites_dir = "#{service_path}/shared/sites/#{args[:site]}" 
    shared_oxen_dir = "#{service_path}/shared/sites/oxen" 
    current = "#{service_path}/current" 


    # prepare system files/directories 
    system "mkdir #{sites_dir} #{shared_sites_dir} #{shared_sites_dir}/public" 
    system "cd #{sites_dir} && cp -rus #{current}/* ." 
    system "cd #{shared_sites_dir}/public && cp -r #{shared_oxen_dir}/public/* ." 
    system "cd #{shared_sites_dir} && mkdir log tmp && cd #{sites_dir} && rm -rf public log tmp && ln -s #{shared_sites_dir}/public public && ln -s #{shared_sites_dir}/log log && ln -s #{shared_sites_dir}/tmp tmp" 
    system "cd #{sites_dir} && touch tmp/restart.txt log/production.log" 
    system "mv tmp/#{args[:site]}.sh public/system/job_queue/#{args[:site]}.sh" 
end 
+0

आपके उत्तर के लिए धन्यवाद! हालांकि यह मेरे मुख्य प्रश्नों को संबोधित नहीं करता है; मैं अंत में संक्षेप में उन्हें फिर से लिखने के लिए अपनी पोस्ट संपादित करूंगा –