Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

यूनिकॉर्न nginx से कैसे बात करता है - रूबी में यूनिक्स सॉकेट्स का परिचय

रूबी एप्लिकेशन सर्वर आमतौर पर nginx जैसे वेब सर्वर के साथ उपयोग किए जाते हैं। जब उपयोगकर्ता आपके रेल ऐप से किसी पृष्ठ का अनुरोध करता है, तो nginx एप्लिकेशन सर्वर को अनुरोध सौंपता है। लेकिन यह वास्तव में कैसे काम करता है? nginx गेंडा के साथ कैसे बात करता है?

सबसे कुशल विकल्पों में से एक यूनिक्स सॉकेट का उपयोग करना है। आइए देखें कि वे कैसे काम करते हैं! इस पोस्ट में हम सॉकेट की मूल बातें से शुरू करेंगे, और अपना खुद का सरल एप्लिकेशन सर्वर बनाकर समाप्त करेंगे जो कि nginx द्वारा प्रॉक्सी किया गया है।

यूनिकॉर्न nginx से कैसे बात करता है - रूबी में यूनिक्स सॉकेट्स का परिचय सॉकेट प्रोग्राम को एक दूसरे के साथ बात करने की अनुमति देते हैं जैसे कि वे किसी फ़ाइल को लिख रहे हों या पढ़ रहे हों। इस उदाहरण में, यूनिकॉर्न सॉकेट बनाता है और कनेक्शन के लिए इसकी निगरानी करता है। Nginx तब सॉकेट से जुड़ सकता है और यूनिकॉर्न के साथ बात कर सकता है।

यूनिक्स सॉकेट क्या है?

यूनिक्स सॉकेट एक प्रोग्राम को दूसरे से इस तरह से बात करने देता है जो फाइलों के साथ काम करने जैसा दिखता है। वे एक प्रकार के आईपीसी, या अंतर-प्रक्रिया संचार हैं।

सॉकेट के माध्यम से पहुंच योग्य होने के लिए, आपका प्रोग्राम पहले एक सॉकेट बनाता है और उसे एक फ़ाइल की तरह डिस्क पर "सहेजता है"। यह आने वाले कनेक्शन के लिए सॉकेट की निगरानी करता है। जब यह एक प्राप्त करता है, तो यह डेटा को पढ़ने और लिखने के लिए मानक IO विधियों का उपयोग करता है।

रूबी कुछ वर्गों के माध्यम से आपको यूनिक्स सॉकेट के साथ काम करने के लिए आवश्यक सब कुछ प्रदान करती है:

  • यूनिक्स*सर्वर * - यह सॉकेट बनाता है, इसे डिस्क पर सहेजता है, और आपको नए कनेक्शन के लिए इसकी निगरानी करने देता है।

  • यूनिक्स*सॉकेट * - आईओ के लिए मौजूदा सॉकेट खोलें।

नोट:  अन्य प्रकार के सॉकेट मौजूद हैं। सबसे विशेष रूप से टीसीपी सॉकेट। लेकिन यह पोस्ट केवल यूनिक्स सॉकेट से संबंधित है। आप अंतर किस तरह बताएंगे? यूनिक्स सॉकेट में फ़ाइल नाम होते हैं।

सबसे सरल सॉकेट

हम दो छोटे कार्यक्रमों को देखने जा रहे हैं।

पहला "सर्वर" है। यह केवल UnixServer . का एक उदाहरण बनाता है वर्ग, फिर server.accept . का उपयोग करता है एक कनेक्शन की प्रतीक्षा करने के लिए। जब यह एक कनेक्शन प्राप्त करता है, तो यह अभिवादन का आदान-प्रदान करता है।

यह ध्यान देने योग्य है कि दोनों accept और readline मेथड्स प्रोग्राम के निष्पादन को तब तक रोकते हैं जब तक कि उन्हें वह नहीं मिल जाता जिसकी वे प्रतीक्षा कर रहे हैं।

require "socket"

server = UNIXServer.new('/tmp/simple.sock')

puts "==== Waiting for connection"
socket = server.accept

puts "==== Got Request:"
puts socket.readline

puts "==== Sending Response"
socket.write("I read you loud and clear, good buddy!")

socket.close

तो हमारे पास एक सर्वर है। अब हमें केवल एक क्लाइंट चाहिए।

नीचे दिए गए उदाहरण में, हम अपने सर्वर द्वारा बनाए गए सॉकेट को खोलते हैं। फिर हम अभिवादन भेजने और प्राप्त करने के लिए सामान्य IO विधियों का उपयोग करते हैं।

require "socket"

socket = UNIXSocket.new('/tmp/simple.sock')

puts "==== Sending"
socket.write("Hello server, can you hear me?\n")

puts "==== Getting Response"
puts socket.readline 

socket.close

प्रदर्शित करने के लिए, हमें पहले सर्वर को चलाने की आवश्यकता है। फिर हम क्लाइंट चलाते हैं। आप परिणाम नीचे देख सकते हैं:

यूनिकॉर्न nginx से कैसे बात करता है - रूबी में यूनिक्स सॉकेट्स का परिचय एक साधारण UNIX सॉकेट क्लाइंट/सर्वर इंटरैक्शन का उदाहरण। ग्राहक बाईं ओर है। सर्वर दाईं ओर है।

nginx के साथ इंटरफेस करना

अब जब हम जानते हैं कि एक यूनिक्स सॉकेट "सर्वर" कैसे बनाया जाता है, तो हम आसानी से nginx के साथ इंटरफेस कर सकते हैं।

मेरा विश्वास मत करो? आइए एक त्वरित प्रूफ-ऑफ-कॉन्सेप्ट करते हैं। मैं इसे सॉकेट से प्राप्त होने वाली हर चीज़ का प्रिंट आउट लेने के लिए ऊपर दिए गए कोड को अनुकूलित करने जा रहा हूँ।

require "socket"

# Create the socket and "save it" to the file system
server = UNIXServer.new('/tmp/socktest.sock')

# Wait until for a connection (by nginx)
socket = server.accept

# Read everything from the socket
while line = socket.readline
  puts line.inspect
end

socket.close

अब अगर मैं nginx को /tmp/socktest.sock पर सॉकेट के अनुरोधों को अग्रेषित करने के लिए कॉन्फ़िगर करता हूं मैं देख सकता हूं कि nginx कौन सा डेटा भेज रहा है। (चिंता न करें, हम एक मिनट में कॉन्फ़िगरेशन पर चर्चा करेंगे)

जब मैं एक वेब अनुरोध करता हूं, तो nginx मेरे छोटे सर्वर को निम्न डेटा भेजता है:

यूनिकॉर्न nginx से कैसे बात करता है - रूबी में यूनिक्स सॉकेट्स का परिचय

बहुत अच्छा! यह केवल एक सामान्य HTTP अनुरोध है जिसमें कुछ अतिरिक्त शीर्षलेख जोड़े गए हैं। अब हम एक वास्तविक ऐप सर्वर बनाने के लिए तैयार हैं। लेकिन पहले, nginx कॉन्फ़िगरेशन पर चर्चा करते हैं।

Nginx को इंस्टाल करना और कॉन्फ़िगर करना

यदि आपके पास अपनी विकास मशीन पर पहले से nginx स्थापित नहीं है, तो एक सेकंड लें और इसे अभी करें। OSX पर होमब्रे के माध्यम से यह वास्तव में आसान है:

brew install nginx

अब हमें स्थानीयहोस्ट पर अनुरोधों को अग्रेषित करने के लिए nginx को कॉन्फ़िगर करने की आवश्यकता है:2048 एक अपस्ट्रीम सर्वर पर /tmp/socktest.sock नामक सॉकेट के माध्यम से। . वह नाम कुछ खास नहीं है। इसे केवल हमारे वेब सर्वर द्वारा उपयोग किए जाने वाले सॉकेट नाम से मेल खाना चाहिए।

आप इस कॉन्फ़िगरेशन को /tmp/nginx.conf . में सहेज सकते हैं और फिर nginx -c /tmp/nginx.conf कमांड के साथ nginx चलाएँ इसे लोड करने के लिए।

# Run nginx as a normal console program, not as a daemon
daemon off;

# Log errors to stdout
error_log /dev/stdout info;

events {} # Boilerplate

http {

  # Print the access log to stdout
  access_log /dev/stdout;

  # Tell nginx that there's an external server called @app living at our socket
  upstream app {
    server unix:/tmp/socktest.sock fail_timeout=0;
  }

  server {

    # Accept connections on localhost:2048
    listen 2048;
    server_name localhost;

    # Application root
    root /tmp;

    # If a path doesn't exist on disk, forward the request to @app
    try_files $uri/index.html $uri @app;

    # Set some configuration options on requests forwarded to @app
    location @app {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass https://app;
    }

  }
}

यह कॉन्फ़िगरेशन nginx को सामान्य टर्मिनल ऐप की तरह चलाने का कारण बनता है, डेमॉन की तरह नहीं। यह सभी लॉग को stdout में भी लिखता है। जब आप nginx चलाते हैं तो यह कुछ इस तरह दिखना चाहिए:

यूनिकॉर्न nginx से कैसे बात करता है - रूबी में यूनिक्स सॉकेट्स का परिचय Nginx नॉन-डेमन मोड में चल रहा है।

एक DIY एप्लिकेशन सर्वर

अब जब हमने देख लिया है कि nginx को हमारे प्रोग्राम से कैसे जोड़ा जाए, तो एक साधारण एप्लिकेशन सर्वर बनाना बहुत आसान मामला है। जब nginx हमारे सॉकेट के लिए एक अनुरोध अग्रेषित करता है तो यह एक मानक HTTP अनुरोध होता है। थोड़ी सी छेड़छाड़ के बाद मैं यह निर्धारित करने में सक्षम था कि यदि सॉकेट एक वैध HTTP प्रतिक्रिया देता है, तो इसे ब्राउज़र में प्रदर्शित किया जाएगा।

नीचे दिया गया एप्लिकेशन कोई भी अनुरोध लेता है और टाइमस्टैम्प प्रदर्शित करता है।

require "socket"

# Connection creates the socket and accepts new connections
class Connection

  attr_accessor :path

  def initialize(path:)
    @path = path
    File.unlink(path) if File.exists?(path)
  end

  def server
    @server ||= UNIXServer.new(@path)
  end

  def on_request
    socket = server.accept
    yield(socket)
    socket.close
  end
end


# AppServer logs incoming requests and renders a view in response
class AppServer

  attr_reader :connection
  attr_reader :view

  def initialize(connection:, view:)
    @connection = connection
    @view = view
  end

  def run
    while true
      connection.on_request do |socket|
        while (line = socket.readline) != "\r\n"
          puts line 
        end
        socket.write(view.render)
      end
    end
  end

end

# TimeView simply provides the HTTP response
class TimeView
  def render
%[HTTP/1.1 200 OK

The current timestamp is: #{ Time.now.to_i }

]
  end
end


AppServer.new(connection: Connection.new(path: '/tmp/socktest.sock'), view: TimeView.new).run

अब अगर मैं nginx के साथ-साथ अपनी स्क्रिप्ट को भी फायर करता हूं, तो मैं लोकलहोस्ट पर जा सकता हूं:2048। अनुरोध मेरे ऐप पर भेजे जाते हैं। और प्रतिक्रियाएँ ब्राउज़र द्वारा प्रदान की जाती हैं। बहुत बढ़िया!

यूनिकॉर्न nginx से कैसे बात करता है - रूबी में यूनिक्स सॉकेट्स का परिचय HTTP अनुरोध हमारे सरल ऐप सर्वर द्वारा STDOUT में लॉग किए जाते हैं

और यहाँ हमारे परिश्रम का गौरवशाली फल है। निहारना! एक टाइमस्टैम्प!

यूनिकॉर्न nginx से कैसे बात करता है - रूबी में यूनिक्स सॉकेट्स का परिचय सर्वर एक टाइमस्टैम्प लौटाता है जो ब्राउज़र में प्रदर्शित होता है


  1. एक मैट्रिक्स क्या है और रूबी में इसका उपयोग कैसे करें?

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

  1. रूबी में स्ट्रक्चर और ओपनस्ट्रक्चर का उपयोग कैसे करें?

    रूबी में स्ट्रक्चर क्या है? एक संरचना एक अंतर्निहित रूबी वर्ग है, इसका उपयोग नए वर्ग बनाने के लिए किया जाता है जो मूल्य वस्तुओं का उत्पादन करते हैं। संबंधित विशेषताओं को एक साथ संग्रहीत करने के लिए एक मूल्य वस्तु का उपयोग किया जाता है। यहां एक उदाहरण दिया गया है : एक Point दो निर्देशांकों के साथ

  1. रूबी नेटवर्क प्रोग्रामिंग

    क्या आप रूबी में कस्टम नेटवर्क क्लाइंट और सर्वर बनाना चाहते हैं? या बस समझें कि यह कैसे काम करता है? फिर आपको सॉकेट से निपटना होगा। रूबी नेटवर्क प्रोग्रामिंग . के इस दौरे में मेरे साथ शामिल हों मूल बातें सीखने के लिए, और रूबी का उपयोग करके अन्य सर्वर और क्लाइंट से बात करना शुरू करें! तो सॉकेट क्य