ホームページ  >  記事  >  データベース  >  Redis 自体が電流の流れを制限できますか?

Redis 自体が電流の流れを制限できますか?

(*-*)浩
(*-*)浩オリジナル
2019-11-22 10:08:402553ブラウズ

Redis 自体が電流の流れを制限できますか?

もちろん、電流制限を実装する方法はたくさんありますが、Redis には非常に強力な機能がありますので、今回は Redis を使って比較的簡単に実装できる 3 つの実装方法を実践しました。 Redis は電流制限を行うだけでなく、データ統計、近くの人々、その他の機能も実行できます。

1: Redis ベースの Setnx (推奨学習: Redis ビデオ チュートリアル )

## Redis の分散型を使用する場合ロックは、setnx 命令に依存していることを誰もが知っています。CAS (比較およびスワップ) 操作中に、同時に指定されたキーの有効期限 (expire) が設定されます。主に現在のキーを制限することが目的です。単位時間内にコード プログラムにアクセスするリクエストは N 回だけです。 したがって、setnx に依存すると、この機能を簡単に実現できます。

10 秒以内に 20 件のリクエストを制限する必要がある場合、setnx を設定するときに有効期限を 10 に設定できます。リクエストされた setnx の数が 20 に達すると、電流制限の効果が達成されます。

もちろん、このアプローチには多くの欠点があります。たとえば、1 ~ 10 秒をカウントする場合、2 ~ 11 秒をカウントすることは不可能です。N 秒以内に M 件のリクエストをカウントする必要がある場合、次に、N 個のキーとその他の問題を Redis に保持する必要があります。

2 番目のタイプ: Redis ベースのデータ構造 zset

実際、現在のデータ構造に関係する最も重要なことは、制限はスライディング ウィンドウですが、1 ~ 10 がどのように 2 ~ 11 になるかについても上で説明しました。実際、開始値と終了値は両方とも 1 です。


そして、Redis のリスト データ構造を使用すると、この関数を簡単に実装できます。


リクエストを zset 配列に作成し、各リクエストが来たときにでは、値は一意のままであり、UUID によって生成でき、スコアは現在のタイムスタンプで表すことができます。これは、スコアを使用して現在のタイムスタンプ内のリクエストの数を計算できるためです。

zset データ構造は、2 つのタイムスタンプ内に存在するリクエストの数を簡単に取得できる range メソッドも提供します。


3 番目のタイプ: Redis トークン バケットに基づくアルゴリズム

電流制限に関して言えば、トークン バケット アルゴリズムについて言及する必要があります。トークン バケット アルゴリズムは、バケット アルゴリズムとも呼ばれます。詳細については、Du Niang の説明を参照してください。トークン バケット アルゴリズム


トークン バケット アルゴリズムには、入力レートと出力レートが記載されています。出力レートが大きい場合入力レートを超えると、トラフィック制限を超えます。


つまり、リクエストにアクセスするたびに、Redis からトークンを取得できます。トークンを取得できた場合は、制限を超えていないことを意味し、取得できなかった場合は、制限を超えていないことを意味します。それなら、結果は逆になります。


上記のアイデアに基づいて、Redis の List データ構造を組み合わせてそのようなコードを簡単に実現できます。


List の leftPop を利用して、トークン

// 输出令牌
public Response limitFlow2(Long id){
        Object result = redisTemplate.opsForList().leftPop("limit_list");
        if(result == null){
            return Response.ok("当前令牌桶中无令牌");
        }
        return Response.ok(articleDescription2);
    }

次に、Java のスケジュールされたタスクに依存して、定期的にトークンをリストに右プッシュします。もちろん、トークンも一意である必要があるため、ここでトークンを生成するために UUID を使用します

// 10S的速率往令牌桶中添加UUID,只为保证唯一性
    @Scheduled(fixedDelay = 10_000,initialDelay = 0)
    public void setIntervalTimeTask(){
        redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());
    }

包括的 最初にコードを実装するのは難しくありません。これらの電流制限メソッドの場合、AOP またはフィルターに上記のコードを追加して、インターフェイスの現在のフローを制限し、最終的に Web サイトを保護できます。

Redis 関連の技術記事の詳細については、

「Redis データベース チュートリアルの使用方法の概要」 列にアクセスして学習してください。

以上がRedis 自体が電流の流れを制限できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。