这样客户端在行使时:
- 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")
总结
限流在一个高并发大流量的体系中是掩护应用的一个利器,成熟的方案大概多,但愿对刚相识这一块的伴侣提供一些思绪。 (编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|