הבנת אלגוריתמי בחירת שרת ותוך אזורי המיקום של Nginx

הקדמה

נגינקס הוא אחד משרתי האינטרנט הפופולריים ביותר בעולם. הוא יכול לטפל בהעמסות גבוהה עם הרבה חיבורי לקוחות סוצים, ויכול לתפקד כשרת אינטרנט, שרת דואר או שרת פרוקסי הפוך.

במדריך זה, נדון בפרטי הפעלה שבעטיין את כיצד נגינקס מעבד בקשות לקוח. הבנת הרעיונות הללו יכולה לעזור להסיר את הנחות המערכת בעיצוב קוביות שרת ומיקום, ויכולה להפוך את טיפול בבקשות להרבה פחות לא צפוי.

תצורות מקטעי נגינקס

נגינקס מחלקת באופן לוגי את ההגדרות המיועדות לשרת תוכן שונה לבלוקים, הקיימים במבנה היררכי. בכל פעם שבקשת לקוח נעשית, נגינקס מתחילה תהליך לקביעת אילו בלוקי הגדרות ישמשו לטיפול בבקשה. התהליך הזה החלטתי נדון במדריך זה.

הבלוקים העיקריים שנדון בהם הם הבלוק שרת והבלוק מיקום.

A server block is a subset of Nginx’s configuration that defines a virtual server used to handle requests of a defined type. Administrators often configure multiple server blocks and decide which block should handle which connection based on the requested domain name, port, and IP address.

A location block lives within a server block and is used to define how Nginx should handle requests for different resources and URIs for the parent server. The URI space can be subdivided in whatever way the administrator likes using these blocks. It is an extremely flexible model.

איך Nginx החלטות על איזה בלוק שרת יטפל בבקשה

מאחר ש-Nginx מאפשר למנהל להגדיר מספר רב של בלוקי שרת הפועלים כמופעים וירטואליים נפרדים של שרת אינטרנט, יש לו ניהול על הצורך לקבוע איזה מבין אלה ישמש לטובת עמידת הבקשה.

הוא עושה זאת דרך מערכת מוגדרת של בדיקות שמשמשות למציאת ההתאמה הטובה ביותר. הפקודות העיקריות של בלוק השרת ש-Nginx דואגת להן במהלך תהליך זה הן פקודת listen, והפקודה server_name.

ניתוח של פקודת listen כדי למצוא התאמות פוטנציאליות

ראשית, Nginx מסתכלת על כתובת ה-IP והפורט של הבקשה. היא משווה את זה עם הפקודת listen של כל שרת כדי לבנות רשימה של בלוקי השרת שעשויים לפתור את הבקשה.

ההנחה הסטנדרטית היא שההוראה listen מגדירה בדרך כלל איזו כתובת IP ופורט יגיב בלוק השרת. בצורה ברירת מחדל, כל לוק שרת שאינו כולל הוראת listen מקבל את פרמטרי ההאזנה של 0.0.0.0:80 (או 0.0.0.0:8080 אם Nginx מופעל על ידי משתמש רגיל, לא root). זה מאפשר לבלוקים אלו להגיב לבקשות על כל ממשק בפורט 80, אך הערך ברירת המחדל הזה אינו נושא משמעות רבה בתהליך בחירת השרת.

ההוראה listen יכולה להיות מוגדרת ל:

  • קומבינציה של כתובת IP/פורט.
  • A lone IP address which will then listen on the default port 80.
  • A lone port which will listen to every interface on that port.
  • נתיב אל תקשורת Unix.

האפשרות האחרונה בדרך כלל משפיעה רק כאשר מעבירים בקשות בין שרתים שונים.

כאשר מנסים לקבוע לאיזו בלוק שרת לשלוח בקשה, Nginx ינסה תחילה להחליט על פי הספציפיות של ההוראה listen באמצעות החוקים הבאים:

  • Nginx מתרגם את כל ההוראות listen "לא שלמות" על ידי החלפת הערכים החסרים בערכים ברירת המחדל שלהם כך שכל בלוק יכול להיערך לפי כתובת ה-IP והפורט שלו. כמה דוגמאות לתרגומים אלו הן:
    • בלוק עם אין הוראת listen משתמש בערך 0.0.0.0:80.
    • בלוק שמוגדר לכתובת IP 111.111.111.111 ללא פורט הופך להיות 111.111.111.111:80
    • בלוק שמוגדר לפורט 8888 ללא כתובת IP הופך להיות 0.0.0.0:8888
  • Nginx מנסה לאסוף רשימה של בלוקי השרת המתאימים לבקשה באופן ממוקד ביותר על פי כתובת ה-IP והפורט. זה אומר שכל בלוק שמשתמש באופן פונקציונלי ב- 0.0.0.0 ככתובת ה-IP שלו (כדי להתאים לכל ממשק), לא יובחר אם יש בלוקים המתאימים שמפרטים כתובת IP ספציפית. בכל מקרה, על הפורט להתאים בדיוק.
  • אם יש רק התאמה מסוימת ביותר, בלוק השרת הזה ישמש לשרת את הבקשה. אם ישנם מספר בלוקי שרת עם אותו רמת ההתאמה, Nginx מתחיל לבדוק את ההוראה server_name של כל בלוק שרת.

חשוב להבין ש-Nginx יבדוק רק את ההוראה server_name כאשר יהיה צורך להבדיל בין בלוקי שרת שמתאימים לאותה רמת התאמה בהוראת ה- listen. לדוגמה, אם example.com מאורחת על פורט 80 של 192.168.1.10, בקשה עבור example.com תשורת תמיד תשמש על ידי הבלוק הראשון בדוגמה זו, למרות ההוראה server_name בבלוק השני.

server {
    listen 192.168.1.10;

    . . .

}

server {
    listen 80;
    server_name example.com;

    . . .

}

במקרה שבו יש יותר מבלוק שרת שמתאימים באותה הדיוק, השלב הבא הוא לבדוק את ההוראה server_name.

פירוק ההוראה server_name כדי לבחור התאמה

בשלב הבא, לצורך הערכתן של בקשות המכילות הנחיות listen באותו דיוק, Nginx בודקת את הכותרת Host של הבקשה. הערך הזה מכיל את הדומיין או כתובת ה-IP אליה ניסה הלקוח להגיע בפועל.

Nginx מנסה למצוא את ההתאמה הטובה ביותר עבור הערך שמופיע באמצעות בדיקת ההוראות server_name בתוך כל אחת מבלוקי השרת שעדיין הועמדו לצורך בחירה. Nginx מעריך את אלו באמצעות הנוסחה הבאה:

  • Nginx תנסה תחילה למצוא בלוק שרת עם server_name שמתאים לערך שבכותרת Host של הבקשה בדיוק. אם יימצא מופע כזה, הבלוק המתאים ישמש לשרת את הבקשה. אם יימצאו מספר התאמות בדיוק, ה-ראשונה תשמש.
  • אם לא נמצאה התאמה מדוייקת, Nginx תנסה למצוא בלוק שרת עם server_name שמתאים באמצעות תו כוכב (*) בתחילת השם בהגדרה. אם יימצא מופע כזה, הבלוק הוא שימש לשרת את הבקשה. אם יימצאו מספר התאמות, ההתאמה הארוכה ביותר תשמש לשרת את הבקשה.
  • אם לא יימצאה התאמה עם תו כוכב מראש, Nginx תחפש בלוק שרת עם server_name שמתאים באמצעות תו כוכב מסיים (*) בשם בהגדרה. אם יימצא מופע כזה, הבלוק הוא שימש לשרת את הבקשה. אם יימצאו מספר התאמות, ההתאמה הארוכה ביותר תשמש לשרת את הבקשה.
  • אם לא נמצאה התאמה בעזרת איחוד קידמי, Nginx תרטיב באפשרויות לשרת שמגדירות את server_name באמצעות רגולריות (מסומן על ידי ~ לפני השם). ה-ראשון server_name עם ביטוי רגולרי שתואם לכותרת "Host" ישמש לעבוד בבקשה.
  • אם לא נמצאה התאמה לביטוי רגולרי, Nginx בוחרת את בלוק השרת המוגדר כברירת מחדל עבור כתובת ה-IP והפורט.

לכל קומבינציה של כתובת IP/פורט יש בלוק שרת ברירת מחדל שישמש כאשר לא ניתן לקבוע פעולה באמצעות השיטות הנ"ל. עבור קומבינציה של כתובת IP/פורט, זה יהיה או הבלוק הראשון בתצורה או הבלוק שמכיל את אפשרות ה-default_server כחלק מההנחיה listen (שתכסה את האלגוריתם שנמצא ראשון). יכול להיות רק דיבור אחד של default_server לכל קומבינציה של כתובת IP/פורט.

דוגמאות

אם יש server_name שהוגדר בדיוק כמו ערך הכותרת של Host, בלוק השרת הוא בחירתו לעיבוד הבקשה.

בדוגמה זו, אם כותרת הבקשה הייתה מוגדרת ל-host1.example.com, השרת השני יבחר:

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

    . . .

}

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

    . . .

}

אם לא נמצאה התאמה מדויקת, Nginx יבדוק אם קיים server_name עם תו כוכב (*) בתחילתו שמתאים. ההתאמה הארוכה ביותר החלה עם כוכב תבחר למלא את הבקשה.

לדוגמה, בדוגמה זו, אם יש לבקשה כותרת Host של www.example.org, יבחר בבלוק השרת השני:

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

    . . .

}

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

    . . .

}

server {
    listen 80;
    server_name *.org;

    . . .

}

אם לא נמצאה התאמה עם כוכב בתחילתו, Nginx יחפש האם יש התאמה באמצעות כוכב בסופו של הביטוי. בנקודה זו, ההתאמה הארוכה ביותר שמסתיימת עם כוכב תבחר לשרת את הבקשה.

לדוגמה, אם לבקשה יש כותרת Host שמוגדרת כ־www.example.com, יבחר בבלוק השרת השלישי:

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

    . . .

}

server {
    listen 80;
    server_name example.com;

    . . .

}

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

    . . .

}

אם לא ניתן למצוא התאמות עם כוכבית, Nginx יעבור לניסיון להתאים server_name שמשתמש בביטויים רגולריים. הביטוי הרגולרי המתאים הראשון יבחר להגיב לבקשה.

לדוגמה, אם כותרת הבקשה מוגדרת כ־www.example.com, אז בלוק השרת השני יבחר למלא את הבקשה:

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$;

    . . .

}

אם אף אחת מהשלבים לעיל לא מצליחה למלא את הבקשה, הבקשה תועבר לשרת ברירת המחדל עבור כתובת ה־IP והיציאה התואמים.

התאמת בלוקי מיקום

בדומה לתהליך שה-Nginx משתמשת בו כדי לבחור את בלוק השרת שיעבד בקשה, גם ל-Nginx יש אלגוריתם מובהק להחלטה על איזה בלוק מיקום בתוך השרת להשתמש בו לטיפול בבקשות.

תחביר בלוק מיקום

לפני שנכסה איך ה-Nginx מחליטה איזה בלוק מיקום להשתמש בו לטיפול בבקשות, בואו נכסה מחדש את חלק מהתחביר שאולי תראו בהגדרות בלוק מיקום. בלוקי המיקום קיימים בתוך בלוקי שרת (או בלוקי מיקום אחרים) ומשמשים להחלטת כיצד לעבד את כתובת ה-URI של הבקשה (החלק של הבקשה שבא אחרי שם הדומיין או כתובת ה-IP/פורט).

בדרך כלל, בלוקי מיקום מתקבלים בתבנית הבאה:

location optional_modifier location_match {

    . . .

}

ה־location_match בדוגמה לעיל מגדיר מה ש-Nginx צריך לבדוק את כתובת ה-URI של הבקשה נגד. הקיום או האי קיום של המודיפיקטור בדוגמה לעיל משפיע על הדרך שבה ה-Nginx מנסה להתאים את בלוק המיקום. המודיפיקטורים שלמטה יגרמו להפעלת בלוק המיקום המתאים כדלקמן:

  • (ללא): אם לא קיימים מודיפיקטורים, המיקום מתפרש כהתאמת קידמה. זה אומר שהמיקום שניתן יתאמץ להתאים לתחילת כתובת ה-URI של הבקשה כדי לקבוע התאמה.
  • =: אם סימן השווה משמש, בלוק זה יחשב כהתאמה אם כתובת ה-URI של הבקשה תואמת בדיוק את המיקום שניתן.
  • ~: אם מודיפייר הגלוייה קיימים, מיקום זה יתפרש כהתאמת ביטוי רגולרי תלוית רגישה לאותיות רישיות.
  • ~*: אם מודיפייר הגלוייה וכוכבית משמשים, משבצת המיקום תתפרש כהתאמת ביטוי רגולרי תלוית בלתי רגישה לאותיות רישיות.
  • ^~: אם מודיפייר הגלוייה קרט וגלוייה קיימים, ואם הבלוק זה נבחר כהתאמה הטובה ביותר שאינה תלוית ביטוי רגולרי, התאמת ביטוי רגולרי לא תתבצע.

דוגמאות לתחביר בלוק מיקום

כדי להמחיש התאמת תחילית, בלוק המיקום הבא עשוי להיות מופעל להגביל בקשות URI שנראות כמו /אתר, /אתר/עמוד1/index.html, או /אתר/index.html:

location /site {

    . . .

}

להמחיש התאמת תחילית דווקא של בקשת URI, בלוק זה תמיד ישמש להגביל בקשת URI שנראה כמו /עמוד1. הוא לא ישמש להגביל בקשת URI שנראה כמו /עמוד1/index.html. יש לשים לב כי אם בלוק זה נבחר והבקשה מתמלאת באמצעות דף אינדקס, יתרום פנימי יתרחש למיקום אחר שיהיה המנהל האמיתי של הבקשה:

location = /page1 {

    . . .

}

כדי לדמות מיקום שצריך להיפסק כביטוי רגולרי התלבשות רגיש לרישיות, בלוק זה יכול לשמש לטיפול בבקשות עבור /tortoise.jpg, אך לא עבור /FLOWER.PNG:

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

    . . .

}

A block that would allow for case-insensitive matching similar to the above is shown below. Here, both /tortoise.jpg and /FLOWER.PNG could be handled by this block:

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

    . . .

}

וסוף סוף, בלוק זה ימנע התאמת ביטוי רגולרי מתרחשת אם נקבע כי זהו ההתאמה הטובה ביותר לא מבוטאת ביטוי רגולרי. הוא יכול לטפל בבקשות עבור /costumes/ninja.html:

location ^~ /costumes {

    . . .

}

כפי שרואים, המודיפיקטורים מציינים איך להבין את בלוק המיקום. אך זה לא מספק לנו את האלגוריתם שבו משתמש Nginx כדי להחליט לאיזו בלוק מיקום לשלוח את הבקשה. נעבור לכך בשורה הבאה.

איך Nginx בוחר איזה מיקום להשתמש בו לטיפול בבקשות

Nginx בוחר במיקום שישמש לשרת בקשה בדרך דומה לאיך שהוא בוחר בבלוק שרת. הוא עובר דרך תהליך שמקבע את הבלוק הטוב ביותר לכל בקשה נתונה. הבנת תהליך זה היא דרישה חיונית להגדרת Nginx באופן אמין ומדויק.

שמירה על רוח הסוגים של ההצהרות למיקום שתיארנו למעלה, Nginx מעריך את הקשרים האפשריים של מיקומים על ידי השוואת כתובת ה-URI של הבקשה לכל אחד מהמיקומים. הוא עושה זאת באמצעות האלגוריתם הבא:

  • Nginx מתחילה על ידי בדיקת כל ההתאמות של מיקום מבוססות קידומת (כל סוגי המיקומים שאינם כוללים ביטוי רגולר). היא בודקת כל מיקום נגד URI הבקשה המלא.
  • ראשית, Nginx מחפשת התאמה מדויקת. אם מופעלת לבלוק מיקום באמצעות המודיפייר = שמתאימה ל URI הבקשה בדיוק, הבלוק מיקום הזה נבחר מיידית כדי לשרת את הבקשה.
  • אם לא נמצאות התאמות מדויקות (עם המודיפייר =), Nginx ממשיכה אל בדיקת קידומות שאינן מדויקות. היא מוצאת את המיקום עם הקידומת הארוכה ביותר המתאימה ל-URI שניתן, ואז היא מבצעת את הערכה הבאה:
    • אם למיקום עם הקידומת הארוכה ביותר יש את המודיפייר ^~, אז Nginx תסיים מייד את חיפושה ותבחר באופן מיידי את המיקום הזה כדי לשרת את הבקשה.
    • אם למיקום עם הקידומת הארוכה ביותר אין את המודיפייר ^~, ההתאמה מאוחסנת על ידי Nginx לרגע כדי שיהיה ניתן להעביר את מוקד החיפוש.
  • לאחר שהמיקום של הפריט הארוך ביותר הוא מוגדר ומאוחסן, Nginx הולך לבדוק ולהעריך את מיקומי הביטויים הרגילים (גם ברגישות לאותיות גדולות וקטנות). אם יש כל מיקום ביטוי רגולרי בתוך המיקום של הפריט הארוך ביותר, Nginx יעביר אותם לראש של רשימת המיקומים של ביטויים רגולריים לבדיקה. לאחר מכן, Nginx מנסה להתאים את הבקשה לפי המיקומים של ביטויים רגולריים בסדר רציונאלי. המיקום הרגולרי הראשון שמתאים ל-URI של הבקשה מתבחר מיידית כדי לשרת את הבקשה.
  • אם לא נמצאו מיקומי ביטויים רגולריים המתאימים ל-URI של הבקשה, מיקום הפריקס האחסון מהפעם הקודמת יבחר לשרת את הבקשה.

חשוב להבין שכברירת מחדל, Nginx ישרת התאמות ביטויים רגולריים לפני התאמות פריקס. מכיוון שהיא מעריכה מיקומי פריקס תחילה, היא מאפשרת למנהל לדרוס את המגמה זו על ידי ציון מיקומים באמצעות המחלקים = ו-^~.

חשוב גם לציין כי, בעוד מיקומי פריקס בדרך כלל בוחרים בהתאמה הארוכה ביותר והמדויקת ביותר, הערכה של ביטויים רגולריים מופסקת כאשר מצויה התאמה ראשונה. זה אומר שהמיקום בתוך התצורה משפיעה בצורה משמעותית על מיקומי ביטויים רגולריים.

לסיום, חשוב להבין כי התאמות ביטויים רגולריים בתוך ההתאמה הארוכה ביותר תקפצנה "לקו אחורה" כאשר Nginx מעריך מיקומי Regex. אלה יוערכו, בסדר, לפני שישום כל אחת מההתאמות האחרות של ביטויים רגולריים. מקסים דונין, מפתח Nginx מועיל ביותר, מסביר בפוסט הזה את חלק זה של אלגוריתם הבחירה.

מתי הערכת בלוק המיקום מדלגת למיקומים אחרים?

באופן כללי, כאשר בלוק מיקום נבחר לטיפול בבקשה, הבקשה נטולת התערבות ניתן במלואה בהקשר הזה מאותו הנקודה והלאה. רק המיקום הנבחר וההנחות המורשות קובעים איך הבקשה תעובד, ללא התערבות מבלוקי מיקום אחים.

אף על פי שזו כלל כללי שיאפשר לך לעצב את בלוקי המיקום שלך בדרך צפויה, חשוב להבין כי ישנם רגעים בהם חיפוש מיקום חדש מופעל על ידי כמה הנחיות מסוימות בתוך המיקום הנבחר. יכולות החריגה מחוק "רק מיקום אחד" עשויות להיות להשפעה על אופן בו הבקשה מוגשת בפועל ועשויות שלא להיות מותאמות לציפיות שהיו לך בעת עיצוב בלוקי המיקום שלך.

מספר ההנחיות שעשויות להוביל להפניה פנימית כזו הם:

  • אינדקס
  • נסה_קבצים
  • rewrite
  • error_page

בואו נעבור על זה בקצרה.

ההנחיה index תמיד מובילה להפניה פנימית אם היא משמשת לטיפול בבקשה. התאמות מדויקות למיקום נמצאות לעיתים קרובות בשימוש כדי להאיץ את תהליך הבחירה על ידי סיום מיידי של ביצוע האלגוריתם. אך, אם אתה עושה התאמת מיקום מדויקת שהיא ספרייה, יש סיכוי טוב שהבקשה תופנה למיקום שונה לעיבוד בפועל.

בדוגמה זו, המיקום הראשון מתאים ל-URI של הבקשה /exact, אך כדי לטפל בבקשה, ההנחיה index שמורשת על ידי הבלוק מפעילה הפניה פנימית לבלוק השני:

index index.html;

location = /exact {

    . . .

}

location / {

    . . .

}

במקרה מעלה, אם אתה באמת צריך שהביצוע יישאר בבלוק הראשון, עליך למצוא שיטה שונה לספק את הבקשה לתיקייה. לדוגמה, תוכל להגדיר index לא תקין עבור הבלוק הזה ולהפעיל autoindex:

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

location  / {

    . . .

}

זו דרך אחת למניעת מצב ש-index יחליף קשרים, אך זה כנראה לא שימושי לרוב התצורות. בעיקר מתאמת מדויקת על ספריות יכולה להיות שימושית לדברים כמו רישום הבקשה מחדש (שגם גורם לחיפוש מיקום חדש).

עוד מקרה בו ניתן להעריך מחדש את מיקום העיבוד הוא עם ההנחיה try_files. ההנחיה הזו אומרת ל-Nginx לבדוק את קיום סט מסוים של קבצים או תיקיות. הפרמטר האחרון יכול להיות URI ש-Nginx יבצע הפניה פנימית אליו.

שקול את התצורה הבאה:

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

location /fallback {
    root /var/www/another;
}

בדוגמה לעיל, אם בוצע בקשה עבור /blahblah, המיקום הראשון יקבל את הבקשה בתחילה. הוא ינסה למצוא קובץ בשם blahblah בתיקיית /var/www/main. אם לא ימצא אחד, הוא ימשיך לחיפוש אחר קובץ בשם blahblah.html. לאחר מכן, הוא ינסה לראות האם יש ספרייה בשם blahblah/ בתוך התיקייה /var/www/main. במקרה של כישלון בכל אחת מהניסיונות הללו, הוא יפנה אל /fallback/index.html. זה יפעיל חיפוש מיקום נוסף שיתפוס על ידי הבלוק השני של המיקום. זה ישרת את הקובץ /var/www/another/fallback/index.html.

קידור אחר שיכול להוביל למעבר של בלוק המיקום הוא ההוראה rewrite. כאשר משתמשים בפרמטר last עם ההוראה rewrite, או כאשר לא משתמשים בפרמטר כלל, Nginx יחפש מיקום חדש התואם לפי תוצאות השינוי.

לדוגמה, אם נשנה את הדוגמה האחרונה כך שתכלול כתיבה מחדש, נוכל לראות שהבקשה לעיתים תועבר ישירות למיקום השני בלי לסמוך על ההוראת 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;
}

בדוגמה לעיל, בקשה עבור /rewriteme/hello תתקבל תחילה על ידי הבלוק הראשון של המיקום. היא תתבצע מחדש כדי /hello ומיקום יחפש. במקרה זה, היא תתאים שוב למיקום הראשון ותעובד על ידי try_files כרגיל, אולי מעבירה חזרה ל- /fallback/index.html אם לא נמצא כלום (באמצעות ההפניה הפנימית של try_files שדנו לעיל).

אך, אם בוצעה בקשה עבור /rewriteme/fallback/hello, הבלוק הראשון יתאים שוב. הניתוב ייושם שוב, הפעם תוצאתו תהיה /fallback/hello. הבקשה תשוב להיות שירות מהבלוק השני.

A related situation happens with the return directive when sending the 301 or 302 status codes. The difference in this case is that it results in an entirely new request in the form of an externally visible redirect. This same situation can occur with the rewrite directive when using the redirect or permanent flags. However, these location searches shouldn’t be unexpected, since externally visible redirects always result in a new request.

ההוראה error_page עשויה להוביל להפניה פנימית דומה לזו שנוצרת על ידי try_files. ההוראה הזו משמשת להגדרת מה ישתייך כאשר מקודי מצב מסוימים נתקלים. דבר זה כנראה לעולם לא יופעל אם ההוראה try_files מוגדרת, מאחר וההוראה הזו עוסקת במחזור החיים של בקשה במלואו.

שקול את הדוגמה הבאה:

root /var/www/main;

location / {
    error_page 404 /another/whoops.html;
}

location /another {
    root /var/www;
}

כל בקשה (מלבד אלה שמתחילות ב- /another) תיטול טיפול על ידי הבלוק הראשון, אשר ישרת קבצים מתוך /var/www/main. אך, אם קובץ לא נמצא (קוד מצב 404), הפניה פנימית ל- /another/whoops.html תתבצע, מובילה לחיפוש מיקום חדש שבסופו תתקבל בבלוק השני. קובץ זה ישרת מתוך /var/www/another/whoops.html.

כפי שניתן לראות, הבנת הנסיבות שבהן Nginx מפעיל חיפוש מיקום חדש עשויה לסייע בניבוי ההתנהגות שתראו בעת ביצוע בקשות.

מסקנה

הבנת הדרכים שבהן Nginx מעבד בקשות מהלקוח יכולה לשפר לך את העבודה כמנהל מערכת בצורה ניכרת. תוכל לדעת אילו בלוקי שרת יבחר Nginx בהתבסס על כל בקשה מהלקוח. תוכל גם לדעת איך בלוק המיקום יבחר בהתבסס על כתובת ה-URI של הבקשה. בסך הכול, ידע על הדרכים שבהן Nginx בוחר בלוקים שונים יעניק לך את היכולת לעקוב אחר ההקשרים שבהם Nginx יחליט ליישם כדי לשרת כל בקשה.

Source:
https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms