| 
                         这样客户端在使用时: 
- RedisLimit redisLimit = new RedisLimit.Builder<>(jedisCluster) 
 -  .limit(limit) 
 -  .build(); 
 
  
更加的简单直接,并且避免了将创建过程分成了多个子步骤。 
这在有多个构造参数,但又不是必选字段时很有作用。 
因此顺便将分布式锁的构建器方式也一并更新了: 
https://github.com/crossoverJie/distributed-redis-tool#features 
API 
从上文可以看出,使用过程就是调用 limit 方法。 
- //限流 
 -  boolean limit = redisLimit.limit(); 
 -  if (!limit){ 
 -  //具体限流逻辑 
 -  } 
 
  
为了减少侵入性,也为了简化客户端提供了两种注解方式。 
@ControllerLimit 
该注解可以作用于 @RequestMapping 修饰的接口中,并会在限流后提供限流响应。 
实现如下: 
- @Component 
 - public class WebIntercept extends WebMvcConfigurerAdapter { 
 -  private static Logger logger = LoggerFactory.getLogger(WebIntercept.class); 
 -  @Autowired 
 -  private RedisLimit redisLimit; 
 -  @Override 
 -  public void addInterceptors(InterceptorRegistry registry) { 
 -  registry.addInterceptor(new CustomInterceptor()) 
 -  .addPathPatterns("/**"); 
 -  } 
 -  private class CustomInterceptor extends HandlerInterceptorAdapter { 
 -  @Override 
 -  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
 -  Object handler) throws Exception { 
 -  if (redisLimit == null) { 
 -  throw new NullPointerException("redisLimit is null"); 
 -  } 
 -  if (handler instanceof HandlerMethod) { 
 -  HandlerMethod method = (HandlerMethod) handler; 
 -  ControllerLimit annotation = method.getMethodAnnotation(ControllerLimit.class); 
 -  if (annotation == null) { 
 -  //skip 
 -  return true; 
 -  } 
 -  boolean limit = redisLimit.limit(); 
 -  if (!limit) { 
 -  logger.warn("request has bean limit"); 
 -  response.sendError(500, "request limit"); 
 -  return false; 
 -  } 
 -  } 
 -  return true; 
 -  } 
 -  } 
 - } 
 
  
其实就是实现了 SpringMVC 中的拦截器,并在拦截过程中判断是否有使用注解,从而调用限流逻辑。 
前提是应用需要扫描到该类,让 Spring 进行管理。 
- @ComponentScan(value = "com.crossoverjie.distributed.intercept") 
 
  
@CommonLimit 
当然也可以在普通方法中使用。实现原理则是 Spring AOP (SpringMVC 的拦截器本质也是 AOP)。 
- @Aspect 
 - @Component 
 - @EnableAspectJAutoProxy(proxyTargetClass = true) 
 - public class CommonAspect { 
 -  private static Logger logger = LoggerFactory.getLogger(CommonAspect.class); 
 -  @Autowired 
 -  private RedisLimit redisLimit ; 
 -  @Pointcut("@annotation(com.crossoverjie.distributed.annotation.CommonLimit)") 
 -  private void check(){} 
 -  @Before("check()") 
 -  public void before(JoinPoint joinPoint) throws Exception { 
 -  if (redisLimit == null) { 
 -  throw new NullPointerException("redisLimit is null"); 
 -  } 
 -  boolean limit = redisLimit.limit(); 
 -  if (!limit) { 
 -  logger.warn("request has bean limit"); 
 -  throw new RuntimeException("request has bean limit") ; 
 -  } 
 -  } 
 - } 
 
  
很简单,也是在拦截过程中调用限流。 
当然使用时也得扫描到该包: 
- @ComponentScan(value = "com.crossoverjie.distributed.intercept") 
 
  
总结 
限流在一个高并发大流量的系统中是保护应用的一个利器,成熟的方案也很多,希望对刚了解这一块的朋友提供一些思路。                         (编辑:滁州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |