การแสดงจุดปลายพร็อกซีหลายรายการภายใต้ตำแหน่งใน Nginx


14

ฉันมีจุดปลาย API สองสามอย่างที่ฉันต้องการให้บริการจากตำแหน่งเดียวของที่/apiมีพา ธ ย่อยไปยังจุดปลายที่แตกต่างกัน โดยเฉพาะฉันต้องการ webdis จะสามารถใช้ได้ใน/apiและ API /api/mypathที่เป็นกรรมสิทธิ์ที่มีอยู่ใน

ฉันไม่กังวลเกี่ยวกับการปะทะกันกับ webdis API เพราะฉันใช้ subpaths ซึ่งไม่น่าจะขัดแย้งกับชื่อคำสั่ง redis และยังสามารถควบคุมการออกแบบ API ได้อย่างสมบูรณ์เพื่อหลีกเลี่ยงการปะทะกัน

นี่คือไฟล์กำหนดค่าจากเซิร์ฟเวอร์ทดสอบของฉันที่ฉันแฮ็ค:

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อะไร เกิดอะไรขึ้นเมื่อคุณเปิดใช้งานคำสั่งระบุตำแหน่งนั้น หมดเวลาเชื่อมต่อหรือไม่ ไม่ตรงกับตำแหน่ง?
masegaloeh

อาขอบคุณสำหรับพรอมต์มันทำให้เกิดข้อผิดพลาดที่ไม่พบในการตรวจสอบเพิ่มเติมปรากฏว่าข้อผิดพลาดนั้นมาจาก API ของฉันดังนั้นจึงใช้งานได้! : D แต่กฎการเขียนซ้ำไม่ได้เพราะฉันต้องเพิ่ม v1 ลงใน URL ( localhost / api / mypath / v1 / about ) ... :(
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) ในทำนองเดียวกัน^~negates บล็อกตำแหน่งการแสดงออกปกติใด ๆ ที่อาจเกิดขึ้น
Doktor J

6

ตกลงคิดออกฉันคิดว่าข้อผิดพลาด "ไม่พบ" มาจาก nginx แต่จริงๆแล้วมันมาจาก API ของฉัน นี่คือทางออกของฉันหากใครสนใจ:

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/;
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.