>  기사  >  데이터 베이스  >  Redis는 어떻게 전류 제한을 구현할 수 있나요?

Redis는 어떻게 전류 제한을 구현할 수 있나요?

王林
王林앞으로
2021-01-20 09:16:572107검색

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; }

위 코드에는 두 가지 결함이 있습니다

경쟁 조건이 있을 수 있습니다. 해결 방법은 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에 여러 요청을 보내야 하지만 스크립트는 한 번만 필요하므로 네트워크 전송이 줄어듭니다. 원자 작업: Redis는 동시성을 걱정하지 않고 전체 스크립트를 원자 작업으로 실행합니다. 트랜잭션 재사용: 스크립트는 Redis에 영구적으로 저장되며 다른 클라이언트는 이를 계속 사용할 수 있습니다.

관련 권장 사항: redis 데이터베이스 튜토리얼

위 내용은 Redis는 어떻게 전류 제한을 구현할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제