加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

漫衍式限流,你想知道的都在这里

发布时间:2019-04-25 04:35:15 所属栏目:教程 来源:儒雅程序员
导读:媒介 在一个高并发体系中对流量的把控长短常重要的,当庞大的流量直接哀求到我们的处事器上没多久就也许造成接口不行用,不处理赏罚的话乃至会造成整个应用不行用。 好比最近就有个这样的需求,我作为客户端要向kafka出产数据,而kafka的斲丧者则再绵绵不断的

这样客户端在行使时:

  1. RedisLimit redisLimit = new RedisLimit.Builder<>(jedisCluster) 
  2.  .limit(limit) 
  3.  .build(); 

越发的简朴直接,而且停止了将建设进程分成了多个子步调。

这在有多个结构参数,但又不是必选字段时很有浸染。

因此趁便将漫衍式锁的构建器方法也一并更新了:

https://github.com/crossoverJie/distributed-redis-tool#features

API

从上文可以看出,行使进程就是挪用 limit 要领。

  1. //限流 
  2.  boolean limit = redisLimit.limit(); 
  3.  if (!limit){ 
  4.  //详细限流逻辑 
  5.  } 

为了镌汰侵入性,也为了简化客户端提供了两种注解方法。

@ControllerLimit

该注解可以浸染于 @RequestMapping 修饰的接口中,并会在限流后提供限流相应。

实现如下:

  1. @Component 
  2. public class WebIntercept extends WebMvcConfigurerAdapter { 
  3.  private static Logger logger = LoggerFactory.getLogger(WebIntercept.class); 
  4.  @Autowired 
  5.  private RedisLimit redisLimit; 
  6.  @Override 
  7.  public void addInterceptors(InterceptorRegistry registry) { 
  8.  registry.addInterceptor(new CustomInterceptor()) 
  9.  .addPathPatterns("/**"); 
  10.  } 
  11.  private class CustomInterceptor extends HandlerInterceptorAdapter { 
  12.  @Override 
  13.  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
  14.  Object handler) throws Exception { 
  15.  if (redisLimit == null) { 
  16.  throw new NullPointerException("redisLimit is null"); 
  17.  } 
  18.  if (handler instanceof HandlerMethod) { 
  19.  HandlerMethod method = (HandlerMethod) handler; 
  20.  ControllerLimit annotation = method.getMethodAnnotation(ControllerLimit.class); 
  21.  if (annotation == null) { 
  22.  //skip 
  23.  return true; 
  24.  } 
  25.  boolean limit = redisLimit.limit(); 
  26.  if (!limit) { 
  27.  logger.warn("request has bean limit"); 
  28.  response.sendError(500, "request limit"); 
  29.  return false; 
  30.  } 
  31.  } 
  32.  return true; 
  33.  } 
  34.  } 

着实就是实现了 SpringMVC 中的拦截器,并在拦截进程中判定是否有行使注解,从而挪用限流逻辑。

条件是应用必要扫描到该类,让 Spring 举办打点。

  1. @ComponentScan(value = "com.crossoverjie.distributed.intercept") 

@CommonLimit

虽然也可以在平凡要领中行使。实现道理则是 Spring AOP (SpringMVC 的拦截器本质也是 AOP)。

  1. @Aspect 
  2. @Component 
  3. @EnableAspectJAutoProxy(proxyTargetClass = true) 
  4. public class CommonAspect { 
  5.  private static Logger logger = LoggerFactory.getLogger(CommonAspect.class); 
  6.  @Autowired 
  7.  private RedisLimit redisLimit ; 
  8.  @Pointcut("@annotation(com.crossoverjie.distributed.annotation.CommonLimit)") 
  9.  private void check(){} 
  10.  @Before("check()") 
  11.  public void before(JoinPoint joinPoint) throws Exception { 
  12.  if (redisLimit == null) { 
  13.  throw new NullPointerException("redisLimit is null"); 
  14.  } 
  15.  boolean limit = redisLimit.limit(); 
  16.  if (!limit) { 
  17.  logger.warn("request has bean limit"); 
  18.  throw new RuntimeException("request has bean limit") ; 
  19.  } 
  20.  } 

很简朴,也是在拦截进程中挪用限流。

虽然行使时也得扫描到该包:

  1. @ComponentScan(value = "com.crossoverjie.distributed.intercept") 

总结

限流在一个高并发大流量的体系中是掩护应用的一个利器,成熟的方案大概多,但愿对刚相识这一块的伴侣提供一些思绪。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读