Java는 동일한 IP가 aop를 통해 인터페이스를 요청하는 횟수 제한을 실현합니다.

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(만료 시간이 있는 맵을 설정할 수 있음) 키를 사용하여 인터페이스 주소를 저장하고 값을 사용하여 개수를 저장하면 됩니다. 타임스.

おすすめ

転載: blog.csdn.net/m0_52191385/article/details/130965359