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

Υλοποίηση Περιορισμού Ρυθμού PHP με τη χρήση του Redis σε Ubuntu 20.04: Ένας Οδηγός

Υλοποίηση Περιορισμού Ρυθμού PHP με τη χρήση του Redis σε Ubuntu 20.04: Ένας Οδηγός

Redis, επίσης γνωστό και ως Remote Dictionary Server, είναι μια βάση δεδομένων ανοιχτού κώδικα στη μνήμη (in-memory). Είναι ένα σύστημα αποθήκευσης δομημένων δεδομένων που εκτελείται στη μνήμη RAM ενός διακομιστή, η οποία είναι πολύ ταχύτερη από τον ταχύτερο δίσκο Solid State Drive (SSD). Ως αποτέλεσμα, το Redis ανταποκρίνεται εξαιρετικά γρήγορα και είναι ιδανικό για περιορισμό ρυθμού (rate limiting).

Ο περιορισμός ρυθμού (Rate limiting) περιορίζει τον αριθμό των φορών που ένας χρήστης μπορεί να ζητήσει έναν πόρο από έναν διακομιστή. Πολλές υπηρεσίες χρησιμοποιούν όρια ρυθμού για να σταματήσουν την κατάχρηση υπηρεσιών, όπως όταν ένας χρήστης προσπαθεί να υπερφορτώσει έναν διακομιστή με υπερβολικό φορτίο. Για παράδειγμα, όταν χρησιμοποιείτε PHP για την ανάπτυξη ενός δημόσιου API (Application Programming Interface) για την εφαρμογή ιστού σας, απαιτούνται περιορισμοί ρυθμού. Αυτό συμβαίνει επειδή όταν εκθέτετε ένα API στο κοινό, θα θέλετε να περιορίσετε πόσες φορές ένα άτομο μπορεί να επαναλάβει μια δραστηριότητα σε ένα συγκεκριμένο χρονικό διάστημα. Χρήστες που δεν έχουν εξουσιοδότηση στο σύστημά σας ενδέχεται να το οδηγήσουν σε αδράνεια.

Ο περιορισμός ρυθμού επιτρέπει στην εφαρμογή σας να λειτουργεί ομαλά, απορρίπτοντας αιτήματα χρηστών που υπερβαίνουν ένα καθορισμένο όριο. Εάν έχετε μεγάλο αριθμό πελατών, ο περιορισμός ρυθμού επιβάλλει μια πολιτική δίκαιης χρήσης που επιτρέπει σε κάθε χρήστη να έχει πρόσβαση στην εφαρμογή σας με υψηλές ταχύτητες. Ο περιορισμός ρυθμού μπορεί επίσης να σας βοηθήσει να εξοικονομήσετε χρήματα από το εύρος ζώνης (bandwidth) μειώνοντας τη συμφόρηση στον διακομιστή σας.

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

Το Redis είναι μια καλή επιλογή για τη δημιουργία ενός περιοριστή ρυθμού (rate limiter) επειδή λειτουργεί ως βάση δεδομένων στη μνήμη και έχει αποδειχθεί αξιόπιστο για αυτό. Σε αυτόν τον οδηγό, θα σας καθοδηγήσουμε στα βήματα για την υλοποίηση περιορισμού ρυθμού PHP χρησιμοποιώντας το Redis σε Ubuntu 20.04.

Ας ξεκινήσουμε!

Προαπαιτούμενα

Για να παρακολουθήσετε αυτόν τον οδηγό, θα χρειαστείτε τα εξής:

Βήμα 1: Εγκατάσταση της επέκτασης Redis για την PHP

Πριν ξεκινήσουμε, ας ενημερώσουμε τα αποθετήρια για να αποφύγουμε διενέξεις πακέτων:

Στη συνέχεια, εγκαταστήστε την επέκταση php-redis, ένα πακέτο που καθιστά δυνατή τη χρήση του Redis σε προγράμματα PHP. Εκτελέστε την ακόλουθη εντολή sudo για να εγκαταστήσετε το php-redis:

Μετά από αυτό, επανεκκινήστε τον διακομιστή Apache για να φορτώσετε τη βιβλιοθήκη php-redis:

Το επόμενο βήμα είναι να ενημερώσετε τις πληροφορίες στο ευρετήριο λογισμικού σας και να εγκαταστήσετε τη βιβλιοθήκη Redis για την PHP. Στη συνέχεια, θα δημιουργήσουμε έναν πόρο PHP που περιορίζει την πρόσβαση με βάση τη διεύθυνση IP ενός χρήστη.

Βήμα 2: Δημιουργία ενός πόρου ιστού PHP για περιορισμό ρυθμού

Σε αυτό το βήμα, θα δημιουργήσετε ένα αρχείο demo.php στον ριζικό κατάλογο του διακομιστή ιστού σας ( /var/www/html/). Αυτό το αρχείο θα είναι ανοιχτό στο κοινό και οι χρήστες θα μπορούν να ανοίξουν τη διεύθυνση URL στο πρόγραμμα περιήγησης ιστού της προτίμησής τους. Αργότερα, θα χρησιμοποιήσουμε την εντολή curl για να επαληθεύσουμε την προσβασιμότητα του πόρου που θέλουμε να χρησιμοποιήσουμε. Οι χρήστες μπορούν να έχουν πρόσβαση στο δείγμα αρχείου πόρου τρεις φορές σε διάστημα 15 δευτερολέπτων. Μια προσπάθεια που υπερβαίνει το μέγιστο όριο θα εμφανίσει ένα μήνυμα σφάλματος.

Η κύρια λειτουργικότητα αυτού του αρχείου εξαρτάται σε μεγάλο βαθμό από τον διακομιστή Redis. Ο κώδικας PHP στο αρχείο δημιουργεί ένα κλειδί στον διακομιστή Redis ανάλογα με τη διεύθυνση IP του χρήστη όταν ο χρήστης αποκτά πρόσβαση στον πόρο για πρώτη φορά. Ο κώδικας θα προσπαθήσει να αντιστοιχίσει τη διεύθυνση IP του χρήστη με τα κλειδιά που είναι αποθηκευμένα στον διακομιστή Redis και να αυξήσει την τιμή κατά ένα εάν το κλειδί υπάρχει όταν ο χρήστης επιστρέψει στον πόρο. Ο κώδικας PHP θα συνεχίσει να ελέγχει για να δει αν η νέα τιμή έχει φτάσει στο μέγιστο όριο.

Μετά από 15 δευτερόλεπτα, το κλειδί Redis, το οποίο βασίζεται στη διεύθυνση IP του χρήστη, θα λήξει και η παρακολούθηση των επισκέψεων του χρήστη στον πόρο ιστού θα ξεκινήσει ξανά. Ανοίξτε το /var/www/html/demo.php αρχείο στον nano επεξεργαστή κειμένου:

Στη συνέχεια, συμπληρώστε όλα τα πεδία για να αρχικοποιήσετε την κλάση Redis. Μην ξεχάσετε να ορίσετε το REDIS_PASSWORD στη σωστή τιμή:

Redis->auth υποστηρίζει έλεγχο ταυτότητας απλού κειμένου διακομιστή Redis. Αυτό λειτουργεί καλά εάν εργάζεστε τοπικά (μέσω localhost), αλλά εάν αντιμετωπίζετε έναν απομακρυσμένο διακομιστή Redis, έλεγχος ταυτότητας SSL συνιστάται.

Στη συνέχεια, στο ίδιο αρχείο, ορίστε τις ακόλουθες μεταβλητές στις προεπιλεγμένες τιμές τους:

Ας κατανοήσουμε αυτές τις δηλώσεις λεπτομερώς:

  • $max_calls_limit: Ένας χρήστης δεν μπορεί να έχει πρόσβαση στον πόρο πέρα από αυτό το μέγιστο όριο κλήσεων.

  • $time_period: Αυτό χρησιμοποιείται ως χρονικό πλαίσιο και μετριέται σε δευτερόλεπτα. Εδώ, ο χρήστης επιτρέπεται να έχει πρόσβαση στον πόρο σύμφωνα με τα όρια που έχουν οριστεί στο $max_calls_limit .

  • $total_user_calls: Αθροίζει τον αριθμό των φορών που ένας χρήστης έχει ζητήσει πρόσβαση στο όριο κλήσεων σε μια δεδομένη χρονική περίοδο.

Στη συνέχεια, προσθέστε τον ακόλουθο κώδικα για να λάβετε τη διεύθυνση IP του αιτούντος που ζητά πρόσβαση στην ιστοσελίδα:

Ως επίδειξη, αυτός ο κώδικας καταγράφει τις ενέργειες των χρηστών με βάση τις διευθύνσεις IP τους. Εάν έχετε έναν προστατευμένο πόρο στον διακομιστή που απαιτεί έλεγχο ταυτότητας, μπορείτε να παρακολουθείτε τις ενέργειες των χρηστών χρησιμοποιώντας τα ονόματα χρηστών ή τα διακριτικά πρόσβασής τους (access tokens).

Στον οδηγό μας, σε κάθε χρήστη που συνδέεται στο σύστημά σας θα εκχωρείται ένα μοναδικό αναγνωριστικό (για παράδειγμα, ένα ID πελάτη, ID προγραμματιστή, ID προμηθευτή ή ακόμα και ένα ID χρήστη). Θυμηθείτε να χρησιμοποιήσετε αυτά τα ID αντί για τη $user_ip διεύθυνση εάν ακολουθείτε το σεμινάριό μας.

Εδώ, η διεύθυνση IP του χρήστη είναι επαρκής για να καταδείξει την έννοια. Προσθέστε το ακόλουθο μπλοκ κώδικα στο αρχείο σας μόλις λάβετε τη διεύθυνση IP του χρήστη από το προηγούμενο απόσπασμα κώδικα:

Ακολουθεί μια επισκόπηση αυτών των δηλώσεων:

  • if...else: Η δήλωση επαληθεύει εάν υπάρχει ένα κλειδί ορισμένο με τη διεύθυνση IP στον διακομιστή Redis.

    • Εάν το κλειδί δεν βρεθεί, if (!$redis->exists($user_ip_address)) {...}, μπορείτε να ορίσετε το κλειδί και να καθορίσετε την τιμή του σε 1 χρησιμοποιώντας $redis->set($user_ip_address, 1).

  • $redis->expire($user_ip_address, $time_period): Υπενθυμίζει στο κλειδί να λήξει σε μια καθορισμένη ώρα. Εδώ σε αυτόν τον οδηγό, το έχουμε ορίσει σε 15 δευτερόλεπτα.

  • Εάν η διεύθυνση IP του χρήστη δεν βρεθεί στο κλειδί Redis, ορίστε τη μεταβλητή $total_user_calls τιμή ως 1.

  • else {...}: Το μπλοκ δηλώσεων χρησιμοποιεί την $redis->INCR($user_ip_address); εντολή για να αυξήσει την τιμή του κλειδιού Redis κατά 1. Αυτό θα εφαρμοστεί σε κάθε διεύθυνση IP που ευθυγραμμίζεται με το κλειδί.

    • Σημείωση: Μπορείτε να το επιτύχετε αυτό μόνο όταν το κλειδί είναι ήδη ορισμένο στον διακομιστή Redis και προσμετράται ως επαναλαμβανόμενο αίτημα.

  • $total_user_calls = $redis->get($user_ip_address): Αυτή η δήλωση ανακτά τα συνολικά αιτήματα επαληθεύοντας το αντίστοιχο κλειδί τους που βασίζεται στη διεύθυνση IP στον διακομιστή Redis.

  • if ($total_user_calls > $max_calls_limit) {... }..: Αυτή η if δήλωση χρησιμοποιείται για την επαλήθευση της υπέρβασης του ορίου. Εάν ναι, ειδοποιείτε τον χρήστη με echo "Χρήστης" . $user_ip_address . " το όριο ξεπεράστηκε.";.

Τέλος, ειδοποιείτε τον χρήστη για τον αριθμό των επισκέψεών του σε μια καθορισμένη περίοδο χρησιμοποιώντας τη echo "Καλώς ορίσατε" . $user_ip_address . "συνολικές κλήσεις που πραγματοποιήθηκαν" . $total_user_calls . "σε" . $time_period . "δευτερόλεπτα"; δήλωση.

Μετά από αυτό, προσθέστε τις ακόλουθες γραμμές κώδικα στο αρχείο σας /var/www/html/demo.php αρχείο:

Αποθηκεύστε και κλείστε το αρχείο /var/www/html/demo.php αφού ολοκληρώσετε την τροποποίησή του. Στην demo.php ιστοσελίδα, έχετε πλέον δημιουργήσει τη λογική που απαιτείται για τον περιορισμό του ρυθμού των χρηστών. Ας δοκιμάσουμε το σενάριό μας στο επόμενο βήμα.

Βήμα 3: Εκτέλεση της δοκιμής περιορισμού ρυθμού Redis

Θα χρησιμοποιήσετε την εντολή curl σε αυτό το βήμα για να ζητήσετε τον πόρο ιστού που γράψατε στο Βήμα 2. Για να δοκιμάσετε διεξοδικά το σενάριο, εκδώστε μια ενιαία εντολή που ζητά τον πόρο πέντε φορές. Αυτό μπορεί να επιτευχθεί προσθέτοντας ένα όρισμα URL placeholder στο demo.php τέλος του αρχείου. Για να εκτελέσετε τις curl οδηγίες πέντε φορές, χρησιμοποιήστε την τιμή ?[1-5] στο τέλος του αιτήματός σας.

Εκτελέστε την ακόλουθη curl εντολή παρακάτω:

Όταν εκτελέσετε τον κώδικα, θα πρέπει να λάβετε κάτι σαν αυτό:

Τα πρώτα τρία αιτήματα, όπως μπορείτε να δείτε, ολοκληρώθηκαν χωρίς κανένα πρόβλημα. Τα ερωτήματα τέσσερα και πέντε, ωστόσο, περιορίστηκαν από το σενάριο κώδικά σας. Υπάρχει μεγάλη πιθανότητα ο διακομιστής Redis να επιβραδύνει την ταχύτητα με την οποία οι χρήστες μπορούν να υποβάλλουν ερωτήματα.

Έχετε ορίσει χαμηλές τιμές για τις δύο μεταβλητές που αναφέρονται παρακάτω σε αυτόν τον οδηγό:

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

Είναι καλή ιδέα να εξετάσετε τα στατιστικά στοιχεία σε πραγματικό χρόνο προτού προσαρμόσετε αυτούς τους αριθμούς. Σε αυτό το παράδειγμα, εάν τα αρχεία καταγραφής του διακομιστή σας δείχνουν ότι ένας μέσος χρήστης επισκέπτεται την εφαρμογή σας 1.000 φορές κάθε 60 δευτερόλεπτα, μπορείτε να χρησιμοποιήσετε αυτόν τον αριθμό ως παράδειγμα για το πόσο περιορισμό θα χρησιμοποιήσετε.

Συμπέρασμα

Σε αυτόν τον οδηγό, μάθατε πώς να χρησιμοποιείτε έναν διακομιστή Redis με PHP στο Ubuntu 20.04. Αν και αυτή η ανάρτηση δείχνει πώς λειτουργεί ο περιορισμός ρυθμού με το Redis, μπορείτε να τον προσαρμόσετε ώστε να ανταποκρίνεται στις απαιτήσεις της διαδικτυακής σας εφαρμογής. Σας ενθαρρύνουμε να εξερευνήσετε παραδείγματα από τον πραγματικό κόσμο όπως το μέγιστο όριο αιτημάτων του Twitter, το Custom Search JSON API της Google, και άλλη παρόμοια τεκμηρίωση για να βελτιώσετε τις γνώσεις σας σχετικά με τον περιορισμό ρυθμού και να πειραματιστείτε μόνοι σας χρησιμοποιώντας διαφορετικά χρονικά όρια.

Επιπλέον, υπάρχουν πολλά άλλα υλικά εκμάθησης για το Redis και την PHP στα οποία μπορείτε να έχετε πρόσβαση από τα ιστολόγιά μας:

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

author

Shreyas Patil

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

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

Σχόλια

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