Nginx में स्थान के तहत कई प्रॉक्सी एंडपॉइंट्स की सेवा


14

मेरे पास एपीआई एंडपॉइंट की एक जोड़ी है जिसे मैं /apiअलग-अलग एंडपॉइंट्स में जाने वाले सबपाथ्स के एक ही स्थान के तहत सेवा करना चाहता हूं । विशेष रूप से, मैं चाहता हूं कि वेबडीआईएस पर /apiऔर एक मालिकाना एपीआई उपलब्ध हो /api/mypath

मैं webdis एपीआई के साथ संघर्ष के बारे में चिंतित नहीं हूं क्योंकि मैं सबपाथ का उपयोग कर रहा हूं जो कि रेडिस कमांड नामों के साथ टकराव की संभावना नहीं है, और संघर्ष से बचने के लिए एपीआई के डिजाइन पर भी पूर्ण नियंत्रण है।

यहां मेरे परीक्षण सर्वर से कॉन्फ़िगर फ़ाइल है जिसे मैं हैक कर रहा हूं:

server {
  listen 80;
  server_name localhost;
  server_name 192.168.3.90;
  server_name 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # temporary hardcoded workaround
  location = /api/mypath/about {
    proxy_pass http://localhost:3936/v1/about;
  }

  location /api {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379/;
  }

  # tried this but it gives "not found" error
  #location ^~ /api/mypath/ {
  #  rewrite ^/api/mypath/(.*)$ /$1 break;
  #  proxy_pass http://localhost:3936/v1/;
  #}
  #
  #location ^~ /api {
  #  rewrite ^/api/(.*)$ /$1 break;
  #  proxy_pass http://localhost:7379/;
  #}
}

मैं अपने वर्कअराउंड को कैसे बदल सकता हूं ताकि किसी भी अनुरोध को /api/mypath/*पोर्ट 3936 में एंडपॉइंट पर जाया जा सके, और बाकी सब 7379 पोर्ट के लिए?


आपका क्या मतलब है tried this to no avail? जब आप उस स्थान को निर्देश सक्षम करते हैं तो क्या हुआ था? कनेक्शन का समय समाप्त? स्थान मिलान नहीं हुआ?
मसलगोह 22

शीघ्र के लिए धन्यवाद, यह एक नहीं मिली त्रुटि दे रहा है, आगे की जांच पर यह प्रतीत होता है कि त्रुटि मेरे एपीआई से आ रही है इसलिए यह काम कर रहा है! : डी लेकिन पुनर्लेखन नियम स्पष्ट रूप से, क्योंकि मैं यूआरएल (करने के लिए v1 जोड़ने की ज़रूरत नहीं है स्थानीय होस्ट / API / mypath / v1 / के बारे में ) ... :(
hamstar

जवाबों:


24

इसके लिए आपको फिर से लिखने की आवश्यकता नहीं है।

server {
  ...

  location ^~ /api/ {
    proxy_pass http://localhost:7379/;
  }
  location ^~ /api/mypath/ {
    proxy_pass http://localhost:3936/v1/;
  }
}

Nginx प्रलेखन के अनुसार

एक स्थान या तो एक उपसर्ग स्ट्रिंग, या एक नियमित अभिव्यक्ति द्वारा परिभाषित किया जा सकता है। पूर्ववर्ती ~*संशोधक (केस-असंवेदनशील मिलान के लिए), या ~संशोधक (केस-संवेदी मिलान के लिए) के साथ नियमित अभिव्यक्तियाँ निर्दिष्ट की जाती हैं । दिए गए अनुरोध के मिलान वाले स्थान को खोजने के लिए, nginx पहले उपसर्ग स्ट्रिंग्स (उपसर्ग स्थानों) का उपयोग करके परिभाषित स्थानों की जांच करता है। उनमें से, सबसे लंबे मिलान वाले उपसर्ग के साथ स्थान का चयन और याद किया जाता है। फिर कॉन्फ़िगरेशन फ़ाइल में उनकी उपस्थिति के क्रम में नियमित अभिव्यक्ति की जांच की जाती है। नियमित अभिव्यक्तियों की खोज पहले मैच पर समाप्त होती है, और संबंधित कॉन्फ़िगरेशन का उपयोग किया जाता है। यदि नियमित अभिव्यक्ति के साथ कोई मेल नहीं मिलता है, तो पहले याद किए गए उपसर्ग स्थान के कॉन्फ़िगरेशन का उपयोग किया जाता है।

यदि सबसे लंबे मिलान वाले उपसर्ग स्थान में ^~संशोधक है तो नियमित अभिव्यक्तियों की जाँच नहीं की जाती है।

इसलिए किसी भी अनुरोध के साथ शुरू होता है जो /api/mypath/हमेशा दूसरे ब्लॉक द्वारा परोसा जाएगा क्योंकि यह सबसे लंबे समय तक मिलान उपसर्ग स्थान है।

कोई भी अनुरोध, /api/जिसके तुरंत बाद शुरू नहीं होता है mypath/, हमेशा पहले ब्लॉक द्वारा परोसा जाएगा, क्योंकि दूसरा ब्लॉक मेल नहीं खाता है, इसलिए पहला ब्लॉक सबसे लंबे मिलान वाले उपसर्ग स्थान को बनाता है ।


2
आप स्थान संशोधक को देखें, तो ( =, ~*, ~, और ^~) यह काउंटर सहज लग सकता है कि ^~शामिल नहीं नियमित अभिव्यक्ति (के बाद से ~एक रेगुलर एक्सप्रेशन मिलान इंगित करता है) ... फिर भी, जैसा कि आपको याद है, ^एक regex चरित्र वर्ग के अंदर (जैसे [^a-z]) को नकारता है कि वर्ग (जैसे कि उदाहरण का अर्थ है ( az से उन लोगों को छोड़कर कोई भी वर्ण ), इसी तरह, ^~किसी भी संभावित नियमित अभिव्यक्ति स्थान ब्लॉक की
उपेक्षा करता है

6

ठीक है, यह पता चला, मुझे लगा कि "नहीं मिला" त्रुटि nginx से आ रही थी, लेकिन वास्तव में यह मेरे एपीआई से आ रही थी। अगर कोई दिलचस्पी रखता है तो यह मेरा समाधान है:

server {
  listen 80;
  server_name localhost;
  server_name 192.168.3.90;
  server_name 127.0.0.1;

  location / {
    root /home/me/src/phoenix/ui;
    index index.html;
  }

  # automatically go to v1 of the (grape) API
  location ^~ /api/mypath/ {
    rewrite ^/api/mypath/(.*)$ /v1/$1 break;
    proxy_pass http://localhost:3936/;
  }

  location ^~ /api {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://localhost:7379/;
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.