単一の IP または単一のユーザーが 1 分間に何回アクセスできるかなど、API またはページへのアクセス頻度を制限する必要がある場合があります。同様の要件は Redis を使用して簡単に達成できます。
戦略 1:
カウント値 (int) を Redis に保存します。キーは user:$ip で、値は回数ですip にアクセスしました。初めてキーを設定すると、設定の有効期限が切れます。
カウントに 1 を追加する前に、キーが存在するかどうかを確認します。キーが存在しない場合は、2 つの状況が考えられます: 1. IP にアクセスされていない; 2. IP にはアクセスされているが、キーが存在しない期限切れです。この時点で有効期限を再度設定する必要があります。
ユーザーがアクセスした場合、countの値が上限値より大きいかどうかを判定し、上限値より小さい場合はリクエストを処理し、そうでない場合はリクエストの処理を拒否します。
戦略 2:
ユーザーが 60 秒以内に 100 回のアクセスしか許可されていないと仮定して、この状況を考えてみましょう。ユーザーが 1 秒間に 1 回アクセスした場合、59 秒目では61 秒で 99 回アクセスされ、61 秒で 100 回アクセスされました。
ポリシー 1 に従って処理された場合、1 秒目から 60 秒目までに 100 件のリクエストが受信され、61 秒目で 100 件のリクエストが受信されたため、62 ~ 120 秒の間、IP は処理されなくなります。聞く。
問題ないようですが、よく考えてみると、59 秒から 61 秒の間に 99 100 = 199 件のリクエストが受け付けられ、その間隔はわずか 3 秒です。この場合、元の設計に問題があります。
解決策: Redis のリスト (双方向キュー) データ構造を使用できます。キーは user:$ip です。つまり、IP ごとに双方向キューが設定されます。リクエストが到着するたびに、
1. リストの要素数が 100 未満の場合、リクエスト到着時のタイムスタンプ Lpush がリストに追加されます。
2. リストに 100 個を超える要素がある場合は、右端の Lindex (-1) を取り出します。これは、100 個のリクエストの中で最も古いリクエストのタイムスタンプです。タイムスタンプ 現在のタイムスタンプとの差が 60 秒を超える場合、最初のリクエストの有効期限が切れたことを意味し、最初のリクエストは Rpop からデキューされます。次に、現在のタイムスタンプを Lpush にエンキューします。
redis の詳細については、redis 入門チュートリアル 列に注目してください。
以上がRedis での IP アクセス数を制限する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。