Thứ hai, 17/11/2014 | 00:00 GMT+7

Hiểu server Nginx và các thuật toán lựa chọn khối vị trí

Nginx là một trong những web server phổ biến nhất trên thế giới. Nó có thể xử lý thành công các tải cao với nhiều kết nối client đồng thời và có thể dễ dàng hoạt động như một web server , một server thư hoặc một server Reverse Proxy .

Trong hướng dẫn này, ta sẽ thảo luận về một số chi tiết mức thấp xác định cách Nginx xử lý các yêu cầu của khách hàng. Hiểu những ý tưởng này có thể giúp loại bỏ phỏng đoán trong việc thiết kế các khối server và vị trí và có thể làm cho việc xử lý yêu cầu có vẻ ít khó đoán hơn.

Cấu hình khối Nginx

Nginx phân chia một cách hợp lý các cấu hình nhằm phục vụ các nội dung khác nhau thành các khối, các khối này nằm trong một cấu trúc phân cấp. Mỗi khi một yêu cầu của khách hàng được thực hiện, Nginx sẽ bắt đầu quá trình xác định đoạn cấu hình nào nên được sử dụng để xử lý yêu cầu. Quá trình quyết định này là những gì ta sẽ thảo luận trong hướng dẫn này.

Các khối chính mà ta sẽ thảo luận là khối server và khối vị trí .

Khối server là một tập hợp con cấu hình của Nginx xác định một server ảo được sử dụng để xử lý các yêu cầu thuộc loại đã xác định. Administrator thường cấu hình nhiều khối server và quyết định khối nào sẽ xử lý kết nối nào dựa trên domain , cổng và địa chỉ IP được yêu cầu.

Khối vị trí nằm trong khối server và được sử dụng để xác định cách Nginx xử lý các yêu cầu đối với các tài nguyên và URI khác nhau cho server mẹ. Không gian URI có thể được chia nhỏ theo bất kỳ cách nào mà administrator thích bằng cách sử dụng các khối này. Nó là một mô hình cực kỳ linh hoạt.

Cách Nginx quyết định khối server nào sẽ xử lý yêu cầu

Vì Nginx cho phép administrator xác định nhiều khối server hoạt động như các version web server ảo riêng biệt, nó cần một quy trình để xác định khối server nào sẽ được sử dụng để đáp ứng yêu cầu.

Nó thực hiện điều này thông qua một hệ thống kiểm tra xác định được sử dụng để tìm ra kết quả phù hợp nhất có thể. Các chỉ thị khối server chính mà Nginx là có liên quan với trong quá trình này là listen chỉ thị, và server_name chỉ thị.

Phân tích cú pháp Chỉ thị "lắng nghe" để tìm các kết quả phù hợp có thể có

Đầu tiên, Nginx xem xét địa chỉ IP và cổng của yêu cầu. Nó đối sánh điều này với chỉ thị listen của từng server để xây dựng danh sách các khối server có thể giải quyết yêu cầu.

Chỉ thị listen thường xác định địa chỉ IP và cổng nào mà khối server sẽ phản hồi. Theo mặc định, bất kỳ khối server nào không bao gồm chỉ thị listen sẽ được cung cấp các tham số lắng nghe là 0.0.0.0:80 (hoặc 0.0.0.0:8080 nếu Nginx đang được chạy bởi user bình thường, không phải root). Điều này cho phép các khối này phản hồi các yêu cầu trên bất kỳ giao diện nào trên cổng 80, nhưng giá trị mặc định này không giữ nhiều trọng lượng trong quá trình lựa chọn server .

Chỉ thị listen có thể được đặt thành:

  • Một tổ hợp địa chỉ IP / cổng.
  • Một địa chỉ IP duy nhất sau đó sẽ lắng nghe trên cổng mặc định 80.
  • Một cổng duy nhất sẽ lắng nghe mọi giao diện trên cổng đó.
  • Đường dẫn đến một socket Unix.

Tùy chọn cuối cùng thường chỉ có ý nghĩa khi chuyển các yêu cầu giữa các server khác nhau.

Khi cố gắng xác định khối server nào để gửi yêu cầu, trước tiên Nginx sẽ cố gắng quyết định dựa trên tính cụ thể của chỉ thị listen bằng cách sử dụng các luật sau:

  • Nginx dịch tất cả các lệnh listen “không đầy đủ” bằng cách thay thế các giá trị bị thiếu bằng các giá trị mặc định của chúng để mỗi khối có thể được đánh giá bằng địa chỉ IP và cổng của nó. Một số ví dụ về các bản dịch này là:
    • Một khối không có chỉ thị listen sử dụng giá trị 0.0.0.0:80 .
    • Một khối được đặt thành địa chỉ IP 111.111.111.111 không có cổng sẽ trở thành 111.111.111.111:80
    • Một khối được đặt thành cổng 8888 không có địa chỉ IP sẽ trở thành 0.0.0.0:8888
  • Sau đó, Nginx cố gắng thu thập danh sách các khối server phù hợp với yêu cầu cụ thể nhất dựa trên địa chỉ IP và cổng. Điều này nghĩa là bất kỳ khối nào có chức năng sử dụng 0.0.0.0 làm địa chỉ IP của nó (để trùng với bất kỳ giao diện nào), sẽ không được chọn nếu có các khối phù hợp liệt kê một địa chỉ IP cụ thể. Trong mọi trường hợp, cổng phải được khớp chính xác.
  • Nếu chỉ có một kết quả phù hợp cụ thể nhất, khối server đó sẽ được sử dụng để phục vụ yêu cầu. Nếu có nhiều khối server có cùng mức độ phù hợp về tính đặc hiệu, thì Nginx sẽ bắt đầu đánh giá lệnh server_name của mỗi khối server .

Điều quan trọng cần hiểu là Nginx sẽ chỉ đánh giá chỉ thị server_name khi nó cần phân biệt giữa các khối server phù hợp với cùng một mức độ cụ thể trong chỉ thị listen . Ví dụ: nếu example.com được lưu trữ trên cổng 80 của 192.168.1.10 , một yêu cầu cho example.com sẽ luôn được khối đầu tiên phục vụ trong ví dụ này, bất chấp chỉ thị server_name trong khối thứ hai.

server {     listen 192.168.1.10;      . . .  }  server {     listen 80;     server_name example.com;      . . .  } 

Trong trường hợp có nhiều hơn một khối server trùng với độ đặc hiệu như nhau, bước tiếp theo là kiểm tra chỉ thị server_name .

Phân tích cú pháp Chỉ thị “server_name” để chọn đối sánh

Tiếp theo, để đánh giá thêm các yêu cầu có chỉ thị listen cụ thể như nhau, Nginx sẽ kiểm tra tiêu đề " Server lưu trữ" của yêu cầu. Giá trị này chứa domain hoặc địa chỉ IP mà client thực sự đang cố gắng truy cập.

Nginx cố gắng tìm ra kết quả phù hợp nhất cho giá trị mà nó tìm thấy bằng cách xem chỉ thị server_name trong mỗi khối server vẫn là ứng viên lựa chọn. Nginx đánh giá những điều này bằng cách sử dụng công thức sau:

  • Nginx đầu tiên sẽ cố gắng tìm một khối server với một server_name phù hợp với giá trị trong “Host” header của yêu cầu chính xác. Nếu điều này được tìm thấy, khối liên kết sẽ được sử dụng để phục vụ yêu cầu. Nếu tìm thấy nhiều kết hợp chính xác, kết quả đầu tiên sẽ được sử dụng.
  • Nếu không tìm thấy kết quả khớp chính xác, thì Nginx sẽ cố gắng tìm một khối server có server_name khớp bằng cách sử dụng ký tự đại diện đứng đầu (được biểu thị bằng dấu * ở đầu tên trong cấu hình). Nếu một khối được tìm thấy, khối đó sẽ được sử dụng để phục vụ yêu cầu. Nếu tìm thấy nhiều kết quả phù hợp, kết quả phù hợp dài nhất sẽ được sử dụng để phục vụ yêu cầu.
  • Nếu không phù hợp được tìm thấy bằng cách sử dụng ký tự đại diện lãnh đạo, Nginx sau đó tìm kiếm một khối server với một server_name rằng trận đấu bằng cách sử dụng ký tự đại diện dấu (chỉ định bởi một tên server kết thúc bằng một * trong config). Nếu một khối được tìm thấy, khối đó được sử dụng để phục vụ yêu cầu. Nếu tìm thấy nhiều kết quả phù hợp, kết quả phù hợp dài nhất sẽ được sử dụng để phục vụ yêu cầu.
  • Nếu không phù hợp được tìm thấy bằng cách sử dụng ký tự đại diện trailing, Nginx sau đó đánh giá khối server xác định server_name sử dụng biểu thức thông thường (chỉ định bởi một ~ trước tên). server_name đầu tiên có biểu thức chính quy trùng với tiêu đề “ Server lưu trữ” sẽ được sử dụng để phân phát yêu cầu.
  • Nếu không tìm thấy đối sánh biểu thức chính quy, Nginx sẽ chọn khối server mặc định cho địa chỉ IP và cổng đó.

Mỗi tổ hợp địa chỉ IP / cổng có một khối server mặc định sẽ được sử dụng khi không thể xác định được quá trình hoạt động bằng các phương pháp trên. Đối với tổ hợp địa chỉ IP / cổng, đây sẽ là khối đầu tiên trong cấu hình hoặc khối có chứa tùy chọn default_server như một phần của chỉ thị listen (sẽ overrides thuật toán tìm thấy đầu tiên). Chỉ có thể có một khai báo default_server cho mỗi tổ hợp địa chỉ IP / cổng.

Ví dụ

Nếu có một server_name được xác định khớp chính xác với giá trị tiêu đề “ Server lưu trữ”, thì khối server đó sẽ được chọn để xử lý yêu cầu.

Trong ví dụ này, nếu tiêu đề " Server lưu trữ" của yêu cầu được đặt thành "host1.example.com", server thứ hai sẽ được chọn:

server {     listen 80;     server_name *.example.com;      . . .  }  server {     listen 80;     server_name host1.example.com;      . . .  } 

Nếu không phù hợp chính xác được tìm thấy, Nginx sau đó kiểm tra xem nếu có một server_name với một ký tự đại diện bắt đầu từ đó phù hợp. Kết quả phù hợp dài nhất bắt đầu bằng ký tự đại diện sẽ được chọn để đáp ứng yêu cầu.

Trong ví dụ này, nếu yêu cầu có tiêu đề “ Server lưu trữ” là “ www.example.org ”, thì khối server thứ hai sẽ được chọn:

server {     listen 80;     server_name www.example.*;      . . .  }  server {     listen 80;     server_name *.example.org;      . . .  }  server {     listen 80;     server_name *.org;      . . .  } 

Nếu không tìm thấy kết quả phù hợp nào với ký tự đại diện bắt đầu, thì Nginx sẽ xem liệu khớp có tồn tại hay không bằng cách sử dụng ký tự đại diện ở cuối biểu thức. Đến đây, kết thúc đối sánh dài nhất bằng ký tự đại diện sẽ được chọn để phục vụ yêu cầu.

Ví dụ: nếu yêu cầu có tiêu đề “ Server lưu trữ” được đặt thành “ www.example.com ”, thì khối server thứ ba sẽ được chọn:

server {     listen 80;     server_name host1.example.com;      . . .  }  server {     listen 80;     server_name example.com;      . . .  }  server {     listen 80;     server_name www.example.*;      . . .  } 

Nếu không tìm thấy kết quả khớp ký tự đại diện nào, thì Nginx sẽ chuyển sang cố gắng khớp các lệnh server_name sử dụng biểu thức chính quy. Biểu thức chính quy phù hợp đầu tiên sẽ được chọn để phản hồi yêu cầu.

Ví dụ: nếu tiêu đề “ Server lưu trữ” của yêu cầu được đặt thành “ www.example.com ”, thì khối server thứ hai sẽ được chọn để đáp ứng yêu cầu:

server {     listen 80;     server_name example.com;      . . .  }  server {     listen 80;     server_name ~^(www|host1).*\.example\.com$;      . . .  }  server {     listen 80;     server_name ~^(subdomain|set|www|host1).*\.example\.com$;      . . .  } 

Nếu không có bước nào ở trên có thể đáp ứng yêu cầu, thì yêu cầu sẽ được chuyển đến server mặc định cho địa chỉ IP và cổng phù hợp.

Khớp các khối vị trí

Tương tự như quy trình mà Nginx sử dụng để chọn khối server sẽ xử lý yêu cầu, Nginx cũng có một thuật toán được cài đặt để quyết định khối vị trí nào trong server sẽ sử dụng để xử lý yêu cầu.

Cú pháp khối vị trí

Trước khi ta đề cập đến cách Nginx quyết định khối vị trí nào sẽ sử dụng để xử lý các yêu cầu, ta hãy xem qua một số cú pháp mà bạn có thể thấy trong định nghĩa khối vị trí. Các khối vị trí nằm trong các khối server (hoặc các khối vị trí khác) và được sử dụng để quyết định cách xử lý URI yêu cầu (một phần của yêu cầu xuất hiện sau domain hoặc địa chỉ IP / cổng).

Các khối vị trí thường có dạng sau:

location optional_modifier location_match {      . . .  } 

location_match ở trên xác định những gì Nginx sẽ kiểm tra URI yêu cầu. Sự tồn tại hoặc không tồn tại của công cụ sửa đổi trong ví dụ trên ảnh hưởng đến cách Nginx cố gắng trùng với khối vị trí. Các công cụ sửa đổi bên dưới sẽ khiến khối vị trí được liên kết được hiểu như sau:

  • (không có) : Nếu không có phần bổ trợ nào, vị trí được hiểu là khớp tiền tố . Điều này nghĩa là vị trí được cung cấp sẽ được trùng với phần đầu của URI yêu cầu để xác định vị trí phù hợp.
  • = : Nếu dấu bằng được sử dụng, khối này sẽ được coi là đối sánh nếu URI yêu cầu khớp chính xác với vị trí đã cho.
  • ~ : Nếu có công cụ sửa đổi dấu ngã, vị trí này sẽ được hiểu là đối sánh biểu thức chính quy phân biệt chữ hoa chữ thường.
  • ~* : Nếu sử dụng công cụ sửa đổi dấu ngã và dấu hoa thị, khối vị trí sẽ được hiểu là đối sánh biểu thức chính quy không phân biệt chữ hoa chữ thường.
  • ^~ : Nếu có công cụ sửa đổi dấu ngã và dấu ngã và nếu khối này được chọn là đối sánh cụm từ không chính quy tốt nhất, thì đối sánh biểu thức chính quy sẽ không diễn ra.

Ví dụ minh họa cú pháp khối vị trí

Ví dụ về đối sánh tiền tố, khối vị trí sau có thể được chọn để phản hồi cho các URI yêu cầu trông giống như /site , /site/page1/index.html hoặc /site/index.html :

location /site {      . . .  } 

Để minh họa về việc đối sánh URI yêu cầu chính xác, khối này sẽ luôn được sử dụng để phản hồi URI yêu cầu có dạng /page1 . Nó sẽ không được sử dụng để phản hồi một /page1/index.html URI yêu cầu. Lưu ý nếu khối này được chọn và yêu cầu được thực hiện bằng cách sử dụng trang index , chuyển hướng nội bộ sẽ diễn ra đến một vị trí khác sẽ là nơi xử lý yêu cầu thực tế:

location = /page1 {      . . .  } 

Là một ví dụ về vị trí cần được hiểu là biểu thức chính quy phân biệt chữ hoa chữ thường, khối này được dùng để xử lý các yêu cầu cho /tortoise.jpg , nhưng không phải cho /FLOWER.PNG :

location ~ \.(jpe?g|png|gif|ico)$ {      . . .  } 

Dưới đây là một khối cho phép đối sánh không phân biệt chữ hoa chữ thường. Ở đây, cả /tortoise.jpg /FLOWER.PNG có thể được xử lý bởi khối này:

location ~* \.(jpe?g|png|gif|ico)$ {      . . .  } 

Cuối cùng, khối này sẽ ngăn đối sánh biểu thức chính quy xảy ra nếu nó được xác định là đối sánh biểu thức không chính quy tốt nhất. Nó có thể xử lý các yêu cầu cho /costumes/ninja.html :

location ^~ /costumes {      . . .  } 

Như bạn thấy, các công cụ sửa đổi cho biết cách khối vị trí sẽ được diễn giải. Tuy nhiên, điều này không cho ta biết thuật toán mà Nginx sử dụng để quyết định khối vị trí nào để gửi yêu cầu. Ta sẽ xem xét điều đó tiếp theo.

Cách Nginx chọn vị trí nào sẽ sử dụng để xử lý yêu cầu

Nginx chọn vị trí sẽ được sử dụng để phục vụ yêu cầu theo cách tương tự như cách nó chọn khối server . Nó chạy qua một quá trình xác định khối vị trí tốt nhất cho bất kỳ yêu cầu nhất định nào. Hiểu được quy trình này là một yêu cầu quan trọng để có thể cấu hình Nginx một cách tin cậy và chính xác.

Hãy ghi nhớ các loại khai báo vị trí mà ta đã mô tả ở trên, Nginx đánh giá các bối cảnh vị trí có thể có bằng cách so sánh URI yêu cầu với từng vị trí. Nó thực hiện điều này bằng cách sử dụng thuật toán sau:

  • Nginx bắt đầu bằng cách kiểm tra tất cả các đối sánh vị trí dựa trên tiền tố (tất cả các loại vị trí không liên quan đến biểu thức chính quy). Nó kiểm tra từng vị trí so với URI yêu cầu hoàn chỉnh.
  • Đầu tiên, Nginx tìm kiếm một kết hợp chính xác. Nếu khối vị trí sử dụng = modifier được tìm thấy khớp chính xác với URI yêu cầu, khối vị trí này ngay lập tức được chọn để phục vụ yêu cầu.
  • Nếu không tìm thấy kết quả khớp khối vị trí chính xác (với = modifier), thì Nginx sẽ chuyển sang đánh giá các tiền tố không chính xác. Nó phát hiện ra vị trí tiền tố phù hợp dài nhất cho URI yêu cầu đã cho, sau đó nó sẽ đánh giá như sau:
    • Nếu vị trí tiền tố phù hợp dài nhất có bổ ngữ ^~ , thì Nginx sẽ ngay lập tức kết thúc tìm kiếm và chọn vị trí này để phục vụ yêu cầu.
    • Nếu vị trí tiền tố phù hợp dài nhất không sử dụng công cụ sửa đổi ^~ , đối sánh được Nginx lưu trữ tại thời điểm này để có thể chuyển trọng tâm của tìm kiếm.
  • Sau khi vị trí tiền tố phù hợp dài nhất được xác định và lưu trữ, Nginx chuyển sang đánh giá các vị trí biểu thức chính quy (cả phân biệt chữ hoa chữ thường và không phân biệt). Nếu có bất kỳ vị trí biểu thức chính quy nào trong vị trí tiền tố phù hợp dài nhất, Nginx sẽ chuyển các vị trí đó lên đầu danh sách các vị trí regex để kiểm tra. Sau đó, Nginx cố gắng đối sánh tuần tự với các vị trí biểu thức chính quy. Vị trí biểu thức chính quy đầu tiên phù hợp với URI yêu cầu ngay lập tức được chọn để phân phát yêu cầu.
  • Nếu không tìm thấy vị trí biểu thức chính quy nào phù hợp với URI yêu cầu, vị trí tiền tố được lưu trữ trước đó sẽ được chọn để phục vụ yêu cầu.

Điều quan trọng cần hiểu là, theo mặc định, Nginx sẽ phân phối các đối sánh biểu thức chính quy thay vì đối sánh tiền tố. Tuy nhiên, nó đánh giá các vị trí tiền tố trước, cho phép người quản trị overrides xu hướng này bằng cách chỉ định các vị trí bằng cách sử dụng các bổ ngữ =^~ .

Cũng cần lưu ý , mặc dù các vị trí tiền tố thường được chọn dựa trên kết quả phù hợp dài nhất, cụ thể nhất, đánh giá biểu thức chính quy sẽ bị dừng khi tìm thấy vị trí phù hợp đầu tiên. Điều này nghĩa là vị trí bên trong cấu hình có ý nghĩa rất lớn đối với các vị trí biểu thức chính quy.

Cuối cùng, điều quan trọng là phải hiểu rằng các đối sánh biểu thức chính quy bên trong đối sánh tiền tố dài nhất sẽ "nhảy dòng" khi Nginx đánh giá các vị trí regex.Chúng sẽ được đánh giá, theo thứ tự, trước khi bất kỳ kết quả phù hợp biểu thức chính quy nào khác được xem xét. Maxim Dounin, một nhà phát triển Nginx cực kỳ hữu ích, giải thích trong bài đăng này phần này của thuật toán lựa chọn.

Khi nào thì Đánh giá khối vị trí chuyển sang các vị trí khác?

Nói chung, khi một khối vị trí được chọn để phục vụ một yêu cầu, yêu cầu được xử lý hoàn toàn trong ngữ cảnh đó kể từ thời điểm đó trở đi. Chỉ vị trí đã chọn và các chỉ thị kế thừa xác định cách yêu cầu được xử lý mà không có sự can thiệp từ các khối vị trí anh em.

Mặc dù đây là luật chung sẽ cho phép bạn thiết kế các khối vị trí của bạn theo cách có thể dự đoán được, nhưng điều quan trọng là nhận ra rằng đôi khi tìm kiếm vị trí mới được kích hoạt bởi một số chỉ thị trong vị trí đã chọn. Các ngoại lệ đối với luật "chỉ một khối vị trí" có thể có ý nghĩa về cách yêu cầu thực sự được phân phối và có thể không phù hợp với mong đợi của bạn khi thiết kế khối vị trí của bạn .

Một số chỉ thị có thể dẫn đến loại chuyển hướng nội bộ này là:

  • mục lục
  • try_files
  • viết lại
  • error_page

Hãy xem qua những điều này một cách ngắn gọn.

index thị index luôn dẫn đến chuyển hướng nội bộ nếu nó được sử dụng để xử lý yêu cầu. Đối sánh vị trí chính xác thường được sử dụng để tăng tốc quá trình lựa chọn bằng cách kết thúc ngay việc thực thi thuật toán. Tuy nhiên, nếu bạn thực hiện khớp một vị trí chính xác với một thư mục , thì rất có thể yêu cầu sẽ được chuyển hướng đến một vị trí khác để xử lý thực tế.

Trong ví dụ này, vị trí đầu tiên được so trùng với một URI yêu cầu /exact , nhưng để xử lý yêu cầu, index thị index được khối kế thừa sẽ khởi tạo một chuyển hướng nội bộ đến khối thứ hai:

index index.html;  location = /exact {      . . .  }  location / {      . . .  } 

Trong trường hợp trên, nếu bạn thực sự cần thực thi để ở trong khối đầu tiên, bạn sẽ phải đưa ra một phương pháp khác để đáp ứng yêu cầu đối với folder . Ví dụ: bạn có thể đặt index không hợp lệ cho khối đó và bật autoindex :

location = /exact {     index nothing_will_match;     autoindex on; }  location  / {      . . .  } 

Đây là một cách để ngăn index chuyển đổi ngữ cảnh, nhưng nó có thể không hữu ích cho hầu hết các cấu hình. Hầu hết một kết quả khớp chính xác trên các folder có thể hữu ích cho những việc như viết lại yêu cầu (điều này cũng dẫn đến việc tìm kiếm vị trí mới).

Một trường hợp khác mà vị trí xử lý có thể được đánh giá lại là với chỉ thị try_files . Lệnh này yêu cầu Nginx kiểm tra sự tồn tại của một group file hoặc folder được đặt tên. Tham số cuối cùng có thể là một URI mà Nginx sẽ thực hiện chuyển hướng nội bộ đến.

Xem xét cấu hình sau:

root /var/www/main; location / {     try_files $uri $uri.html $uri/ /fallback/index.html; }  location /fallback {     root /var/www/another; } 

Trong ví dụ trên, nếu một yêu cầu được thực hiện cho /blahblah , vị trí đầu tiên ban đầu sẽ nhận được yêu cầu. Nó sẽ cố gắng tìm một file có tên blahblah trong folder /var/www/main . Nếu nó không thể tìm thấy nó, nó sẽ theo dõi bằng cách tìm kiếm một file có tên blahblah.html . Sau đó, nó sẽ thử xem có một folder tên là blahblah/ trong folder chính /var/www/main . Không thực hiện được tất cả những lần thử này, nó sẽ chuyển hướng đến /fallback/index.html . Điều này sẽ kích hoạt một tìm kiếm vị trí khác sẽ bị chặn bởi khối vị trí thứ hai. Điều này sẽ phân phát file /var/www/another/fallback/index.html .

Một chỉ thị khác có thể dẫn đến lỗi khối vị trí là lệnh rewrite . Khi sử dụng tham số last với chỉ thị rewrite hoặc khi không sử dụng tham số nào, Nginx sẽ tìm kiếm một vị trí phù hợp mới dựa trên kết quả ghi lại.

Ví dụ: nếu ta sửa đổi ví dụ cuối cùng để bao gồm ghi lại, ta có thể thấy rằng yêu cầu đôi khi được chuyển trực tiếp đến vị trí thứ hai mà không dựa vào chỉ thị try_files :

root /var/www/main; location / {     rewrite ^/rewriteme/(.*)$ /$1 last;     try_files $uri $uri.html $uri/ /fallback/index.html; }  location /fallback {     root /var/www/another; } 

Trong ví dụ trên, một yêu cầu cho /rewriteme/hello sẽ được xử lý ban đầu bởi khối vị trí đầu tiên. Nó sẽ được viết lại thành /hello và một vị trí sẽ được tìm kiếm. Trong trường hợp này, nó sẽ khớp lại với vị trí đầu tiên và được xử lý bởi try_files như bình thường, có thể quay trở lại /fallback/index.html nếu không tìm thấy gì (sử dụng chuyển hướng nội bộ try_files mà ta đã thảo luận ở trên).

Tuy nhiên, nếu một yêu cầu được thực hiện cho /rewriteme/fallback/hello , thì khối đầu tiên sẽ khớp lại. Việc viết lại được áp dụng , lần này dẫn đến /fallback/hello . Sau đó, yêu cầu sẽ được phân phát từ khối vị trí thứ hai.

Một tình huống liên quan xảy ra với lệnh return khi gửi mã trạng thái 301 hoặc 302 . Sự khác biệt trong trường hợp này là nó dẫn đến một yêu cầu hoàn toàn mới ở dạng chuyển hướng có thể nhìn thấy bên ngoài. Tình huống tương tự này có thể xảy ra với lệnh rewrite khi sử dụng cờ redirect hoặc cờ permanent . Tuy nhiên, những tìm kiếm vị trí này không được mong đợi, vì các chuyển hướng có thể nhìn thấy bên ngoài luôn dẫn đến một yêu cầu mới.

Chỉ thị error_page có thể dẫn đến chuyển hướng nội bộ tương tự như chuyển hướng được tạo bởi try_files . Chỉ thị này được sử dụng để xác định điều gì sẽ xảy ra khi gặp phải một số mã trạng thái nhất định. Điều này có thể sẽ không bao giờ được thực thi nếu try_files được đặt, vì lệnh đó xử lý toàn bộ vòng đời của một yêu cầu.

Hãy xem xét ví dụ này:

root /var/www/main;  location / {     error_page 404 /another/whoops.html; }  location /another {     root /var/www; } 

Mọi yêu cầu (trừ những yêu cầu bắt đầu bằng /another ) sẽ được xử lý bởi khối đầu tiên, khối này sẽ phân phát các file từ /var/www/main . Tuy nhiên, nếu không tìm thấy file (trạng thái 404), chuyển hướng nội bộ đến / /another/whoops.html sẽ xảy ra, dẫn đến tìm kiếm vị trí mới cuối cùng sẽ đến khối thứ hai. Tệp này sẽ được phân phát từ /var/www/another/whoops.html .

Như bạn thấy , việc hiểu các trường hợp mà Nginx kích hoạt tìm kiếm vị trí mới có thể giúp dự đoán hành vi bạn sẽ thấy khi đưa ra yêu cầu.

Kết luận

Hiểu các cách mà Nginx xử lý các yêu cầu của khách hàng có thể giúp công việc của bạn với quyền là administrator dễ dàng hơn nhiều. Bạn có thể biết Nginx sẽ chọn khối server nào dựa trên từng yêu cầu của khách hàng. Bạn cũng sẽ có thể cho biết cách khối vị trí sẽ được chọn dựa trên URI yêu cầu. Nhìn chung, biết cách mà Nginx chọn các khối khác nhau sẽ cung cấp cho bạn khả năng theo dõi các ngữ cảnh mà Nginx sẽ áp dụng để phục vụ từng yêu cầu.


Tags:

Các tin trước

Cách thiết lập server block Nginx trên CentOS 7 2014-11-05
Cách sử dụng tệp bản đồ Salt Cloud để triển khai server ứng dụng và reverse-proxy Nginx 2014-10-27
Cách triển khai ứng dụng Rails với Passenger và Nginx trên Ubuntu 14.04 2014-10-09
Cách tạo profile AppArmor cho Nginx trên Ubuntu 14.04 2014-10-06
Cách cấu hình Nginx với SSL làm Reverse Proxy cho Jenkins 2014-09-23
Cách thiết lập nhiều trang web WordPress với Nginx trên Ubuntu 14.04 2014-08-21
Cách cài đặt và bảo mật phpMyAdmin với Nginx trên server Ubuntu 14.04 2014-08-06
Cách cài đặt và bảo mật phpMyAdmin với Nginx trên server CentOS 7 2014-08-06
Cách cài đặt Nginx trên CentOS 7 2014-07-22
Cách tạo chứng chỉ ECC trên Nginx cho Debian 7 2014-07-21