1. 구현 방법
인터페이스 요청 수 제한은 인터페이스 요청 전에 판단해야 aop 또는 인터셉터를 통해 구현할 수 있습니다.
2. 구체적인 구현
1. 관련 jar 패키지 소개
expiringmap은 만료 시간을 설정할 수 있고 스레드로부터 안전한 맵입니다.
<!-- AOP 옵션 -->
<종속성>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<!-- 지도 보기 -->
<dependency>
<groupId>net.jodah</groupId>
<artifactId>expiringmap</artifactId>
<version>0.5.8</version>
</dependency>
2. 사용자 지정 주석 추가
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentLimiting { long time() default 60000; // 제한 시간 단위: 밀리초(현재 1분) int value() default 5; // 허용 요청 수 }
3. 사용자 정의 섹션 클래스 추가
패키지 com.test.aop; import com.test.interface1.CurrentLimiting; import jakarta.servlet.http.HttpServletRequest; import net.jodah.expiringmap.ExpirationPolicy; import net.jodah.expiringmap.ExpiringMap; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @측면 @요소 공개 클래스 CurrentLimitingAspect { 개인용 정적 ConcurrentHashMap<String, ExpiringMap<String, Integer>> map = new ConcurrentHashMap<>(); /** * 레이어 컷 포인트 */ @Pointcut("@annotation(currentLimiting)") 공공 무효 컨트롤러Aspect(CurrentLimiting currentLimiting) { } @Around("controllerAspect(currentLimiting)") 공공 객체 doAround(ProceedingJoinPoint pjp, CurrentLimiting currentLimiting) throws Throwable { // 요청 객체 가져오기 RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest 요청 = sra.getRequest(); // Map 값 객체를 가져오고, 그렇지 않으면 기본값을 반환합니다. // //getOrDefault는 매개변수를 가져옵니다. 가져오지 않으면 기본값을 제공합니다. ExpiringMap<String, Integer> em = map.getOrDefault(request.getRequestURI(), ExpiringMap.builder().variableExpiration().build()); 정수 개수 = em.getOrDefault(request.getRemoteAddr(), 0); if (Count >= currentLimiting.value()) { // 횟수를 초과하면 대상 메서드를 실행하지 않음 "인터페이스 요청 수가 초과되었습니다"를 반환합니다. } else if (Count == 0) { // 최초 요청시 유효한 시간을 설정 em.put(request.getRemoteAddr(), 개수 + 1, ExpirationPolicy.CREATED, currentLimiting.time(), TimeUnit.MILLISECONDS); } else { // 횟수를 초과하지 않으면 레코드에 1을 추가합니다. em.put(request.getRemoteAddr(), 개수 + 1); } map.put(request.getRequestURI(), em); // result의 값은 인터셉트된 메서드의 반환 값입니다. 개체 결과 = pjp.proceed(); 반환 결과; } }
4. 실행 방법 소개
ConcurrentHashMap(thread-safe) 키를 사용하여 인터페이스 주소 저장, expiringmap 저장 값(만료 시간이 있는 맵 설정 가능) 유형 ip 수집, ip 저장 expiringmap 키, 개수 저장 값 타임스.
5. 테스트 인터페이스
@RestController
@RequestMapping("/test")
public class ClassController { @GetMapping("/test") @CurrentLimiting() public String test(){ return "调用成功"; } }
5번 테스트 및 호출 후 리턴 포트 요청 횟수 초과, 다른 ip 변경시 5번 재계산 시작
단순히 ip 제한으로 인터페이스 수를 제한할 필요가 없다면 expiringmap(만료 시간이 있는 맵을 설정할 수 있음) 키를 사용하여 인터페이스 주소를 저장하고 값을 사용하여 개수를 저장하면 됩니다. 타임스.