추천: "PHP 비디오 튜토리얼"
일상 비즈니스 기능 개발에서 특정 기간에 특정 횟수만큼 특정 인터페이스에 액세스하도록 모든 IP를 제한하려는 경우 어떻게 해야 합니까? 그것을 구현?
이 기능 요구 사항은 일반적으로 스크립트가 인터페이스를 악의적으로 브러싱하는 것을 방지하는 데 사용됩니다. 현재 인터넷에는 비교적 완전한 전류 제한 솔루션이 많이 있습니다. 일반 사이트의 경우 redis의 연결리스트 데이터 구조를 이용하여 IP 전류 제한 기능을 구현할 수 있습니다.
예를 들어 -
인터페이스 A에 대해 연속 5초마다 최대 3번의 액세스를 허용하도록 모든 IP를 제한하고, 3회를 초과하면 오류를 반환해야 한다고 가정해 보겠습니다.
위 사진의 경우 08초에 지난 5초 동안 4개의 요청이 발생하여 최대 개수 제한에 도달하여 현재 접속이 제한됩니다.
PHP로 구현한 경우 구체적인 로직 코드는 다음과 같습니다. -
/** * 检查队列的长度是否到达设定的阈值,已到达则返回false,未到达则将当前时间戳推入队列最末端,同时刷新队列整体的缓存时间 * @param $key 队列缓存的key * @param $expire 队列缓存过期时间,例如上面例子中的5秒 * @param $limit 队列长度阈值,如上面例子中的3次 * @return bool */public function checkLimit($key, $expire, $limit){ $length = $this->refreshList($key, $expire); if ($length rPush($key, time()); $this->expire($key, intval($limit)); return true; } return false;}/** * 刷新队列,过滤掉已经不在有效时间内的值,返回最新队列的长度 * @param $key string 自定义的缓存key * @param $expire 队列缓存过期时间,例如上面例子中的5秒 * @return bool|int */public function refreshList ($key, $expire) { if ($this->has($key)) { do { // 对于已存在数据的list,要先从前往后把已经过期的数据弹出 $oldest_value = $this->lPop($key); } while ($oldest_value && time() - $oldest_value > $expire); // 把最后弹出的数据重新塞回list的最前边 $oldest_value && $this->lPush($key, $oldest_value); return $this->lLen($key); } return 0;}
여기에 사용된 lPop, lPush, lLen, rPush 및 기타 메소드는 모두 Redis 확장을 캡슐화한 후 연결 목록 데이터 구조를 작동하는 메소드입니다. 반환 값은 기본 메서드와 일치합니다.
사실 나중에 온라인으로 확인한 결과 redis가 이 시나리오를 처리할 때 zset과 같은 순서 집합을 사용하여 더 직접적으로 구현된다는 것을 알았습니다. 논리는 기본적으로 현재 타임스탬프를 저장한 다음 슬라이딩을 사용하는 것입니다. 창 알고리즘 아이디어. 현재 창의 값 길이가 제한을 초과했는지 확인합니다.
위 내용은 IP 전류 제한 작업을 구현하기 위한 redis 기반 PHP의 목록 유형 데이터 구조에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!