Επιστροφή στο blog

Αλγόριθμοι Επιλογής Nginx Server και Location Block: Επισκόπηση

Αλγόριθμοι Επιλογής Nginx Server και Location Block: Επισκόπηση

Εισαγωγή

Nginx είναι μεταξύ των πιο δημοφιλών επιλογών web server παγκοσμίως. Είναι σε θέση να διαχειρίζεται με επιτυχία ένα πλήθος ταυτόχρονων συνδέσεων πελατών. Ταυτόχρονα, λειτουργεί ως διακομιστής αλληλογραφίας, ιστού ή reverse proxy.

Αυτός ο οδηγός στοχεύει να περιγράψει τις παρασκηνιακές μεθόδους που κατευθύνουν τον τρόπο με τον οποίο το Nginx επεξεργάζεται τα αιτήματα των πελατών. Θα απομυθοποιήσουμε τη σχεδίαση server και location block, καθώς και να εξηγήσουμε πώς να μειώσετε καλύτερα τη φαινομενική απρόβλεπτη συμπεριφορά κατά τη διαχείριση των αιτημάτων.

Πρώτα απ' όλα, ορίστε ένας ολοκληρωμένος οδηγός σχετικά με το πώς να εγκαταστήσετε το Nginx στον Ubuntu διακομιστή σας. Τώρα, ας ξεκινήσουμε!

Διαμόρφωση Block με το Nginx

Η λογική προσέγγιση του Nginx περιλαμβάνει την ταξινόμηση των ρυθμίσεων που προορίζονται για διαφορετικούς σκοπούς σε ξεχωριστά, πιο λογικά blocks περιεχομένου. Αυτά θα βρίσκονται σε μια ιεραρχική δομή. Όταν ένας πελάτης υποβάλλει ένα αίτημα, το Nginx ξεκινά μια διαδικασία μέσω της οποίας καθορίζει ποια από αυτά τα blocks ρυθμίσεων είναι τα πλέον κατάλληλα για την αντιμετώπιση αυτού του αιτήματος. Θα εστιάσουμε σε αυτή τη διαδικασία λήψης αποφάσεων.

Τα κύρια blocks που θα συζητήσουμε θα είναι τα server blocks και τα location blocks. Τα server blocks είναι ένα υποσύνολο των ρυθμίσεων που καθορίζει το Nginx, οι οποίες ορίζουν ποιος εικονικός διακομιστής (virtual server) θα είναι υπεύθυνος για τη διαχείριση ενός καθορισμένου τύπου αιτήματος. Βασίζονται συχνότερα στη διεύθυνση IP, το όνομα τομέα (domain name) ή τη θύρα (port) του εισερχόμενου αιτήματος. Οι διαχειριστές διαμορφώνουν πολλαπλά server blocks. Στη συνέχεια, πρέπει να αποφασίσουν ποια από τις συνδέσεις θα πρέπει να διαχειρίζεται το αίτημα.

Τα location blocks βρίσκονται μέσα στα server blocks. Αυτά λαμβάνουν τις αποφάσεις σχετικά με το πώς και ποιους πόρους μπορείτε να αξιοποιήσετε για να διαχειριστείτε τα εισερχόμενα αιτήματα στον συγκεκριμένο γονικό διακομιστή τους. Αυτό το μοντέλο είναι εξαιρετικά ευέλικτο. Ο χώρος URI μπορεί να διαμορφωθεί ώστε να χρησιμοποιεί αυτά τα blocks με όποιον τρόπο κρίνει καλύτερο ο διαχειριστής.

Αποφασίστε ποιο Block θα διαχειριστεί ποιο αίτημα με το Nginx

Το Nginx επιτρέπει τον ορισμό πολλαπλών server blocks. Όλα τους λειτουργούν ως διαφορετικοί εικονικοί διακομιστές ιστού (virtual web servers). Επομένως, πρέπει να υπάρχει μια μέθοδος που να προσδιορίζει ποιος διακομιστής θα αντιμετωπίζει συγκεκριμένα εισερχόμενα αιτήματα. Αυτό γίνεται βρίσκοντας την καλύτερη αντιστοίχιση για την απόδοση του αιτήματος μέσω ενός συστήματος καθορισμένων ελέγχων.

Το Nginx ασχολείται κυρίως με δύο βασικές οδηγίες (directives) των server blocks: listen και server_name.

Εύρεση πιθανών αντιστοιχιών με την οδηγία ‘Listen’

Το πρώτο πράγμα που αξιολογεί το Nginx είναι η θύρα (port) και η διεύθυνση IP του αιτήματος. Στη συνέχεια, το αντιστοιχίζει με την οδηγία listen κάθε διακομιστή. Αυτή η ανάλυση (parsing) της λίστας διακομιστών βοηθά στην απομόνωση μόνο εκείνων των server blocks που μπορούν να επιλύσουν το εν λόγω αίτημα.

Συνήθως, η οδηγία listen ορίζει τη θύρα και τη διεύθυνση IP στις οποίες θα είναι υπεύθυνο να απαντά ένα συγκεκριμένο server block. Ένα server block που δεν διαθέτει οδηγία listen λαμβάνει από προεπιλογή τις παραμέτρους listen 0.0.0.0:80. Εάν το Nginx εκτελείται από έναν κανονικό χρήστη, μη root, η παράμετρος listen ορίζεται ως 0.0.0.0:8080. Αυτό σημαίνει ότι ανεξάρτητα από τη διεπαφή (interface), εάν τα blocks προέρχονται από τη θύρα 80, τα blocks που ορίζονται με αυτόν τον τρόπο θα απαντήσουν σε αυτά. Ωστόσο, αυτή η προεπιλεγμένη τιμή δεν λαμβάνεται σοβαρά υπόψη στη διαδικασία επιλογής διακομιστή.

Μπορείτε να διαμορφώσετε την οδηγία listen σε:

  • Μια μεμονωμένη διεύθυνση IP που ακούει για αιτήματα στην προεπιλεγμένη θύρα (80).
  • Μια μεμονωμένη θύρα που ακούει σε οποιαδήποτε διεπαφή σε αυτήν τη θύρα.
  • Έναν συνδυασμό θύρας και διεύθυνσης IP.
  • Μια καθορισμένη διαδρομή Unix socket (αυτή η επιλογή έχει σημασία μόνο όταν τα αιτήματα περνούν από διαφορετικούς διακομιστές).

Το Nginx θα εφαρμόσει ένα σύνολο κανόνων όταν αποφασίζει σε ποιο server block θα σταλεί ένα αίτημα. Οι κανόνες εξαρτώνται από τη συγκεκριμένη διαμόρφωση της οδηγίας listen. Έχουν ως εξής:

  • Εάν μια οδηγία listen είναι ελλιπής, τα κομμάτια που λείπουν λαμβάνουν τις προεπιλεγμένες τιμές τους. Αυτό σημαίνει ότι η διεύθυνση IP και η θύρα θα συμπληρωθούν αναγκαστικά με προεπιλεγμένες τιμές προκειμένου να υποβληθεί σε επεξεργασία το αίτημα.
    • Σε αυτήν την περίπτωση, ένα block που δεν περιέχει οδηγία listen θα χρησιμοποιήσει την προεπιλεγμένη τιμή 0.0.0.0:80.
    • Ένα block στο οποίο λείπει μια θύρα και έχει διεύθυνση IP 111.111.111.111 θα γίνει 111.111.111.111:80.
    • Όταν δεν υπάρχει διεύθυνση IP, ένα block με θύρα 8888 θα αποκτήσει την προεπιλεγμένη διεύθυνση IP για να προσαρτηθεί και να δημιουργήσει το 0.0.0.0:8888.
  • Έχοντας την καθορισμένη διεύθυνση IP και θύρα, ο Nginx θα αναζητήσει στη συνέχεια server blocks που προσφέρονται ως αντιστοιχία σε αυτήν τη θύρα.
  • Αν βρει μόνο μία συγκεκριμένη αντιστοιχία, αυτό θα είναι το server block. Αν υπάρχουν πολλαπλά blocks που πληρούν τις προϋποθέσεις, ο Nginx θα στραφεί στην οδηγία server_name για να περιορίσει περαιτέρω την αναζήτηση στο ακριβές server block.

Ο Nginx θα καταφύγει στην αξιολόγηση της οδηγίας server_name μόνο εάν δεν βρήκε το server block με το ακριβές επίπεδο εξειδίκευσης από την οδηγία listen. Εάν το example.com βρίσκεται στη θύρα 80, με IP 192.168.1.10, το πρώτο block σε αυτό το παράδειγμα θα είναι πάντα αυτό που εξυπηρετεί το αίτημα. Αυτό ισχύει ανεξάρτητα από το τι λέει η οδηγία server_name:

Nginx Server

Εάν υπάρχουν περισσότερα από ένα κατάλληλα blocks υπηρεσιών με αντιστοιχία εξειδίκευσης, τότε θα ληφθεί υπόψη η οδηγία server_name.

Εύρεση πιθανών αντιστοιχιών με την οδηγία ‘Server_Name’

Εάν οι οδηγίες listen είναι εξίσου συγκεκριμένες, ο Nginx θα ελέγξει την κεφαλίδα ‘Host’ του αιτήματος’. Αυτή είναι μια τιμή που θα έχει την IP του domain που προσπαθούσε να προσεγγίσει αρχικά ο πελάτης. Ο Nginx θα χρησιμοποιήσει την οδηγία server_name μέσα σε κάθε υποψήφιο server block που εξακολουθεί να πληροί τις προϋποθέσεις. Εκτελεί αυτές τις αξιολογήσεις με βάση έναν τύπο. Έχει ως εξής:

  • Η πρώτη προσπάθεια του Nginx θα είναι να εντοπίσει ένα block με server_name που να ταιριάζει ακριβώς με την τιμή της κεφαλίδας ‘Host’ στο αίτημα. Εάν το βρει, το block που περιέχει την ακριβή αντιστοιχία θα είναι αυτό που θα εξυπηρετήσει το αίτημα. Σε περίπτωση που βρει πολλαπλά blocks, θα επιλέξει το πρώτο στη λίστα.
  • Εάν δεν υπάρχουν ακριβείς αντιστοιχίες, ο Nginx θα προσπαθήσει στη συνέχεια να χρησιμοποιήσει το server_name για να βρει το server block που ταιριάζει με τη χρήση του *, ενός χαρακτήρα μπαλαντέρ (wildcard) στην αρχή του ονόματος του server block στη διαμόρφωση. Η εύρεση ενός με αυτήν τη μέθοδο σημαίνει ότι το server block έχει καθοριστεί. Εάν βρει περισσότερες από μία αντιστοιχίες, η μεγαλύτερη σε μήκος αντιστοιχία θα είναι αυτή που θα εκπληρώσει το αίτημα.
  • Χωρίς αντίστοιχο μπαλαντέρ στην αρχή, ο Nginx θα προσπαθήσει να βρει ένα server block με αντίστοιχο μπαλαντέρ στο τέλος. Με άλλα λόγια, αυτό θα είναι ένα όνομα διακομιστή με ένα * στο τέλος στη διαμόρφωση. Εάν βρεθεί ένα, χρησιμοποιείται για το αίτημα. Ενώ, εάν βρείτε πολλά, ο Nginx θα χρησιμοποιήσει και πάλι τη μεγαλύτερη σε μήκος αντιστοιχία.
  • Σε περίπτωση που εξακολουθούν να μην υπάρχουν αντιστοιχίες μετά από τις δύο προσπάθειες με μπαλαντέρ, ο Nginx θα αξιολογήσει εκείνα τα server blocks που ορίζουν το server_name χρησιμοποιώντας κανονικές εκφράσεις (που υποδεικνύονται με ένα ~ πριν από το όνομα). Η πρώτη εμφάνιση του server_name με μια έκφραση που ταιριάζει με αυτήν της κεφαλίδας ‘Host’, θα θεωρηθεί ως το server block για τη διαχείριση του αιτήματος.
  • Εάν σε αυτό το σημείο εξακολουθούν να μην υπάρχουν αντιστοιχίες, ο Nginx θα χρησιμοποιήσει το προεπιλεγμένο server block για αυτόν τον συνδυασμό θύρας και διεύθυνσης IP.

Κάθε συνδυασμός θύρας/διεύθυνσης IP θα έχει ένα καθορισμένο server block. Θα χρησιμοποιηθεί εάν οι κανόνες καθορισμού του κατάλληλου server block για τη διαχείριση αιτημάτων αποβούν άκαρποι. Αυτό θα είναι το πρώτο block στη διαμόρφωση που περιέχει μια επιλογή default_server στην οδηγία listen (θα υπερισχύει του αλγορίθμου που βρέθηκε αρχικά). Κάθε συνδυασμός διεύθυνσης IP/θύρας μπορεί να έχει, το πολύ, μία ρύθμιση default_server.

Παραδείγματα επιλογής Server Block

Εάν το ορισμένο server_name ταιριάζει ακριβώς με την τιμή της κεφαλίδας ‘Host’, θα είναι το server block που θα επιλεγεί για την επεξεργασία του αιτήματος. Το ακόλουθο παράδειγμα δείχνει μια κεφαλίδα ‘Host’ του αιτήματος που ορίζεται ως “host1.example.com”. Σε αυτήν την περίπτωση, θα επιλέξει τον δεύτερο διακομιστή:

Nginx Server

Χωρίς ακριβή αντιστοιχία, ο Nginx θα ελέγξει εάν υπάρχει το server_name με μπαλαντέρ. Εάν όχι, θα επιλεγεί η μεγαλύτερη σε μήκος αντιστοιχία που ξεκινά με μπαλαντέρ. Στο ακόλουθο, “www.example.org” βρίσκεται στην κεφαλίδα “Host”. Αυτό σημαίνει ότι θα επιλέξει το δεύτερο block:

server screenshot

Χωρίς αντιστοίχιση που να ξεκινά με μπαλαντέρ, ο Nginx προχωρά σε έλεγχο τελικού μπαλαντέρ. Η μεγαλύτερη αντιστοίχιση που τελειώνει με το μπαλαντέρ θα επιλεγεί για την επεξεργασία του αιτήματος. Σε αυτήν την περίπτωση, η κεφαλίδα «Host» είναι «www.example.com», οπότε θα επιλέξει το τρίτο server block:

Nginx Server

Αν και πάλι δεν υπάρχουν αντιστοιχίσεις, ο Nginx θα προσπαθήσει να αντιστοιχίσει τις οδηγίες server_name χρησιμοποιώντας κανονικές εκφράσεις. Η πρώτη από αυτές τις εκφράσεις επιλέγεται για την επεξεργασία του αιτήματος. Αν το «Host» είναι «www.example.com,» το δεύτερο server block θα είναι η επιλογή για την εξυπηρέτηση του αιτήματος:

Nginx Server

Αν και πάλι δεν υπάρχει αντιστοίχιση, το αίτημα θα μεταβεί στον συνδυασμό διεύθυνσης IP και θύρας με τον αντίστοιχο προεπιλεγμένο διακομιστή (default server) που έχει ρυθμιστεί.

Αντιστοίχιση Location Block

Ο Nginx πρέπει επίσης να καθορίσει έναν αλγόριθμο με τον οποίο θα αποφασίζει ποιο location block στον διακομιστή θα είναι υπεύθυνο για την απάντηση σε ένα αίτημα.

Σύνταξη για Location Blocks

Πριν εξηγήσουμε πώς ο Nginx αποφασίζει να ορίσει το location block που θα χειρίζεται τα αιτήματα, θα εξετάσουμε τη σύνταξη στους ορισμούς των location blocks. Όπως αναφέρθηκε προηγουμένως, τα location blocks βρίσκονται μέσα σε server blocks (και άλλα location blocks). Ο σκοπός τους είναι να λαμβάνουν αποφάσεις σχετικά με τον τρόπο επεξεργασίας του URI του αιτήματος. Το URI είναι το τμήμα του αιτήματος που έρχεται μετά τη διεύθυνση IP και τη θύρα ή το όνομα τομέα (domain name) στο αίτημα.

Τα location blocks συνήθως μοιάζουν κάπως έτσι:

Syntax for Location Blocks

Ο Nginx θα ελέγξει το URI του αιτήματος σε σχέση με το location_match. Η παρουσία ή μη του παραπάνω τροποποιητή θα καθορίσει τον τρόπο με τον οποίο ο Nginx θα προσπαθήσει να αντιστοιχίσει τα blocks. Ανάλογα με τον τροποποιητή, τα location blocks θα ερμηνευθούν σύμφωνα με τους ακόλουθους κανόνες:

  • Χωρίς τροποποιητές: Χωρίς τροποποιητές, το location θα ερμηνευθεί ως αντιστοίχιση προθέματος (prefix match). Αυτό σημαίνει ότι η παρεχόμενη τοποθεσία θα αντιστοιχιστεί με την αρχή του URI στο αίτημα για να προσδιοριστεί μια σωστή αντιστοίχιση.
  • =: Το σύμβολο του ίσου σημαίνει ότι αυτό το block θα θεωρηθεί ως αντιστοίχιση εφόσον το URI του αιτήματος ταιριάζει ακριβώς με την παρεχόμενη τοποθεσία.
  • ~: Ο τροποποιητής περισπωμένης (tilde) υποδηλώνει ότι η αντιστοίχιση του location block θα έχει διάκριση πεζών-κεφαλαίων (case sensitive).
  • ~*: Ο συνδυασμός περισπωμένης και αστερίσκου υποδηλώνει ότι το location block δεν θα έχει διάκριση πεζών-κεφαλαίων (case-insensitive) κατά την αναζήτηση αντιστοίχισης.
  • ^~: Εάν πριν από τον τροποποιητή περισπωμένης υπάρχει μια εισαγωγική (carat - ^), δεν θα πραγματοποιηθεί αντιστοίχιση κανονικών εκφράσεων (regular expression matching) εφόσον αυτό το block επιλεγεί ως η καλύτερη αντιστοίχιση μη κανονικής έκφρασης.

Παραδείγματα Σύνταξης Location Block

Για να παρουσιάσουμε ένα παράδειγμα αντιστοίχισης προθέματος, το location block θα είναι η επιλογή για την απάντηση σε ένα URI αιτήματος της μορφής /site, /site/page1/index.html ή /site/index/html:

location site

Για τους σκοπούς αυτής της επίδειξης της απαιτούμενης αντιστοίχισης URI, το block θα χρησιμοποιείται πάντα για να απαντά σε αιτήματα URI της μορφής /page1, και όχι στο URI αιτήματος /page1/index.html. Εάν αυτό είναι το επιλεγμένο block και ικανοποιεί το αίτημα χρησιμοποιώντας μια σελίδα ευρετηρίου (index page), ο πραγματικός χειριστής του αιτήματος θα ανακατευθυνθεί εσωτερικά σε μια άλλη τοποθεσία (location):

Nginx Server

Για παράδειγμα, μια τοποθεσία που πρέπει να ερμηνευθεί με έκφραση που έχει διάκριση πεζών-κεφαλαίων, το ακόλουθο block δεν θα μπορούσε να χειριστεί αιτήματα για το /FLOWER.PNG. Ωστόσο, θα χειριστεί αιτήματα για το /tortoise.jpg:

Nginx Server and Location Block Selection Algorithms: Overview

Στη συνέχεια, παρατηρήστε ένα block που θα επέτρεπε αντιστοίχιση χωρίς διάκριση πεζών-κεφαλαίων, παρόμοιο με το παραπάνω. Σε αυτήν την περίπτωση, το block θα μπορούσε να χειριστεί τόσο το //tortoise.jpg και /FLOWER.PNG:

location

Η τελευταία παραλλαγή είναι αυτή στην οποία ένα block θα εμπόδευζε την εκτέλεση αντιστοίχισης κανονικών εκφράσεων, εάν κριθεί ότι είναι η βέλτιστη αντιστοίχιση μη κανονικής έκφρασης. Αυτό μπορεί να χειριστεί αιτήματα για το /costumes/ninja.html:

Nginx Server and Location Block Selection Algorithms: Overview

Για να γίνουμε πιο ακριβείς, οι τροποποιητές καθορίζουν τον τρόπο με τον οποίο προσδιορίζονται τα location blocks. Αυτό, ωστόσο, δεν μας λέει τι χρησιμοποιεί ο Nginx ως αλγόριθμο λήψης αποφάσεων για να αναγνωρίσει το location block στο οποίο πρέπει να σταλεί ένα αίτημα. Ας το εξετάσουμε αυτό στη συνέχεια.

Επιλογή της Τοποθεσίας (Location) που θα Χειρίζεται τα Αιτήματα από τον Nginx

Η μέθοδος με την οποία το Nginx επιλέγει την τοποθεσία (location) που επεξεργάζεται ένα αίτημα είναι παρόμοια με τον τρόπο επιλογής των server blocks. Με άλλα λόγια, καθορίζει τη βέλτιστη τοποθεσία για κάθε αίτημα εκτελώντας μια διαδικασία. Για να ρυθμίσετε το Nginx με ακρίβεια και αναλόγως, είναι επιτακτική ανάγκη να κατανοήσετε αυτήν τη διαδικασία.

Έχοντας υπόψη τις δηλώσεις location που αναφέρθηκαν προηγουμένως, το Nginx χρησιμοποιεί παρομοίως πιθανά location contexts ελέγχοντας την καταλληλότητα για κάθε location συγκρίνοντας με αυτό το URI από ένα δεδομένο αίτημα. Σε αυτό, εφαρμόζει τον ακόλουθο αλγόριθμο:

  • Πρώτον, το Nginx ελέγχει όλους τους τύπους location που δεν περιλαμβάνουν κανονική έκφραση (regular expression). Το κάνει αυτό αναζητώντας όλες τις αντιστοιχίσεις προθέματος (prefix matches) που βασίζονται σε location. Για να το κάνει αυτό, ελέγχει το location σε σχέση με το πλήρες URI του αιτήματος.
  • Το Nginx ξεκινά αναζητώντας μια ακριβή αντιστοίχιση. Μόλις εντοπιστεί ένα location block που χρησιμοποιεί τον τροποποιητή =, συγκρίνεται με το URI του αιτήματος. Εάν τα δύο ταιριάζουν ακριβώς, το location block επιλέγεται για να χειριστεί το αίτημα επί τόπου.
  • Εάν δεν υπάρχουν locations που να ταιριάζουν ακριβώς με τη σύγκριση του τροποποιητή =, το Nginx προχωρά στην αξιολόγηση προθεμάτων που δεν είναι ακριβή. Μόλις προσδιορίσει το location με το μεγαλύτερο πρόθεμα (longest prefix location) που ταιριάζει με το URI του αιτήματος, θα εκτελέσει τις ακόλουθες αξιολογήσεις:
    • Εάν το location με την αντιστοίχιση του μεγαλύτερου προθέματος χρησιμοποιεί τον τροποποιητή ^~, αυτό το location θα επιλεγεί αμέσως.
    • Εάν το location με το μεγαλύτερο πρόθεμα δεν χρησιμοποιεί τον τροποποιητή ^~, η αντιστοίχιση διατηρείται προσωρινά από το Nginx για να επιτραπεί η μετατόπιση της εστίασης της αναζήτησης.
  • Μόλις βρεθεί και αποθηκευτεί η αντιστοίχιση location με το μεγαλύτερο πρόθεμα, το Nginx μεταβαίνει στην αξιολόγηση των locations με κανονικές εκφράσεις (regular expressions). Αυτά περιλαμβάνουν αντιστοιχίσεις με διάκριση και χωρίς διάκριση πεζών-κεφαλαίων. Εάν το location με το μεγαλύτερο πρόθεμα αντιστοίχισης έχει οποιεσδήποτε κανονικές εκφράσεις μέσα του, το Nginx θα αναδιαμορφώσει τη λίστα για να τις τοποθετήσει κοντά στην κορυφή της λίστας των locations. Η πρώτη έκφραση από την αναδιαταγμένη λίστα που ταιριάζει με το URI ενός αιτήματος, θα είναι το location που θα επιλεγεί για την εξυπηρέτηση του αιτήματος.
  • Εάν δεν βρεθούν κανονικές εκφράσεις που να ικανοποιούν το RI του αιτήματος, το location που αποθηκεύτηκε προηγουμένως θα επιλεγεί για την επεξεργασία του αιτήματος.

Το Nginx δίνει προτεραιότητα στις αντιστοιχίσεις κανονικών εκφράσεων έναντι αυτών με προτιμησιακό πρόθεμα από προεπιλογή. Ωστόσο, αξιολογεί πρώτα τα prefix locations, έτσι ώστε ο διαχειριστής να μπορεί να παρακάμψει αυτήν την τάση με τους τροποποιητές = και ^~.

Ένα άλλο σημαντικό συμπέρασμα είναι ότι ενώ τα prefix locations βασίζονται συνήθως στην πιο συγκεκριμένη, μεγαλύτερη αντιστοίχιση που βρέθηκε, ο έλεγχος κανονικών εκφράσεων σταματά μόλις εντοπιστεί η πρώτη αντιστοίχιση. Αυτό σημαίνει ότι η τοποθέτηση εντός των ρυθμίσεων (configuration) έχει πραγματικές συνέπειες για τα locations με κανονικές εκφράσεις.

Ένα τελευταίο σημείο που πρέπει να αναφερθεί είναι ότι οι αντιστοιχίσεις κανονικών εκφράσεων εντός της αντιστοίχισης με το μεγαλύτερο πρόθεμα θα παρακάμψουν ουσιαστικά τη σειρά κατά τις αξιολογήσεις location του Nginx. Αυτές θα τοποθετηθούν στην κορυφή της λίστας και θα αξιολογηθούν πριν από άλλες κανονικές εκφράσεις.

Πότε συμβαίνει η μετάβαση σε άλλα Locations κατά τις αξιολογήσεις των Location Blocks;

Συνήθως, μόλις ένα αίτημα αξιολογηθεί και επιλεγεί ένα location block για το χειρισμό του, θα αντιμετωπιστεί εξ ολοκλήρου εντός αυτού του πλαισίου. Αυτό σημαίνει ότι μόνο οι κληρονομούμενες οδηγίες (directives) και τα επιλεγμένα locations καθορίζουν την επεξεργασία του αιτήματος, χωρίς καμία παρέμβαση από αδελφικά (sibling) location blocks.

Αν και αυτή είναι μια γενική οδηγία που επιτρέπει τον προβλέψιμο σχεδιασμό των location blocks, μερικές φορές ορισμένες οδηγίες (directives) εντός του location μπορούν επίσης να προκαλέσουν μια νέα αναζήτηση. Με άλλα λόγια, ο κανόνας «μόνο ένα location block» έχει μερικές εξαιρέσεις. Αυτές οι εξαιρέσεις ενδέχεται να μην ευθυγραμμίζονται με τις προσδοκίες των location blocks. Επομένως, ενδέχεται να μην αντιμετωπίσουν το αίτημα όπως αναμένεται.

Αυτές οι εσωτερικές ανακατευθύνσεις (internal redirects) μπορεί τελικά να εκδηλωθούν λόγω ορισμένων οδηγιών, συμπεριλαμβανομένων των:

  • index
  • rewrite
  • error_page
  • try_files

Αν χρησιμοποιήσετε την οδηγία index, αυτό θα έχει πάντα ως αποτέλεσμα μια εσωτερική ανακατεύθυνση κατά τη διάρκεια του χειρισμού του αιτήματος. Ενώ η εύρεση αντιστοιχιών location συνήθως τερματίζει την εκτέλεση του αλγορίθμου για να επιταχυνθεί η διαδικασία επιλογής, εάν η αντιστοιχία location που βρέθηκε είναι κατάλογος, το αίτημα πιθανότατα θα ανακατευθυνθεί σε άλλη τοποθεσία για να υποβληθεί σε επίσημη επεξεργασία.

Για παράδειγμα, το ακόλουθο πρώτο location ταιριάζει με ένα URI αιτήματος /exact. Ωστόσο, για την επεξεργασία του αιτήματος, η οδηγία index που κληρονομεί το location block ανακατευθύνει το αίτημα σε ένα δευτερεύον block:

index

Για αυτό το σενάριο, εάν η εκτέλεση πρέπει να παραμείνει εντός του πρωτεύοντος block, ένα άλλο σχήμα θα πρέπει να επεξεργαστεί το αίτημα προς τον κατάλογο. Ένας τρόπος για να γίνει αυτό είναι να ορίσετε ένα μη έγκυρο index για το εν λόγω block και να ενεργοποιήσετε αντ' αυτού το auto index:

location exact

Αν και αυτή η μέθοδος μπορεί να λειτουργήσει σε λίγες περιπτώσεις, σε γενικές γραμμές δεν είναι πρακτικά εφαρμόσιμη στα περισσότερα πλαίσια. Μια ακριβής αντιστοίχιση καταλόγου μπορεί να είναι χρήσιμη για καταστάσεις όπου το αίτημα πρέπει να ξαναγραφτεί. Αυτό θα ενεργοποιήσει μια ολοκαίνουργια αναζήτηση location.

Μια άλλη οδηγία που μπορεί να χρησιμοποιηθεί για την επαναξιολόγηση της τοποθεσίας επεξεργασίας είναι η οδηγία try_files. Λέει στο Nginx να ελέγξει συγκεκριμένα εάν υπάρχει ένα καθορισμένο σύνολο αρχείων ή καταλόγων, με το τελευταίο κριτήριο αναζήτησης να είναι το URI στο οποίο θα ανακατευθύνει εσωτερικά το Nginx.

Ας σκεφτούμε την ακόλουθη διαμόρφωση:

root var

Εάν υπάρχει ένα αίτημα για /blahblah, το πρώτο location θα το λάβει. Η μη εύρεση του αρχείου blahblah στον κατάλογο /var/www/main θα ενεργοποιήσει μια επακόλουθη αναζήτηση για blahblah.html. Στη συνέχεια, θα αναζητήσει έναν υποκατάλογο με το όνομα blahblah στον κατάλογο /var/www/main. Εάν όλοι αυτοί οι έλεγχοι αποτύχουν, θα ανακατευθύνει στο /fallback/index.html. Αυτό θα ενεργοποιήσει μια άλλη αναζήτηση location την οποία θα αναλάβει ένα άλλο location block. Στη συνέχεια, θα επεξεργαστεί το αρχείο /var/www/another/fallback/index.html.

Μια άλλη οδηγία που οδηγεί σε ανακατεύθυνση σε άλλο location block είναι η οδηγία rewrite. Το Nginx θα αναζητήσει ένα νέο location που ταιριάζει με βάση το αποτέλεσμα της οδηγίας rewrite όταν χρησιμοποιείται η παράμετρος last. Εάν το τελευταίο παράδειγμα τροποποιηθεί ώστε να περιλαμβάνει τώρα αυτήν την οδηγία rewrite, γίνεται προφανές ότι το αίτημα μπορεί να ανακατευθυνθεί σε άλλη τοποθεσία χωρίς να εφαρμοστεί η οδηγία try_files:

root var ww main

Για αυτό το παράδειγμα, το αίτημα για /rewrite/hello θα αντιμετωπιστεί αρχικά από το πρώτο location. Αφού ξαναγραφτεί σε /hello, θα ενεργοποιηθεί μια δευτερεύουσα αναζήτηση location. Θα ταιριάξει με το πρώτο location. Θα υποβληθεί σε επεξεργασία από την οδηγία try_file, επιστρέφοντας ενδεχομένως στο /fallback/index.html εάν δεν αποφέρει αποτελέσματα.

Εάν υποβληθεί αίτημα για /rewrite/fallback/hello, ωστόσο, θα βρεθεί μια αντιστοιχία με το πρώτο block. Έτσι, το rewrite θα υποβληθεί ξανά σε επεξεργασία, αλλά αυτή τη φορά θα αποφέρει το /fallback/hello ως αποτέλεσμα. Το αίτημα θα υποβληθεί σε επεξεργασία σε ένα άλλο location block.

Παρόμοιες καταστάσεις συμβαίνουν όταν χρησιμοποιείτε την οδηγία return για να στείλετε κωδικούς κατάστασης 301 ή 302. Η μόνη διαφορά είναι ότι προκύπτει ένα νέο αίτημα και εκδηλώνεται με μια πολύ προφανή ανακατεύθυνση. Ομοίως, αυτό μπορεί να συμβεί με την οδηγία rewrite όταν εφαρμόζετε σημαίες permanent ή redirect.

Μια άλλη οδηγία που μπορεί να οδηγήσει σε παρόμοιες εσωτερικές ανακατευθύνσεις με αυτήν του try_again είναι η οδηγία error_page. Μπορείτε να τη χρησιμοποιήσετε όταν αντιμετωπίζετε συγκεκριμένους κωδικούς σφάλματος κατά την επεξεργασία. Όταν έχει οριστεί μια οδηγία try_files, η οδηγία error_page πιθανότατα δεν θα εκτελεστεί ποτέ. Αυτό συμβαίνει επειδή αυτή η οδηγία θα χειριστεί τον πλήρη κύκλο ζωής του αιτήματος.

Ας εξετάσουμε το ακόλουθο παράδειγμα:

root screenshot

Σε αυτήν την περίπτωση, κάθε αίτημα θα υποβάλλεται σε επεξεργασία από το πρώτο block που εξυπηρετεί αρχεία από το /var/www/main. Αυτό δεν ισχύει για εκείνα τα αιτήματα που ξεκινούν με /another. Αλλά εάν ένα αρχείο δεν βρεθεί, θα ξεκινήσει μια εσωτερική ανακατεύθυνση προς το /another/whoops/html. Αυτό θα οδηγήσει σε μια άλλη αναζήτηση location. Με τη σειρά του, θα κατευθύνει το αίτημα σε ένα δευτερεύον block, με το εν λόγω αρχείο να εξυπηρετείται από το /var/www/another/whoops.html.

Όπως είναι προφανές, η κατανόηση των περιπτώσεων όπου ο Nginx θα ενεργοποιήσει μια νέα αναζήτηση location μπορεί να βοηθήσει στην καλύτερη πρόβλεψη της συμπεριφοράς του συστήματος κατά την επεξεργασία των αιτημάτων.

Συμπέρασμα

Η δουλειά των διαχειριστών γίνεται εξαιρετικά απλούστερη όταν κατανοούν τις μεθόδους με τις οποίες ο Nginx διαχειρίζεται τα αιτήματα των πελατών. Αυτό επιτρέπει στους διαχειριστές να εξακριβώσουν σε ποιο server block θα κατευθυνθεί το αίτημα. Μπορούν επίσης να προσδιορίσουν το location block που θα επιλεγεί με βάση το URI του αιτήματος. Σε γενικές γραμμές, παρέχει επίσης στους διαχειριστές τη δυνατότητα να εντοπίζουν τα πλαίσια (contexts) που εφαρμόζει ο Nginx κατά τη διαχείριση κάθε αιτήματος.

Τέλος, μπορείτε να ρίξετε μια ματιά στα άλλα σεμινάρια στο blog μας που εστιάζουν στον Nginx. Θα σας βοηθήσουν να επωφεληθείτε καλύτερα από έναν από τους πιο δημοφιλείς web servers στον κόσμο:

Καλή υπολογιστική!

author

Manpreet Singh

Συγγραφέας · CloudSigma

Ο Preslav Dobrev είναι Δημιουργικός Σχεδιαστής στην CloudSigma, με εστίαση στη συνεπή επιχειρηματική ταυτότητα μέσω παραδοσιακών και καινοτόμων καναλιών μάρκετινγκ. Διαθέτει την ικανότητα να συνδυάζει το καλλιτεχνικό όραμα με το στρατηγικό μάρκετινγκ για τη δημιουργία εντυπωσιακών αφηγήσεων επωνυμίας.

Σχόλια

Δεν υπάρχουν σχόλια ακόμα. Γράψτε το πρώτο.