Heim > Datenbank > Redis > Hauptteil

Wie kann Redis eine Strombegrenzung implementieren?

王林
Freigeben: 2021-01-20 09:16:57
nach vorne
2151 Leute haben es durchsucht

Wie kann Redis eine Strombegrenzung implementieren?

Zweck:

  • Um eine Zugriffshäufigkeitsbeschränkung zu erreichen

  • Um zu erreichen, dass Besucher $ip nur $limit-Zeiten innerhalb einer bestimmten Zeit $time zugreifen können

(Teilen von Lernvideos: redis-Video-Tutorial )

Nicht-Skript-Implementierung

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; }
Nach dem Login kopieren

Der obige Code weist zwei Mängel auf

Es kann zu Race-Bedingungen kommen: Die Lösung besteht darin, WATCH zu verwenden, um rate.limit:$IP-Änderungen zu überwachen, aber es ist problematischer; Code verwendet keine Pipeline. In diesem Fall müssen bis zu 5 Anweisungen von Redis angefordert werden, was zu viel ist, um sie zu übertragen.


Redis ermöglicht die Übertragung von Lua-Skripten zur Ausführung auf den Redis-Server Redis-Befehle können im Skript aufgerufen werden, und Redis stellt sicher, dass das Skript Atomicity:

Zuerst müssen Sie Lua-Code vorbereiten: 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
Nach dem Login kopieren

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); }
Nach dem Login kopieren

Lua Einbettung von Redis Vorteile:


Reduzierter Netzwerk-Overhead: Codes Diejenigen, die Lua nicht verwenden, müssen mehrere Anfragen an Redis senden, aber das Skript benötigt nur einmal, wodurch die Netzwerkübertragung reduziert wird. Atomare Operation: Redis führt das gesamte Skript als atomare Operation aus, ohne sich um die Parallelität zu kümmern, und es sind keine Transaktionen erforderlich ; Wiederverwendung: Das Skript wird dauerhaft in Redis gespeichert und kann von anderen Clients weiterhin verwendet werden.

Verwandte Empfehlungen:

Redis-Datenbank-Tutorial

Das obige ist der detaillierte Inhalt vonWie kann Redis eine Strombegrenzung implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!