优秀的编程知识分享平台

网站首页 > 技术文章 正文

使用Redisson+AOP+自定义注解 实现 访问限流和黑名单拦截操作?

nanyue 2024-09-01 00:07:22 技术文章 4 ℃

IP访问限流则是性能管理的重要措施。在面临大量网络请求时,为了防止系统过载或遭受恶意攻击,需要对IP访问进行限制。通过限制单个IP或IP段的访问频率,可以有效保护系统资源,防止因过多请求导致的性能下降或服务中断。

如何在Spring Boot项目中实现IP访问限制以及限流操作,可以结合结合Redisson、AOP和自定义注解来实现。下面是一个简单的示例代码。

添加依赖

由于需要用到Redisson所以需要引入Redisson的相关依赖,注意版本需要根据自己适配的版本来进行选择。

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.16.0</version>
</dependency>

配置Redisson

application.propertiesapplication.yml中配置Redisson连接信息。

spring.redis.redisson.config=classpath:/redisson.yml

需要在resources目录下创建一个redisson.yml文件,配置Redisson连接信息,如下所示。

singleServerConfig:
  address: "redis://127.0.0.1:6379"

自定义注解

创建一个自定义注解,用于标记需要进行访问限流和黑名单拦截的方法。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessLimit {
    int value() default 5; // 默认限流阈值
    int period() default 60; // 默认限流时间窗口,单位秒
}

创建了一个注解可以分别设置阈值与限流窗口大小。

AOP拦截切面

@Aspect
@Component
public class AccessLimitAspect {

    @Autowired
    private RedissonClient redissonClient;

    @Pointcut("@annotation(com.example.AccessLimit)")
    public void accessLimitPointcut() {
    }

    @Before("accessLimitPointcut()")
    public void before(JoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        AccessLimit accessLimit = methodSignature.getMethod()
          .getAnnotation(AccessLimit.class);
      	// 限流参数判断
        if (accessLimit != null) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                                          .getRequestAttributes()).getRequest();
            String ip = request.getRemoteAddr();
            String key = "access:" + ip + ":" + request.getRequestURI();
            RMapCache<String, Integer> accessMap = redissonClient.getMapCache("accessMap");
            Integer count = accessMap.get(key);
            if (count == null) {
                accessMap.put(key, 1, accessLimit.period(), TimeUnit.SECONDS);
            } else {
                if (count >= accessLimit.value()) {
                    throw new RuntimeException("访问频率过高,已被限流");
                } else {
                    accessMap.put(key, count + 1, accessLimit.period(), TimeUnit.SECONDS);
                }
            }
        }
    }
}

测试类

在需要进行访问限流和黑名单拦截的方法上添加自定义注解。

@RestController
public class MyController {

    @AccessLimit(value = 5, period = 60)
    @GetMapping("/api/test")
    public String test() {
        return "Test API";
    }
}

/api/test接口被添加了@AccessLimit注解,表示这个接口需要进行访问限流和黑名单拦截。当用户访问频率超过限定阈值时,将会抛出异常,并返回限流提示信息。

总结

通过以上步骤,就可以在Spring Boot应用中使用Redisson、AOP和自定义注解实现访问限流和黑名单拦截功能

实现白名单和IP访问限流主要是出于安全性和性能管理的考虑,通过限制和控制访问请求,保护系统资源和数据安全,提高服务质量和效率。

Tags:

最近发表
标签列表