Sentinel如何根据IP一段时间内禁止访问?

比如:有用户暴力注册,然后我限制他所属的ip只能1小时注册5次,防止一直注册

阅读 619
1 个回答

Sentinel自身没有这个功能的,但是可以拓展,这里有几个麻烦点
1.不能动态的配置,例如根据接口URL等,想添加新的接口,只能改代码,如需动态配置,需要自己拓展
2.获取IP的问题,在代理场景下,IP获取不准

大致步骤如下:
1.需要一个IP参数的解析器

@Component
public class IpParamParser implements RequestAttributeParser {
    @Override
    public String parse(HttpServletRequest request) {
        // 可根据需要处理代理IP X-Forwarded-For
        return request.getRemoteAddr(); 
    }
}

2.@SentinelResource配置

@PostMapping("/register")
@SentinelResource(
    value = "register",
    blockHandler = "handleBlock",
    blockHandlerClass = {SentinelBlockHandler.class}
)
public ResponseEntity<String> register(User user) {
    // 注册逻辑
    return ResponseEntity.ok("注册成功");
}

3.限流异常的处理

public class SentinelBlockHandler {
    public static ResponseEntity<String> handleBlock(BlockException ex) {
        return ResponseEntity.status(429).body("请求过于频繁,请1小时后再试");
    }
}

4.配置规则

@PostConstruct
public void initFlowRules() {
    ParamFlowRule rule = new ParamFlowRule("register")
        .setParamIdx(0) // 对应参数索引
        .setCount(5) // 1小时内允许5次
        .setGrade(RuleConstant.FLOW_GRADE_QPS)
        .setDurationInSec(3600); // 时间窗口1小时
    ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
}

上述代码还需考虑:

  • 集群部署:上面是单机限流,需集群限流需启用Sentinel集群流控并配置Nacos等Token Server。
  • 规则持久化:默认规则存储在内存,重启失效。可通过集成Nacos/Zookeeper实现持久化。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进