Redis, más néven Remote Dictionary Server, egy nyílt forráskódú, memóriában működő adatbázis. Ez egy olyan adatszerkezet-alapú tárolórendszer, amely a szerver RAM-jában fut, ami sokkal gyorsabb, mint a leggyorsabb Solid State Drive (SSD). Ennek eredményeként a Redis rendkívül gyors válaszidővel rendelkezik, és kiválóan alkalmas a sebességkorlátozásra.
A sebességkorlátozás korlátozza, hogy egy felhasználó hányszor kérhet le egy erőforrást a szerverről. Számos szolgáltatás használ sebességkorlátokat a szolgáltatással való visszaélések megakadályozására, például amikor egy felhasználó túl nagy terheléssel próbálja túlterhelni a szervert. Például, amikor PHP-t használ egy nyilvános API (alkalmazásprogramozási felület) fejlesztésére a webalkalmazásához, sebességkorlátozásokra van szükség. Ez azért van, mert amikor nyilvánossá tesz egy API-t, korlátozni szeretné, hogy egy egyén hányszor ismételhet meg egy tevékenységet egy bizonyos időn belül. Azok a felhasználók, akiknek nincs jogosultságuk a rendszer felett, teljesen megbéníthatják azt.
A sebességkorlátozás lehetővé teszi az alkalmazás zökkenőmentes működését azáltal, hogy elutasítja a beállított korlátot meghaladó felhasználói kéréseket. Ha nagyszámú ügyféllel rendelkezik, a sebességkorlátozás méltányos használati szabályzatot (fair-use policy) vezet be, amely lehetővé teszi, hogy minden felhasználó gyorsan hozzáférjen az alkalmazáshoz. A sebességkorlátozás abban is segíthet, hogy pénzt takarítson meg a sávszélességen a szerver torlódásának csökkentésével.
A felhasználói tevékenységek nyomon követésével egy olyan adatbázisban, mint a MySQL, lehetséges lenne egy sebességkorlátozó program létrehozása. Mivel azonban az ilyen adatokat le kell tölteni a lemezről, és össze kell vetni a meghatározott korláttal, a végeredmény nem biztos, hogy skálázható lesz, ha egyszerre többen lépnek kapcsolatba a rendszerrel. Ez nemcsak nem hatékony, de a relációs adatbázis-kezelő megoldásokat nem is erre tervezték.
A Redis jó választás sebességkorlátozó készítéséhez, mivel memóriában működő adatbázisként működik, és már bizonyítottan megbízható erre a célra. Ebben az útmutatóban végigvezetjük a PHP sebességkorlátozás megvalósításának lépésein Redis használatával Ubuntu 20.04-en.
Kezdjük el!
Előfeltételek
Az útmutató követéséhez a következőkre lesz szüksége:
-
A legfrissebb telepített Ubuntu verzió a rendszerén.
-
A rendszerfelhasználóknak rendelkezniük kell sudo jogosultságokkal.
-
Egy LAMP szoftvercsomag (stack).
-
Ezt a Hogyan állítsuk be a LAMP szoftvercsomagot útmutatót követve állíthatja be.
-
-
Egy Redis szerver.
-
Kövesse a Hogyan telepítsük és biztosítsuk a Redis szervert útmutatót a Redis beállításához a rendszerében.
-
1. lépés: A Redis kiterjesztés telepítése PHP-hez
Mielőtt elkezdenénk, frissítsük a tárolókat a csomagkonfliktusok elkerülése érdekében:
|
1 |
sudo apt update |
Ezután telepítse a php-redis kiterjesztést, egy olyan csomagot, amely lehetővé teszi a Redis használatát PHP programokban. Futtassa a következő sudo parancsot a php-redis:
|
1 |
sudo apt install -y php-redis |
Ezt követően indítsa újra az Apache szervert a php-redis könyvtár betöltéséhez:
|
1 |
sudo systemctl restart apache2 |
A következő lépés a szoftverindex információinak frissítése és a PHP-hez készült Redis könyvtár telepítése. Ezután létrehozunk egy PHP erőforrást, amely a felhasználó IP-címe alapján korlátozza a hozzáférést.
2. lépés: PHP webes erőforrás létrehozása a sebességkorlátozáshoz
Ebben a lépésben létrehoz egy demo.php fájlt a webszerver gyökérkönyvtárában ( /var/www/html/). Ez a fájl nyilvános lesz, és a felhasználók megnyithatják az URL-t a preferált webböngészőjükben. Később a curl paranccsal ellenőrizzük a használni kívánt erőforrás elérhetőségét. A felhasználók 15 másodperces időtartamon belül háromszor férhetnek hozzá a minta erőforrásfájlhoz. A maximális korlátot meghaladó kísérlet hibaüzenetet fog eredményezni.
Ennek a fájlnak az elsődleges funkciója erősen függ a Redis szervertől. A fájlban található PHP kód létrehoz egy kulcsot a Redis szerveren a felhasználó IP-címe alapján, amikor a felhasználó először fér hozzá az erőforráshoz. A kód megpróbálja egyeztetni a felhasználó IP-címét a Redis szerveren mentett kulcsokkal, és eggyel növeli az értéket, ha a kulcs már létezik, amikor a felhasználó visszatér az erőforráshoz. A PHP kód folyamatosan ellenőrzi, hogy az új érték elérte-e a maximális mennyiséget.
15 másodperc elteltével a felhasználó IP-címén alapuló Redis kulcs lejár, és a felhasználó webes erőforrás-látogatásainak nyomon követése újra kezdődik. Nyissa meg a /var/www/html/demo.php fájlt a nano szövegszerkesztőben:
|
1 |
sudo nano /var/www/html/demo.php |
Ezután töltse ki az összes mezőt a Redis osztály inicializálásához. Ne felejtse el beállítani a REDIS_PASSWORD értéket a megfelelőre:
|
1 2 3 4 |
<?php $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis->auth('REDIS_PASSWORD'); |
Redis->auth támogatja a Redis szerver egyszerű szöveges hitelesítését. Ez jól működik, ha helyben dolgozik (localhoston keresztül), de ha távoli Redis szerverrel van dolga, SSL hitelesítés ajánlott.
Ezután ugyanabban a fájlban állítsa be a következő változókat az alapértelmezett értékeikre:
|
1 2 3 4 5 |
. . . $max_calls_limit = 3; $time_period = 15; $total_user_calls = 0; |
Ismerjük meg ezeket az utasításokat részletesen:
-
$max_calls_limit: A felhasználó nem férhet hozzá az erőforráshoz ezen a maximális hívási korláton túl.
-
$time_period: Ez időkeretként használatos, és másodpercben van megadva. Itt a felhasználó az alábbiakban beállított korlátok szerint férhet hozzá az erőforráshoz: $max_calls_limit .
-
$total_user_calls: Összegzi, hogy a felhasználó hányszor kért hozzáférést a hívások korláthoz egy adott időszakban.
Ezután adja hozzá a következő kódot a weboldal elérését kérő IP-címének lekéréséhez:
|
1 2 3 4 5 6 7 8 9 10 |
. . . if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $user_ip_address = $_SERVER['HTTP_CLIENT_IP']; } elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $user_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $user_ip_address = $_SERVER['REMOTE_ADDR']; } |
Szemléltetésképpen ez a kód a felhasználók tevékenységeit az IP-címük alapján naplózza. Ha a szerveren van olyan védett erőforrás, amely hitelesítést igényel, a felhasználók tevékenységeit a felhasználónevük vagy hozzáférési tokenjeik segítségével is nyomon követheti.
Útmutatónkban minden, a rendszerbe bejelentkező felhasználóhoz egy egyedi azonosító lesz hozzárendelve (például ügyfél-azonosító, fejlesztői azonosító, szállítói azonosító vagy akár felhasználói azonosító). Ne felejtse el ezeket az azonosítókat használni a $user_ip cím, ha követi a bemutatónkat.
Itt a felhasználó IP-címe elegendő az elv bemutatásához. Adja hozzá a következő kódblokkot a fájljához, miután megkapta a felhasználó IP-címét az előző kódrészletből:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
. . . if (!$redis->exists($user_ip_address)) { $redis->set($user_ip_address, 1); $redis->expire($user_ip_address, $time_period); $total_user_calls = 1; } else { $redis->INCR($user_ip_address); $total_user_calls = $redis->get($user_ip_address); if ($total_user_calls > $max_calls_limit) { echo "Felhasználó " . $user_ip_address . " korlát túllépve."; exit(); } } echo "Üdvözöljük " . $user_ip_address . " összes hívás száma " . $total_user_calls . " alatt " . $time_period . " seconds"; |
Íme egy áttekintés ezekről az utasításokról:
-
if...else: Az utasítás ellenőrzi, hogy van-e az IP-címmel definiált kulcs a Redis szerveren.
-
Ha a kulcs nem található, if (!$redis->exists($user_ip_address)) {...}, beállíthatja a kulcsot, és az értékét 1-re állíthatja a következővel: $redis->set($user_ip_address, 1).
-
-
$redis->expire($user_ip_address, $time_period): Beállítja a kulcs lejárati idejét egy meghatározott időpontra. Ebben az útmutatóban ezt a következőre állítottuk be: 15 másodperc.
-
Ha a felhasználó IP-címe nem található a Redis kulcsban, állítsa be a $total_user_calls értéket a következőként: 1.
-
else {...}: Az utasításblokk a $redis->INCR($user_ip_address); parancsot használja a Redis kulcs értékének növelésére a következővel: 1. Ez minden, a kulcshoz hozzárendelt IP-címre érvényes lesz.
-
Note: Ezt csak akkor érheti el, ha a kulcs már be van állítva a Redis szerveren, és ismétlődő kérésnek minősül.
-
-
$total_user_calls = $redis->get($user_ip_address): Ez az utasítás lekéri az összes kérést a megfelelő IP-cím alapú kulcs ellenőrzésével a Redis szerveren.
-
if ($total_user_calls > $max_calls_limit) {... }..: Ez az if utasítás a túllépett korlát ellenőrzésére szolgál. Ha igen, értesíti a felhasználót a következővel: echo "User" . $user_ip_address . " limit exceeded.";.
Végül értesíti a felhasználót a látogatásai számáról egy adott időszakban a következő echo "Welcome" . $user_ip_address . "total calls made" . $total_user_calls . "in" . $time_period . "seconds"; utasítással.
Ezután adja hozzá a következő kódsorokat a /var/www/html/demo.php fájlhoz:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis->auth('REDIS_PASSWORD'); $max_calls_limit = 3; $time_period = 15; $total_user_calls = 0; if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $user_ip_address = $_SERVER['HTTP_CLIENT_IP']; }elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $user_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $user_ip_address = $_SERVER['REMOTE_ADDR']; } if (!$redis->exists($user_ip_address)) { $redis->set($user_ip_address, 1); $redis->expire($user_ip_address, $time_period); $total_user_calls = 1; } else { $redis->INCR($user_ip_address); $total_user_calls = $redis->get($user_ip_address); if ($total_user_calls > $max_calls_limit) { echo "User " . $user_ip_address . " limit exceeded."; exit(); } } echo "Welcome " . $user_ip_address . " total calls made " . $total_user_calls . " in " . $time_period . " seconds"; ?> |
Mentse és zárja be a /var/www/html/demo.php fájlt, miután befejezte a módosítását. A demo.php weboldalon most létrehozta a felhasználók sebességkorlátozásához szükséges logikát. Teszteljük a szkriptünket a következő lépésben.
3. lépés: A Redis sebességkorlátozási teszt futtatása
Ebben a lépésben a curl parancsot fogja használni a 2. lépés szakaszban megírt webes erőforrás lekéréséhez. A szkript alapos teszteléséhez adjon ki egyetlen parancsot, amely ötször kéri le az erőforrást. Ez egy helyőrző URL-argumentum hozzáadásával érhető el a demo.php fájl végét. A curl utasítások ötszöri végrehajtásához használja a ?[1-5] értéket a kérése végén.
Hajtsa végre a következő curl parancsot alább:
|
1 |
curl -H "Accept: text/plain" -H "Content-Type: text/plain" -X GET http://localhost/demo.php?[1-5] |
A kód végrehajtásakor valami hasonlót kell kapnia:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[1/5]: http://localhost/demo.php?1 --> <stdout> --_curl_--http://localhost/demo.php?1 Welcome 127.0.0.1 total calls made 1 in 15 seconds [2/5]: http://localhost/demo.php?2 --> <stdout> --_curl_--http://localhost/demo.php?2 Welcome 127.0.0.1 total calls made 2 in 15 seconds [3/5]: http://localhost/demo.php?3 --> <stdout> --_curl_--http://localhost/demo.php?3 Welcome 127.0.0.1 total calls made 3 in 15 seconds [4/5]: http://localhost/demo.php?4 --> <stdout> --_curl_--http://localhost/demo.php?4 User 127.0.0.1 limit exceeded. [5/5]: http://localhost/demo.php?5 --> <stdout> --_curl_--http://localhost/demo.php?5 User 127.0.0.1 limit exceeded. |
Az első három kérés, amint látható, zökkenőmentesen lefutott. A negyedik és ötödik lekérdezést azonban a szkript korlátozta. Nagy a valószínűsége annak, hogy a Redis szerver lassítja a lekérdezések gyakoriságát.
Ebben az útmutatóban alacsony értékeket adott meg az alább felsorolt két változóhoz:
|
1 2 3 4 |
... $max_calls_limit = 3; $time_period = 15; ... |
Amikor az alkalmazást éles környezetben készíti el, érdemes lehet nagyobb számok használatát fontolóra venni, attól függően, hogy véleménye szerint milyen gyakran fogják használni.
Ezen számok módosítása előtt érdemes megvizsgálni a valós idejű statisztikákat. Ebben a példában, ha a szervernaplók azt mutatják, hogy egy átlagos felhasználó 60 másodpercenként 1000-szer látogatja meg az alkalmazást, ezt a számot használhatja példaként a korlátozás mértékére.
Összegzés
Ebben az útmutatóban megtanulta, hogyan használhatja a Redis szervert PHP-val Ubuntu 20.04-en. Bár ez a bejegyzés bemutatja, hogyan működik a sebességkorlátozás a Redis segítségével, testre szabhatja azt a webalkalmazása igényeinek megfelelően. Javasoljuk, hogy fedezzen fel olyan valós példákat, mint a Twitter maximális kéréskorlátja, Google Custom Search JSON API, és más hasonló dokumentációkat, hogy bővítse ismereteit a sebességkorlátozásról, és próbáljon meg kísérletezni különböző időkorlátokkal.
Emellett számos más tananyag is elérhető a Redisről és a PHP-ról a blogjainkon:
- PHP-alkalmazás telepítése Kubernetes fürtre Ubuntu 18.04 rendszeren
- A PHPmyadmin telepítése és biztosítása Ubuntu 20.04 rendszeren
- A LEMP szoftvercsomag (Linux Nginx MySQL PHP) telepítése Ubuntu 20.04 rendszeren
Kellemes kódolást!
Hozzászólások
Még nincsenek hozzászólások. Legyen Ön az első.