Phục vụ nhiều điểm cuối proxy theo vị trí trong Nginx


13

Tôi có một vài điểm cuối API mà tôi muốn phân phát dưới một vị trí duy nhất /apivới các đường dẫn phụ đi đến các điểm cuối khác nhau. Cụ thể, tôi muốn webdis có sẵn tại /apivà API độc quyền có sẵn tại /api/mypath.

Tôi không lo lắng về việc đụng độ với API webdis vì tôi đang sử dụng các đường dẫn phụ không có khả năng xung đột với tên lệnh redis và cũng có toàn quyền kiểm soát thiết kế API để tránh xung đột.

Đây là tập tin cấu hình từ máy chủ thử nghiệm của tôi mà tôi đã hack:

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/;
  #}
}

Làm cách nào tôi có thể thay đổi cách giải quyết của mình để mọi yêu cầu /api/mypath/*sẽ đi đến điểm cuối tại cổng 3936 và mọi thứ khác đến cổng 7379?


Bạn có ý nghĩa tried this to no availgì? Điều gì đã xảy ra khi bạn kích hoạt chỉ thị vị trí đó? Hết thời gian kết nối? Vị trí không phù hợp?
masegaloeh

À cảm ơn vì lời nhắc, nó đang đưa ra một lỗi không tìm thấy, khi điều tra thêm thì có vẻ như lỗi đó đến từ API của tôi nên nó đang hoạt động! : D Nhưng quy tắc viết lại rõ ràng không phải vì tôi phải thêm v1 vào URL ( localhost / api / mypath / v1 / about ) ... :(
hamstar 8/12/14

Câu trả lời:


23

Bạn không cần viết lại cho điều này.

server {
  ...

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

Theo tài liệu nginx

Một vị trí có thể được xác định bởi một chuỗi tiền tố hoặc bởi một biểu thức thông thường. Biểu thức chính quy được chỉ định với công cụ ~*sửa đổi trước (đối với trường hợp khớp không phân biệt chữ hoa chữ thường) hoặc công cụ ~sửa đổi (đối với trường hợp khớp phân biệt chữ hoa chữ thường ). Để tìm vị trí khớp với một yêu cầu đã cho, trước tiên nginx kiểm tra các vị trí được xác định bằng chuỗi tiền tố (vị trí tiền tố). Trong số đó, vị trí có tiền tố phù hợp dài nhất được chọn và ghi nhớ. Sau đó, các biểu thức chính quy được kiểm tra, theo thứ tự xuất hiện của chúng trong tệp cấu hình. Việc tìm kiếm các biểu thức chính quy chấm dứt trên kết quả khớp đầu tiên và cấu hình tương ứng được sử dụng. Nếu không tìm thấy kết quả khớp với biểu thức chính quy thì cấu hình của vị trí tiền tố được nhớ trước đó sẽ được sử dụng.

Nếu vị trí tiền tố phù hợp dài nhất có công cụ ^~sửa đổi thì các biểu thức thông thường không được kiểm tra.

Do đó, mọi yêu cầu bắt đầu /api/mypath/sẽ luôn được phục vụ bởi khối thứ hai vì đó là vị trí tiền tố phù hợp dài nhất .

Bất kỳ yêu cầu nào bắt đầu /api/không được thực hiện ngay lập tức mypath/sẽ luôn được phục vụ bởi khối thứ nhất, vì khối thứ hai không khớp, do đó làm cho khối thứ nhất trở thành vị trí tiền tố phù hợp dài nhất .


2
Nếu bạn nhìn vào các bổ từ vị trí ( =, ~*, ~, và ^~) nó có vẻ phản trực giác mà ^~không bao gồm biểu thức thông thường (vì ~chỉ một trận đấu biểu thức chính quy) ... Tuy nhiên, nếu bạn gọi lại, ^bên trong một lớp nhân vật regex (ví dụ [^a-z]) phủ nhận rằng lớp (ví dụ như ví dụ có nghĩa (bất kỳ ký tự nào ngoại trừ các ký tự từ az); tương tự, ^~phủ nhận bất kỳ khối vị trí biểu thức chính quy tiềm năng nào.
Doktor J

6

OK đã tìm ra nó, tôi nghĩ rằng lỗi "không tìm thấy" đến từ nginx, nhưng thực sự nó đến từ API của tôi. Đây là giải pháp của tôi nếu có ai quan tâm:

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/;
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.