zuul实现限流

zuul限流
限流算法
漏桶: leakey bucket,原理:桶的下方的小孔会以一个相对恒定的速率漏水,而不管入桶的水流量,这样就达到了控制出水口的流量
令牌桶: token bucket,原理:以相对恒定的速率向桶中加入令牌,请求来时于桶中取令牌,取到了就放行,没能取到令牌的请求则丢弃
限流粒度
粗粒度
网关限流
单个服务
细粒度
user: 认证用户或者匿名,针对某个用户粒度进行限流
origin: 客户机的IP,针对请求客户机的IP进行限流
url: 特定url,针对请求的url粒度进行限流
serviceId: 特定服务,针对某个服务的id粒度进行限流
实现
从单个服务的角度实现限流,原理:利用redis键过期的自动删除的特性。以url为key,如果key不存在,创建key,并设置键过期时间,相同请求过来就对这个key进行计数,使用redis.incr原子方法,当请求超过limit时,则不让请求api。

1.定义注解:br/>@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)br/>@Documented
public @interface RateLimit {

//每秒请求
int value() default 10;

}

2.定义切面br/>@Aspect
@Component
br/>@Slf4j
public class RateLimitAspect {

@Autowired
private RedisTemplate redisTemplate;

@Pointcut(value = "@annotation(com.pinlor.gml.cloudrateservice.annotation.RateLimit)")
public void pointcut(){

}

@Around(value = "pointcut()")
@ResponseBody
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    log.debug("限速检测");
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Method method = methodSignature.getMethod();
    RateLimit rate = method.getAnnotation(RateLimit.class);
    int limit = rate.value();
    HttpServletRequest request = RequestUtil.getRequest();
    String key = request.getRequestURI();
    //最好以下部分用redis分布锁加锁一下
    Object object = redisTemplate.opsForValue().get(key);
    if (object == null){
        redisTemplate.opsForValue().increment(key);
        redisTemplate.expire(key, 1, TimeUnit.SECONDS);
    }else {
        System.out.println("当前记数: "+ redisTemplate.opsForValue().get(key));
        if (redisTemplate.opsForValue().increment(key) > limit) {
            System.out.println("服务器繁忙,请稍后再试!!");
            return "服务器繁忙,请稍后再试!!";
        }
    }

    return joinPoint.proceed();

}

}

3.redis配置:br/>@Configuration
public class RedisConfig {

@Autowired
private RedisConnectionFactory redisConnectionFactory;

// 默认用的是用JdkSerializationRedisSerializer进行序列化的
@Bean
public RedisTemplate<String, Object> redisTemplate() {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    // 注入数据源
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    // 使用Jackson2JsonRedisSerialize 替换默认序列化
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
                         new Jackson2JsonRedisSerializer(Object.class);
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    // key-value结构序列化数据结构
    redisTemplate.setKeySerializer(stringRedisSerializer);
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    // hash数据结构序列化方式,必须这样否则存hash 就是基于jdk序列化的
    redisTemplate.setHashKeySerializer(stringRedisSerializer);
    redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
    // 启用默认序列化方式
    redisTemplate.setEnableDefaultSerializer(true);
    redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);

    /// redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

}

4.api服务:br/>@RestController
@RequestMapping(value = "/rc")
public class RateController {

@Value(value = "${server.port}")
private int port;

@RateLimit(value = 10)
@GetMapping("/getRate")
public String getRate(){
    System.out.println("rate from: "+ port);
    return "rate from: "+ port;
}

}

5.工具类:
public class RequestUtil {

public static HttpServletRequest getRequest(){
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    if (requestAttributes == null){
        return null;
    }
    return ((ServletRequestAttributes)requestAttributes).getRequest();
}

}
6.maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>

zuul实现限流

原文地址:https://blog.51cto.com/youling87/2486771

时间: 2024-10-31 04:58:46

zuul实现限流的相关文章

SpringCloud zuul 实现限流

zuul: routes: user-service: path: /user/** serviceId: user-service add-host-header: true sensitive-headers: Access-Control-Allow-Origin,Access-Control-Allow-Methods strip-prefix: true ratelimit: # 开启限流 enabled: true # 存储方式 repository: REDIS # 限流策略 po

SpringCloud(8)----zuul权限校验、接口限流

项目代码GitHub地址:https://github.com/yudiandemingzi/spring-cloud-study 一.权限校验搭建 正常项目开发时,权限校验可以考虑JWT和springSecurity结合进行权限校验,这个后期会总结,这里做个基于ZuulFilter过滤器进行一个简单的权限校验过滤. 对于组件zuul中,其实带有权限认证的功能,那就是ZuulFilter过滤器.ZuulFilter是Zuul中核心组件,通过继承该抽象类,覆写几个关键方法达到自定义调度请求的作用

Spring Cloud限流思路及解决方案

转自: http://blog.csdn.net/zl1zl2zl3/article/details/78683855 在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法.常见的限流算法有漏桶算法以及令牌桶算法.这个可参考 https://www.cnblogs.com/LBSer/p/4083131.html ,写得通俗易懂,你值得拥有,我就不拽文

使用springcloud gateway搭建网关(分流,限流,熔断)

Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式. Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter

更好用的集群限流功能,Sentinel 发布 v1.4.2

摘要: 感谢 Sentinel 社区的贡献者们 ? Sentinel 发布 v1.4.2 正式发布,该版本主要变更如下: 特性/功能改进 新增 Zuul 1.x 适配模块(sentinel-zuul-adapter),结合集群限流特性可以更好地在 API Gateway 发挥流控的作用 热点参数限流添加线程数模式支持 在 BlockException 中携带更多的信息(如触发的规则) 完善 Tracer,支持针对某个 Entry 或 Context 记录异常数目 优化 ClusterStateM

Spring Cloud Alibaba | Sentinel: 服务限流基础篇

目录 Spring Cloud Alibaba | Sentinel: 服务限流基础篇 1. 简介 2. 定义资源 2.1 主流框架的默认适配 2.2 抛出异常的方式定义资源 2.3 返回布尔值方式定义资源 2.4 注解方式定义资源 2.5 异步调用支持 3. 规则的种类 3.1 流量控制规则 (FlowRule) 3.2 熔断降级规则 (DegradeRule) 3.3 系统保护规则 (SystemRule) 3.4 访问控制规则 (AuthorityRule) Spring Cloud Al

Spring Cloud微服务安全实战_4-10_用spring-cloud-zuul-ratelimit做限流

本篇讲网关上的限流 用开源项目spring-cloud-zuul-ratelimit 做网关上的限流 (项目github:https://github.com/marcosbarbero/) 1,在网关项目里,引入限流组件的maven依赖: 2,在网关项目yml配置里,配限流相关配置 github也有相关配置说明:https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit 限流框架限流需要存一些信息,可以存在数据库里,也可以存在red

SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级

源码地址:GitHub·点这里||GitEE·点这里 一.基本简介 1.概念描述 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性.包括核心的独立类库,监控台,丰富的使用场景验证.(这似乎是阿里开源组件的一贯作风,极其有特点,且特点很规律) 基本特性图: 补刀一句:这种图很多人可能不在意,但是一般官方给这个图就是该中间件的基本使用思路,与核心功能点. 2.基础性概念 资源管理 资源是Sentinel组件中的核心概念之一.应用服务器上脚本,静态页面,A

springboot + aop + Lua分布式限流原理解析

一.什么是限流?为什么要限流?不知道大家有没有做过帝都的地铁,就是进地铁站都要排队的那种,为什么要这样摆长龙转圈圈?答案就是为了 限流 !因为一趟地铁的运力是有限的,一下挤进去太多人会造成站台的拥挤.列车的超载,存在一定的安全隐患.同理,我们的程序也是一样,它处理请求的能力也是有限的,一旦请求多到超出它的处理极限就会崩溃.为了不出现最坏的崩溃情况,只能耽误一下大家进站的时间. 限流是保证系统高可用的重要手段!!! 由于互联网公司的流量巨大,系统上线会做一个流量峰值的评估,尤其是像各种秒杀促销活动