推奨: 「PHP ビデオ チュートリアル 」
日常のビジネス機能開発で、特定の期間内のみにアクセスするように IP を制限したい場合の実装方法特定のインターフェイスを特定の回数?
この機能要件は通常、スクリプトが悪意を持ってインターフェイスをブラッシングするのを防ぐために使用されます。現在、インターネット上には比較的完全な電流制限ソリューションが多数あります。一般的なサイトの場合、redisのリンクリストデータ構造を利用してIP電流制限機能を実装できます。
たとえば、-
実装する必要がある場合、インターフェイス A に対して、連続 5 秒ごとに最大 3 回のアクセスを許可するように IP を制限し、3 回を超えるとエラーを返します。
上の図では、08 秒の時点で、過去 5 秒間に 4 つのリクエストが開始され、最大数制限に達しているため、この時点でアクセスが制限されます。
PHP で実装されている場合、具体的なロジック コードは次のとおりです -
/** * 检查队列的长度是否到达设定的阈值,已到达则返回false,未到达则将当前时间戳推入队列最末端,同时刷新队列整体的缓存时间 * @param $key 队列缓存的key * @param $expire 队列缓存过期时间,例如上面例子中的5秒 * @param $limit 队列长度阈值,如上面例子中的3次 * @return bool */public function checkLimit($key, $expire, $limit){ $length = $this->refreshList($key, $expire); if ($length rPush($key, time()); $this->expire($key, intval($limit)); return true; } return false;}/** * 刷新队列,过滤掉已经不在有效时间内的值,返回最新队列的长度 * @param $key string 自定义的缓存key * @param $expire 队列缓存过期时间,例如上面例子中的5秒 * @return bool|int */public function refreshList ($key, $expire) { if ($this->has($key)) { do { // 对于已存在数据的list,要先从前往后把已经过期的数据弹出 $oldest_value = $this->lPop($key); } while ($oldest_value && time() - $oldest_value > $expire); // 把最后弹出的数据重新塞回list的最前边 $oldest_value && $this->lPush($key, $oldest_value); return $this->lLen($key); } return 0;}
使用される lPop、lPush、lLen、rPush およびその他のメソッドはすべて、redis 拡張後にカプセル化されます。リンク リストのデータ構造、パラメータ、戻り値の操作はネイティブ メソッドと一致します。
実際、後でオンラインで確認したところ、Redis は zset のような順序付きセットを使用することで、このシナリオをより直接的に処理することがわかりました。ロジックは基本的に同じです。つまり、現在のタイムスタンプを保存し、スライディング ウィンドウ アルゴリズムを使用します。目的は、現在のウィンドウ内の値の長さが制限を超えているかどうかを判断することです。
以上がIP電流制限操作を実装するためのredisベースのPHPのリスト型データ構造の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。