☰
Sentinel 流控配置案例:两次请求的时间间隔必须在3秒以上
2026/10/15 4:41:43 网站建设 项目流程

要实现“两次请求的时间间隔必须在3秒以上”这种需求,需要根据具体的业务场景选择合适的Sentinel配置方式。本文博主将介绍几种实现方案:

方案1:使用排队等待流控效果(最接近需求)

# Sentinel规则配置(对应控制台设置)规则类型:流控规则 资源名:yourResource 流控模式:直接 阈值类型:QPS 阈值:0.33(因为1/3≈0.33,即每秒最多0.33个请求) 流控效果:排队等待 超时时间:3000ms(3秒)

控制台设置:

┌─────────────────────────────────────┐ │ 添加流控规则 │ ├─────────────────────────────────────┤ │ 资源名: yourResource │ │ 阈值类型: QPS │ │ 单机阈值: 0.33 │ │ 流控模式: [直接] │ │ │ │ 流控效果: [排队等待] │ │ 超时时间: 3000 ms │ └─────────────────────────────────────┘

工作原理:

  • 请求进入队列排队
  • 每个请求处理间隔至少3秒
  • 如果请求到达太快,会在队列中等待
  • 如果等待时间超过3秒,会被拒绝

代码示例:

@RestControllerpublicclassMyController{@GetMapping("/api/resource")@SentinelResource(value="myResource",blockHandler="handleBlock")publicStringmyApi(){// 业务逻辑return"success";}// 阻塞处理函数publicStringhandleBlock(BlockExceptione){return"请求太频繁,请至少间隔3秒再试";}}

方案2:使用Warm Up预热模式(接近但不完全符合)

规则类型:流控规则 资源名:yourResource 阈值类型:QPS 阈值:0.33 流控效果:Warm Up 预热时长:3秒

方案3:使用热点参数限流(针对同一用户/设备)

如果需要针对同一用户限制3秒间隔,使用热点参数规则:

@GetMapping("/api/resource")@SentinelResource(value="myResource")publicStringmyApi(@RequestParamStringuserId){// 业务逻辑return"success";}

控制台配置:

规则类型:热点参数规则 资源名:myResource 参数索引:0(对应userId) 单机阈值:1(每个userId) 统计窗口时长:3000ms(3秒)

方案4:自定义实现(最灵活)

@ComponentpublicclassRequestIntervalLimiter{privatefinalMap<String,Long>lastRequestTime=newConcurrentHashMap<>();publicbooleanallowRequest(Stringkey){longcurrentTime=System.currentTimeMillis();LonglastTime=lastRequestTime.get(key);if(lastTime==null){lastRequestTime.put(key,currentTime);returntrue;}// 检查时间间隔if(currentTime-lastTime>=3000){lastRequestTime.put(key,currentTime);returntrue;}returnfalse;}}@RestControllerpublicclassMyController{@AutowiredprivateRequestIntervalLimiterlimiter;@GetMapping("/api/resource")publicResponseEntity<?>myApi(HttpServletRequestrequest){StringclientId=getClientId(request);// 获取客户端标识if(!limiter.allowRequest(clientId)){returnResponseEntity.status(429).body("请求太频繁,请至少间隔3秒再试");}// 业务逻辑returnResponseEntity.ok("success");}privateStringgetClientId(HttpServletRequestrequest){// 根据业务获取客户端标识// 可以是:userId, IP, sessionId等returnrequest.getHeader("X-User-Id")!=null?request.getHeader("X-User-Id"):request.getRemoteAddr();}}

方案5:使用Sentinel的系统自适应保护(全局限制)

spring:cloud:sentinel:filter:enabled:true# 系统规则 - 限制整体QPSdatasource:ds1:nacos:server-addr:localhost:8848dataId:sentinel-system-rulesrule-type:system

系统规则配置:

{"avgRt":1000,"highestSystemLoad":0.8,"qps":0.33,// 全局QPS限制"highestCpuUsage":0.8,"maxThread":50}

推荐方案比较

方案优点缺点适用场景
排队等待Sentinel原生支持不是严格3秒间隔需要均匀处理请求
自定义实现最精确控制需要自己实现精确的3秒间隔需求
热点参数按用户/设备限制配置复杂针对特定用户限制
系统规则全局控制不够精确系统整体保护

最接近需求的配置

如果严格要求"两次请求间隔必须≥3秒":

  1. 使用方案1的排队等待:

    QPS阈值 = 1 / 3 ≈ 0.33 超时时间 = 3000ms
  2. 配合自定义逻辑增强:

@ComponentpublicclassStrictIntervalLimiter{privatefinalLoadingCache<String,Long>requestCache=CacheBuilder.newBuilder().expireAfterWrite(3,TimeUnit.SECONDS).build(newCacheLoader<String,Long>(){@OverridepublicLongload(Stringkey){returnSystem.currentTimeMillis();}});publicbooleantryAcquire(Stringkey){try{// 如果key存在,说明3秒内有过请求LonglastTime=requestCache.getIfPresent(key);if(lastTime!=null){returnfalse;}requestCache.put(key,System.currentTimeMillis());returntrue;}catch(Exceptione){returnfalse;}}}

最佳实践建议:

  • 如果只是需要大致3秒间隔,使用方案1(排队等待)
  • 如果需要严格精确的3秒间隔,使用方案4(自定义实现)
  • 如果需要针对不同用户分别限制,使用方案3(热点参数)+ 方案4组合

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询