ホームページ  >  記事  >  データベース  >  Redis はどのようにして電流制限を実装できますか?

Redis はどのようにして電流制限を実装できますか?

王林
王林転載
2021-01-20 09:16:572153ブラウズ

Redis はどのようにして電流制限を実装できますか?

#目的:

  • アクセス頻度制限の実現

  • 訪問者 $ip を一定の制限内に抑える$time

時間内で $limit 回のみアクセスできます (学習ビデオ共有:

redis ビデオ チュートリアル)

非スクリプト実装

private boolean accessLimit(String ip, int limit, int time, Jedis jedis) {

    boolean result = true; String key = "rate.limit:" + ip; if (jedis.exists(key)) { long afterValue = jedis.incr(key); if (afterValue > limit) { result = false; } } else { Transaction transaction = jedis.multi(); transaction.incr(key); transaction.expire(key, time); transaction.exec(); }  return result; }

上記のコードには 2 つの欠陥があります


競合状態が発生する可能性があります: 解決策は WATCH を使用して rate.limit:$IP の変化を監視することですが、これはさらに面倒です。コードはパイプラインを使用しません この場合、Redis から最大 5 つの命令をリクエストする必要がありますが、送信するには多すぎます

Lua スクリプトの実装


Redis では、Lua スクリプトを使用して、実行のために Redis サーバーに転送され、スクリプト内で呼び出すことができます。 ほとんどの Redis コマンドと Redis はスクリプトのアトミック性を保証します:

最初に Lua コードを準備する必要があります: script.lua

--

-- Created by IntelliJ IDEA.

-- User: jifang

-- Date: 16/8/24

-- Time: 下午6:11 -- local key = "rate.limit:" .. KEYS[1] local limit = tonumber(ARGV[1]) local expire_time = ARGV[2] local is_exists = redis.call("EXISTS", key) if is_exists == 1 then if redis.call("INCR", key) > limit then return 0 else return 1 end else redis.call("SET", key, 1) redis.call("EXPIRE", key, expire_time) return 1 end

Java

private boolean accessLimit(String ip, int limit, int timeout, Jedis connection) throws IOException { List<String> keys = Collections.singletonList(ip); List<String> argv = Arrays.asList(String.valueOf(limit), String.valueOf(timeout)); return 1 == (long) connection.eval(loadScriptString("script.lua"), keys, argv); } // 加载Lua代码 private String loadScriptString(String fileName) throws IOException { Reader reader = new InputStreamReader(Client.class.getClassLoader().getResourceAsStream(fileName)); return CharStreams.toString(reader); }

Lua 組み込み Redis の利点:


ネットワーク オーバーヘッドの削減: Lua を使用しないコードは Redis に複数のリクエストを送信する必要がありますが、スクリプトを送信するだけで済みます。 1 回でネットワーク送信が削減される; アトミック操作: Redis はスクリプト全体をアトミックとして実行するため、心配する必要はありません。 同時実行とは、トランザクションの必要がないことを意味します。 再利用: スクリプトは Redis に永続的に保存され、他のクライアントは引き続き使用できます。

関連する推奨事項:

redis データベース チュートリアル

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

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。