ReactJS: Hiểu về máy chủ Nginx và các thuật toán lựa chọn khối vị trí

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Giới thiệu

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

Trong bài hướng dẫn này, chúng ta sẽ thảo luận về một số chi tiết hậu trường xác định cách Nginx xử lý các yêu cầu của khách hàng. Việc 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 máy chủ và vị trí, đồng thời 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 bắt đầu quá trình xác định khối 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ì chúng ta sẽ thảo luận trong hướng dẫn này.

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

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

Khối vị trí nằm trong khối máy chủ và được sử dụng để xác định cách Nginx sẽ xử lý các yêu cầu đối với các tài nguyên và URI khác nhau cho máy chủ mẹ. Không gian URI có thể được chia nhỏ theo bất kỳ cách nào mà quản trị viên 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 máy chủ nào sẽ xử lý yêu cầu

Vì Nginx cho phép quản trị viên xác định nhiều khối máy chủ hoạt động như các phiên bản máy chủ web ảo riêng biệt, nó cần một quy trình để xác định khối máy chủ nào trong số các khối máy chủ này 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 máy chủ chính mà Nginx có liên quan trong quá trình này là chỉ thị listen và chỉ thị server_name.

Phân tích cú pháp chỉ thị listen để tìm các kết quả phù hợp có thể

Đầ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 máy chủ để xây dựng danh sách các khối máy chủ 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 máy chủ sẽ phản hồi. Theo mặc định, bất kỳ khối máy chủ nào không bao gồm chỉ thị listen đều được cung cấp các tham số lắng nghe của 0.0.0.0:80 (hoặc 0.0.0.0:8080 nếu Nginx đang được chạy bởi một người dùng 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 có nhiều trọng lượng trong quá trình lựa chọn máy chủ.

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 ổ cắm 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 máy chủ khác nhau.

Khi cố gắng xác định khối máy chủ 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 quy tắc sau:

  • Nginx dịch tất cả các chỉ thị “không đầy đủ” listen 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 máy chủ 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 có nghĩa là bất kỳ khối nào đang sử dụng chức năng 0.0.0.0 làm địa chỉ IP của nó (để khớp 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 máy chủ đó sẽ được sử dụng để phục vụ yêu cầu. Nếu có nhiều khối máy chủ có cùng mức độ phù hợp về tính đặc hiệu, thì Nginx sẽ bắt đầu đánh giá chỉ thị server_name của từng khối máy chủ.

Đ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 máy chủ khớ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 máy chủ khớp 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 một đối sánh

Tiếp theo, để đánh giá thêm các yêu cầu có các chỉ thị listen cụ thể như nhau, Nginx sẽ kiểm tra header Host của yêu cầu. Giá trị này chứa miền hoặc địa chỉ IP mà máy khách 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 với giá trị mà nó tìm thấy bằng cách xem chỉ thị server_name trong mỗi khối máy chủ 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:

  • Trước tiên, Nginx sẽ cố gắng tìm một khối máy chủ có giá trị server_name khớp chính xác với giá trị trong header Host của yêu cầu. 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 nhiều kết quả khớp chính xác được tìm thấy, kết quả đầu tiên sẽ được sử dụng.
  • Nếu không tìm thấy kết quả phù hợp chính xác, thì Nginx sẽ cố gắng tìm một khối máy chủ có khối server_name phù hợ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 tìm thấy kết quả phù hợp nào bằng cách sử dụng ký tự đại diện đứng đầu, thì Nginx sẽ tìm kiếm khối máy chủ có khối server_name phù hợp bằng cách sử dụng ký tự đại diện ở cuối (được biểu thị bằng tên máy chủ kết thúc bằng một * 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 tìm thấy kết quả phù hợp nào bằng cách sử dụng ký tự đại diện theo sau, thì Nginx sẽ đánh giá các khối máy chủ định nghĩa server_name sử dụng biểu thức chính quy (được biểu thị bằng dấu ~ trước tên). Đầu tiên server_name có biểu thức chính quy khớp với header "Host" 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, thì Nginx sẽ chọn khối máy chủ 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 máy chủ mặc định sẽ được sử dụng khi không thể xác định được quá trình hành độ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 chứa tùy chọn default_server như một phần của chỉ thị listen (sẽ ghi đè 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.

Các ví dụ

Nếu có một định nghĩa server_name khớp chính xác với header Host, thì khối máy chủ đó sẽ được chọn để xử lý yêu cầu.

Trong ví dụ này, nếu header Host của yêu cầu được đặt thành host1.example.com, thì máy chủ 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 tìm thấy kết quả khớp chính xác nào, Nginx sẽ kiểm tra xem liệu server_name có một ký tự đại diện bắt đầu phù hợp hay không. 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ó header Host là www.example.org, thì khối máy chủ 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. Tại thời điểm 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ó header Host được đặt thành www.example.com, thì khối máy chủ 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 so 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 header Host của yêu cầu được đặt thành www.example.com, thì khối máy chủ 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 máy chủ 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 máy chủ sẽ xử lý yêu cầu, Nginx cũng có một thuật toán được thiết lập để quyết định khối vị trí nào trong máy chủ sẽ sử dụng để xử lý yêu cầu.

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

Trước khi chúng tôi đề 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, chúng 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 máy chủ (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 tên miền hoặc địa chỉ IP / cổng).

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

location optional_modifier location_match {

    . . .

}

Phần location_match ở trên xác định những gì Nginx nên kiểm tra URI yêu cầu chống lại. 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 khớp với khối vị trí. Các công cụ sửa đổi bên dưới sẽ làm cho khối vị trí được liên kết được hiểu như sau:

  • (none - không có) : Nếu không có công cụ sửa đổi nào, vị trí được hiểu là đối sánh tiền tố. Điều này có nghĩa là vị trí được cung cấp sẽ được so khớp 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í

Như một 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ề đố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 một URI yêu cầu trông giống như /page1. Nó sẽ không được sử dụng để trả lời một yêu cầu URI /page1/index.html. Hãy nhớ rằng 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 chỉ mục, chuyển hướng nội bộ sẽ diễn ra đến một vị trí khác sẽ là nơi xử lý thực tế của yêu cầu:

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ó thể được sử dụng để xử lý các yêu cầu đối với /tortoise.jpg, nhưng không phải đối với /FLOWER.PNG:

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

    . . .

}

Một khối cho phép đối sánh không phân biệt chữ hoa chữ thường tương tự như ở trên được hiển thị bên dưới. Ở đây, cả hai /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 chúng 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. Chúng 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 máy chủ. 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ể định cấu hình Nginx một cách đáng tin cậy và chính xác.

Hãy ghi nhớ các loại khai báo vị trí mà chúng tôi đã 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 quả phù 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ó modifier ^~, 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 modifier ^~, thì kết quả khớp đượ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 chữ hoa chữ thường). 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, thì 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át 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 tiên, cho phép người quản trị ghi đè xu hướng này bằng cách chỉ định các vị trí bằng cách sử dụng các modifier = à ^~.

Cũng cần lưu ý rằng, mặc dù vị trí tiền tố thường được chọn dựa trên đối sánh dài nhất, cụ thể nhất, thì đá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 có nghĩa là vị trí 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 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 phần này của thuật toán lựa chọn trong bài đăng này.

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à quy tắc chung sẽ cho phép bạn thiết kế các khối vị trí của mình theo cách có thể dự đoán được, nhưng điều quan trọng là phải 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 quy tắc "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át và có thể không phù hợp với mong đợi của bạn khi thiết kế các khối vị trí của mình.

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

  • index
  • try_files
  • rewrite
  • error_page

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

Chỉ 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 đối sánh 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 khớp bởi một URI yêu cầu /exact, nhưng để xử lý yêu cầu, chỉ thị index được khối kế thừa sẽ bắt đầu 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 để ở lại 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 thư mục. 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 không cho index chuyển đổi ngữ cảnh, nhưng nó có lẽ 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 thư mục 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 ví dụ 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 nhóm tệp hoặc thư mục đượ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.

Hãy 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 /blahblah, vị trí đầu tiên sẽ nhận được yêu cầu ban đầu. Nó sẽ cố gắng tìm một tệp được gọi là blahblah trong thư mục /var/www/main. Nếu nó không thể tìm thấy, nó sẽ theo dõi bằng cách tìm kiếm một tệp có tên blahblah.html. Sau đó, nó sẽ thử xem có thư mục nào được gọi là blahblah/ trong thư mục /var/www/main hay không. Nếu không thực hiện được tất cả các nỗ lực 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ục vụ file /var/www/another/fallback/index.html.

Một chỉ thị khác có thể dẫn đến một khối vị trí bị chuyển đi là chỉ thị 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 vị trí khớp mới dựa trên kết quả ghi lại.

Ví dụ: nếu chúng tôi sửa đổi ví dụ cuối cùng để bao gồm ghi lại, chúng tôi 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 cần dựa vào lệnh 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 đối với /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_filesn như bình thường, có thể khởi động lại /fallback/index.html nếu không tìm thấy gì (sử dụng try_files chuyển hướng nội bộ mà chúng 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. Việc viết lại được áp dụng một lần nữa, 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 chỉ thị 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ướ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 chỉ thị rewrite khi sử dụng các cờ redirect hoặc . permanentTuy nhiên, những tìm kiếm vị trí này sẽ không nằm ngoài dự kiến, 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 một chuyển hướng nội bộ tương tự như đượ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 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 bên ngoài /var/www/main. Tuy nhiên, nếu tệp không được tìm thấy (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. File này sẽ được phân phối ngoài /var/www/another/whoops.html.

Như bạn có thể 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.

Phần kết luận

Việc 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 tư cách là quản trị viên trở nên dễ dàng hơn nhiều. Bạn sẽ có thể biết Nginx sẽ chọn khối máy chủ 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.

» Tiếp: Cách cài đặt Linux, Nginx, MySQL, PHP (ngăn xếp LEMP) trên Ubuntu
« Trước: Cách cài đặt Nginx trên Ubuntu
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!