精华内容
下载资源
问答
  • 主要介绍了SpringCloud Zuul过滤器和谷歌Gauva实现限流,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要介绍了php使用lua+redis实现限流,计数器模式,令牌桶模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 本篇文章主要介绍了基于 Redis 实现分布式应用限流的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了Spring Cloud Alibaba使用Sentinel实现接口限流,本文详细的介绍了Sentinel组件的用法以及接口限流,感兴趣的可以了解一下
  • spring cloud gateway 实现限流

    千次阅读 2019-04-23 17:11:17
    对一些客流访问量比较大,存在高并发情况的系统,就需要在系统中进行限流,一方面是为了防止大量的请求致使服务器宕机,导致服务不可用,另一方面是为了防止网络攻击。 一般的应用服务器,都是通过限制线程池的线程...

    对一些客流访问量比较大,存在高并发情况的系统,就需要在系统中进行限流,一方面是为了防止大量的请求致使服务器宕机,导致服务不可用,另一方面是为了防止网络攻击。
    一般的应用服务器,都是通过限制线程池的线程数来控制并发,也有通过单位时间内窗口的平均速度来控制流量。常见的限流纬度有比如通过Ip来限流、通过uri来限流、通过用户访问频次来限流。

    常见的限流算法:

    引用一位博主所介绍的,个人觉得说的很容易理解与透彻,原文地址:https://blog.csdn.net/forezp/article/details/85081162

    计数器算法:

    计数器算法采用计数器实现限流有点简单粗暴,一般我们会限制一秒钟的能够通过的请求数,比如限流qps为100,算法的实现思路就是从第一个请求进来开始计时,在接下去的1s内,每来一个请求,就把计数加1,如果累加的数字达到了100,那么后续的请求就会被全部拒绝。等到1s结束后,把计数恢复成0,重新开始计数。具体的实现可以是这样的:对于每次服务调用,可以通过AtomicLong#incrementAndGet()方法来给计数器加1并返回最新值,通过这个最新值和阈值进行比较。这种实现方式,相信大家都知道有一个弊端:如果我在单位时间1s内的前10ms,已经通过了100个请求,那后面的990ms,只能眼巴巴的把请求拒绝,我们把这种现象称为“突刺现象”。

    漏桶算法:

    漏桶算法为了消除"突刺现象",可以采用漏桶算法实现限流,漏桶算法这个名字就很形象,算法内部有一个容器,类似生活用到的漏斗,当请求进来时,相当于水倒入漏斗,然后从下端小口慢慢匀速的流出。不管上面流量多大,下面流出的速度始终保持不变。不管服务调用方多么不稳定,通过漏桶算法进行限流,每10毫秒处理一次请求。因为处理的速度是固定的,请求进来的速度是未知的,可能突然进来很多请求,没来得及处理的请求就先放在桶里,既然是个桶,肯定是有容量上限,如果桶满了,那么新进来的请求就丢弃。
    在这里插入图片描述
    在算法实现方面,可以准备一个队列,用来保存请求,另外通过一个线程池(ScheduledExecutorService)来定期从队列中获取请求并执行,可以一次性获取多个并发执行。
    这种算法,在使用过后也存在弊端:无法应对短时间的突发流量。

    令牌桶算法:

    从某种意义上讲,令牌桶算法是对漏桶算法的一种改进,桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用的平均速率的同时还允许一定程度的突发调用。在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。放令牌这个动作是持续不断的进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这时进来的请求就可以直接拿到令牌执行,比如设置qps为100,那么限流器初始化完成一秒后,桶中就已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。
    在这里插入图片描述
    实现思路:可以准备一个队列,用来保存令牌,另外通过一个线程池定期生成令牌放到队列中,每来一个请求,就从队列中获取一个令牌,并继续执行。

    Spring Cloud Gateway 实现限流

    在Spring Cloud Gateway中,有Filter过滤器,因此可以在“pre”类型的Filter中自行实现上述三种过滤器,因此Spring Cloud Gateway可以使用内置的限流过滤器工厂来实现限流。

    首先看下项目结构:

    在这里插入图片描述
    一个服务注册中心eurekaserver、一个服务实例gateway-service-hi、一个网关实现限流gateway-limiter

    接下来详细介绍gateway-limiter的配置

    在pom.xml文件中添加依赖:

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    

    spring-boot-starter-data-redis-reactive:使用redis实现限流

    application.yml配置如下-

    server:
      port: 8887
    
    spring:
      application:
        name: gateway-limiter
      cloud:
        gateway:
          routes:
            - id: gateway-service-hi
              uri: lb://gateway-service-hi
              predicates:
                - Path=/gateway/**
              filters:
                - name: RequestRateLimiter
                  args:
                    #用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象
                    key-resolver: "#{@hostAddKeyResolver}"
                    #令牌桶每秒填充平均速率
                    redis-rate-limiter.replenishRate: 2
                    #令牌桶总容量
                    redis-rate-limiter.burstCapacity: 4
                - StripPrefix=1
          discovery:
            locator:
              enabled: true
    #          服务名可以小写
              lowerCaseServiceId: true
    
      redis:
        host: localhost
        port: 6379
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
    

    在上面的配置文件,指定程序的端口为8887,也配置了 redis的信息,并配置了RequestRateLimiter的限流过滤器,该过滤器需要配置三个参数:

    burstCapacity,令牌桶总容量。
    replenishRate,令牌桶每秒填充平均速率,也可以理解为每秒允许的请求访问次数
    key-resolver,用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

    Bean 对象,这里是hostAddKeyResolver,根据IP进行限流,要实现抽线类KeyResolver,重写esolver方法

    package com.sinosoft.gatewaylimiter.resolver;
    
    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    public class HostAddKeyResolver implements KeyResolver {
        @Override
        public Mono<String> resolve(ServerWebExchange exchange) {
            return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
        }
    
    }
    

    也可以根据uri去限流,代码如下:

    public class UriKeyResolver  implements KeyResolver {
    
        @Override
        public Mono<String> resolve(ServerWebExchange exchange) {
            return Mono.just(exchange.getRequest().getURI().getPath());
        }
    
    }
    

    同样可以以用户的维度去限流,代码如下:

    public class UserKeyResolver  implements KeyResolver {
    
        @Override
        public Mono<String> resolve(ServerWebExchange exchange) {
            return Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
        }
    
    }
    

    启始类中配置如下:

    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    import reactor.core.publisher.Mono;
    
    @SpringBootApplication
    public class GatewayLimiterApplication {
    
       public static void main(String[] args) {
          SpringApplication.run(GatewayLimiterApplication.class, args);
       }
    
       @Bean
       public KeyResolver hostAddKeyResolver(){
          return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
       }
    
    }
    

    需要在启始类启动的时候将这些KeyResolver放到spring容器中

    运行项目

    首先先运行redis:在redis的安装目录路径下打开命令窗口,执行redis-server.exe redis.windows.conf,这样redis就启动了,这个窗口不要关闭!
    在这里插入图片描述
    接下来依次运行:eurekaserver、gateway-service-hi、gateway-limiter

    这时在redis的安装目录路径下重新打开一个命令窗口,执行redis-cli.exe -h 127.0.0.1 -p 6379
    接着执行monitor实时查看redis状态

    最后访问:http://localhost:8887/gateway/hi

    在这里插入图片描述
    在这里插入图片描述
    可见,RequestRateLimiter是使用Redis来进行限流的。

    展开全文
  • 基于gateway网关实现限流

    千次阅读 2020-09-29 19:42:16
    在前面的限流方案介绍中,我们谈到了网关在微服务体系架构中的重要作用,网关不经具备大家熟知的动态路由,请求拦截等功能外,还可以基于网关实现分布式环境下的限流,下面我们以gatway为例,用代码进行实现一下 ...

    前言

    在前面的限流方案介绍中,我们谈到了网关在微服务体系架构中的重要作用,网关不经具备大家熟知的动态路由,请求拦截等功能外,还可以基于网关实现分布式环境下的限流,下面我们以gatway为例,用代码进行实现一下

    实现原理

    • 所有经过网关代理的请求会被网关进行拦截
    • 基于拦截到的请求,可以以IP、请求参数、方法名等作为限流的维度
    • 既然是限流,必然存在一个存储请求信息的地方,我们这里选用redis,简单高效,只需配置一定的策略即可

    代码实现逻辑

    1、添加pom依赖

    		<dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    
     		<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starte
    展开全文
  • 下面小编就为大家分享一篇基于Redis的限流器的实现(示例讲解),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 实战系列-Java实现限流算法

    千次阅读 2021-04-20 10:50:23
    文章目录限流算法之漏桶算法漏桶的实现限流算法之令牌桶法简单的令牌桶算法实现总结 限流算法之漏桶算法   漏桶算法:首先保证请求先进入到漏桶中,漏桶再通过一定的速度将流量引出,这里需要注意的是当流量太大...

    导语
      在Java开发过程中,经常用到的限流算法有两种,一种是令牌桶算法,一种是漏斗桶算法,那么下面就来分别看看两种算法的Java实现方式。

    限流算法之漏桶算法

      漏桶算法:首先保证请求先进入到漏桶中,漏桶再通过一定的速度将流量引出,这里需要注意的是当流量太大或者是漏桶已经满了之后会直接溢出,然后就开始拒绝请求,可以看出漏桶算法能强行限制数据传输的速率。如图所示,图来自网络

    在这里插入图片描述

    漏桶的实现

      实现的关键点:

    • 1、定义这个桶的最大容量;
    • 2、记录好上次操作完成后的时间以及桶的剩余量,用来记录后续计算当前桶的容量;
    • 3、定义好流速,速率越小,流控越大,流量越小;
    • 4、每次请求,需要先检查桶大小,如果超过最大值,则拒绝,如果没有超过最大值则继续进行操作;
    public class LeakyBucket {
    
        // 流出速率
        private double rate;
    
        // 桶大小
        private double burst;
    
        // 最后更新时间
        private long refreshTime;
    
        // 现有量
        private int water;
    
    
        public LeakyBucket(double rate,double burst){
            this.rate = rate;
            this.burst = burst;
        }
    
        /**
         * 用来刷新水量
         */
        private void refreshWater(){
            long now = System.currentTimeMillis();
            water = (int) Math.max(0,water-(now-refreshTime)* rate);
            refreshTime = now;
        }
    
        public synchronized boolean tryAcquire(){
            refreshWater();
            if (water<burst) {
                water++;
                return true;
            }else {
                return false;
            }
        }
    
    
        private static LeakyBucket leakyBucket = new LeakyBucket(1,100);
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < 1000; i++) {
                executorService.execute(()->{
                    System.out.println(leakyBucket.tryAcquire());
                });
            }
            executorService.shutdown();
        }
    }
    

    限流算法之令牌桶法

      系统通过一定的速率往桶里面添加令牌,处理请求之前,需要先从桶里获取一个令牌,当桶里没有令牌的时候则需要进行返回失败。
      大概描述如下:

    • 所有的请求在处理之前都需要拿到一个可用的令牌才会被处理;
    • 获取不到令牌,则请求返回失败;
    • 根据限流大小,设置按照一定的速率往桶里添加令牌;
    • 桶要设置最大放置令牌的限制,当桶满的时候、添加新的令牌就会被丢弃或者拒绝;

     如图所示

    在这里插入图片描述

    简单的令牌桶算法实现

      实现关键点

    • 1、初始化固定数量的令牌放入令牌桶中
    • 2、初始化和开启一个定时任务,定时往令牌桶添加令牌
    • 3、提供一个获取令牌的方法,获取一个令牌,令牌桶中减一,如果令牌桶为空,则返回失败
    public class TokenLimiter {
    
        private ArrayBlockingQueue<String> blockingQueue;
        private int limit;
        private TimeUnit timeUnit;
        private int period;
    
    
        public TokenLimiter(int limit,int period,TimeUnit timeUnit){
            this.limit = limit;
            this.timeUnit = timeUnit;
            this.period = period;
            blockingQueue = new ArrayBlockingQueue<>(limit);
            init();
            start();
        }
    
    
    
        /**
         * 初始化令牌操作
         */
        private void init() {
            for (int i = 0; i < limit; i++) {
                blockingQueue.add("1");
            }
        }
    
        /**
         * 获取令牌为空,返回false
         * @return
         */
        public boolean tryAcquire(){
            return blockingQueue.poll()==null?false:true;
        }
    
        private void addToken(){
            blockingQueue.offer("1");
        }
    
    
    
    
        private void start() {
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(()->{
                addToken();
            },10,period,timeUnit);
        }
    }
    
    

    总结

      上面通过简单的方式实现了两种限流算法,当然还是有很多的改进的地方,这里只是通过简单的代码对两种算法的核心内容进行演示,当然后续高级算法的演变也是基于核心思想来进行的变化。

    展开全文
  • 微服务Zuul实现限流保护

    千次阅读 2020-01-28 16:16:02
    spring boot版本:2.1.10.RELEASE 1、项目搭建 ...2、添加限流相关依赖 <!--Zuul限流的相关依赖--> <dependency> <groupId>com.marcosbarbero.cloud</groupId> <artifactId...

    spring boot版本:2.1.10.RELEASE

    1、项目搭建

    所需依赖及项目的搭建请参考上一篇博客 微服务中网关的作用及搭建

    2、添加限流相关依赖

    <!--Zuul限流的相关依赖-->
    <dependency>
        <groupId>com.marcosbarbero.cloud</groupId>
        <artifactId>spring-cloud-zuul-ratelimit</artifactId>
        <version>1.3.4.RELEASE</version>
    </dependency>
    

    4、针对某个服务限流

    application.properties 中添加如下配置:

    # 针对某个服务进行限流
    zuul.routes.book-product.path=/book-product/**
    zuul.routes.book-product.serviceId=ebook-product-core
    
    #开启限流
    zuul.ratelimit.enabled=true
    #60s内请求超过3次,服务端就抛出异常,60s后可以恢复正常请求
    zuul.ratelimit.policies.book-product.limit=3
    zuul.ratelimit.policies.book-product.refresh-interval=60
    #针对某个IP进行限流,不影响其他IP
    zuul.ratelimit.policies.book-product.type=origin
    

    5、全局限流

    #全局配置限流
    zuul.ratelimit.enabled=true
    zuul.ratelimit.default-policy.limit=3
    zuul.ratelimit.default-policy.refresh-interval=60
    zuul.ratelimit.default-policy.type=origin
    

    6、配置详解

    zuul.ratelimit.enabled:

    是否开启限流,默认值false。


    zuul.ratelimit.repository:

    限流的存储方式。支持4种存储方式:

    • IN_MEMORY:使用ConcurrentHashMap作为数据存储(在内存中),作为默认值。
    • REDIS:使用 Redis 作为数据存储。
    • CONSUL:使用 Consul 作为数据存储。
    • JPA:使用 数据库 作为数据存储。

    zuul.ratelimit.policies.ServiceId.refresh-interval:

    刷新时间窗口的时间,单位秒,默认值 60秒。


    zuul.ratelimit.policies.ServiceId.limit:

    每个刷新时间窗口对应的请求数量限制


    zuul.ratelimit.policies.ServiceId.quota:

    单位时间内允许访问的总时间(统计每次请求的时间综合)。例如:

    refresh-interval=60;limit=10;quota=30;,即60秒内允许10个访问,并且要求总请求时间小于30秒。


    zuul.ratelimit.policies.ServiceId.type:

    限流的类型。支持三种类型的限流:

    • ORIGIN:对访问IP进行限流(例如:某个IP每分钟只允许请求多少次)。
    • URL:对请求的URL进行限流(例如:某个URL每分钟只允许调用多少次)。
    • USER:对某些特定用户或者用户组进行限流(例如:非VIP用户限制每分钟只允许调用100次某个API等)。

    展开全文
  • 主要介绍了spring cloud gateway 限流实现与原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Java限流实现

    2019-04-24 01:06:45
    NULL 博文链接:https://bijian1013.iteye.com/blog/2382409
  • 写在前面 最近,有不少读者说看了我的文章后,学到了很多知识,其实我本人听到后是非常开心的,自己写的东西能够为大家带来...想来想去,写一篇关于高并发实战的文章吧,对,就写一下如何使用Nginx实现限流的文章吧。
  • 一般对外暴露的系统,在促销或者黑客攻击时会涌来大量的请求,为了保护系统不被瞬间到来的高并发流量给打垮, 就需要限流,这篇文章主要介绍了nginx限流方案的实现,非常具有实用价值,需要的朋友可以参考下
  • 【开发经验】java代码中实现限流

    千次阅读 2020-07-08 21:16:12
    限流目的 限流的目的是防止恶意请求流量、恶意攻击、或者防止流量超过系统峰值。 流量达到峰值时,会有一个熔断策略,常见的熔断策略: 直接拒绝请求,跳转到一个“服务器出小差”页面 排队等待,比如火车票等待。 ...
  • 基于令牌桶算法的Java限流实现。 项目需要使用限流措施,查阅后主要使用令牌桶算法实现,为了更灵活的实现限流,就自己实现了一个简单的基于令牌桶算法的限流实现。
  • SpringCloud中使用Sentinel实现限流

    万次阅读 多人点赞 2020-07-27 18:25:52
    Sentinel Sentinel 是面向微服务的轻量级流量控制框架,从流量控制、熔断降级、系统负载...服务降级:针对核心业务服务的压力剧增,根据当前业务场景和流量对其他非核心服务进行降级处理,可以进行限流,快速返回等处理
  • Redis 实现限流的三种方式

    万次阅读 多人点赞 2019-05-30 23:37:24
    当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式。Redis不仅仅是可以做限流,还可以做数据统计,附近的人等功能,这些可能会后续写到。 第一种...
  • zuul实现限流

    千次阅读 2019-05-18 10:14:31
    zuul限流 限流算法 漏桶: leakey bucket,原理:桶的下方的小孔会以一个相对恒定的速率漏水,而不管入桶的水流量,这样就达到了控制出水口的流量 令牌桶: token bucket,原理:以相对恒定的速率向桶中加入令牌,请求...
  • 主要介绍了Golang 限流器的使用和实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • Redis如何实现限流算法

    千次阅读 2019-04-21 23:28:37
    本文将介绍如何利用Redis实现限流算法,希望您有所收获。
  • 1. 在zuul网关服务中实现限流 1.1 为什么需要限流? 限流是为了保证服务器的负载量处于正常状态,因为如果太多的访问量可能会直接导致服务的崩溃。 1.2 如何实现限流 1.2.1 令牌桶算法简介 在zuul中实现限流是通过...
  • spring cloud gateway(实现限流

    千次阅读 2018-12-06 17:33:30
    spring cloud gateway(实现限流) 限流一般有两个实现方式,令牌桶和漏桶 令牌桶是初始化令牌(容器)的个数,通过拿走里边的令牌就能通过, 没有令牌不能报错,可以设置向容器中增加令牌的速度和最大个数 漏桶...
  • gateway实现限流和熔断

    2020-11-30 14:50:47
    Gateway通过内置的RequestRateLimiter过滤器实现限流,使用令牌桶算法,借助Redis保存中间数据。用户可通过自定义KeyResolver设置限流维度,例如: 对请求的目标URL进行限流 对来源IP进行限流 特定用户进行限流 本例...
  • 基于Hystrix实现限流

    千次阅读 2019-04-17 22:31:53
    前言 在微服务治理中,我们常常会遇到依赖接口超时或者调用失败的场景,如果没有对这些异常的场景做补偿会影响用户体验,甚至会导致应用瘫痪,影响其他业务。那如何解决呢?目前业界常用的方案就是熔断和降级两种...
  • 关注“Java艺术”一起来充电吧!我们项目中使用了Sentinel作为限流器,Sentinel可配置按最大工作线程数以及按QPS限流,而要实现这两个限流规则,就必须要统计到当前工作线程数...
  • Nginx结合Lua实现限流

    千次阅读 2019-01-10 14:02:45
    初始化限流策略信息 limitdata_init.lua 初始化限流策略信息 limitdata_init.lua /** Created by Erick. ** DateTime: 2019-1-4 16:35 ** 初始化文件限流数据到table中 **/ local limit_table = ngx . shared...
  • Springboot使用Redis-Cell实现限流

    千次阅读 2021-11-10 15:14:11
    Redis-Cell限流插件安装(Centos)_毅呀毅呀哟-CSDN博客一、下载wget https://github.com/brandur/redis-cell/releases/download/v0.3.0/redis-cell-v0.3.0-x86_64-unknown-linux-gnu.tar.gz二、解压tar -zxvf redis...
  • java实现 限流算法 漏斗模型

    千次阅读 2019-03-19 17:17:14
    package com.example.redis.漏斗限流; /** * @Auther: liuyujie * @Date: 2019/3/4 12:48 * @Description: */ public class Funnel { int capacity;//漏斗容量 double leakingRate;//漏水速度 int leftQuota...
  • (四)redis实现限流的两种方式

    千次阅读 2020-11-14 00:31:59
    每次请求过来,都会使用zset的范围查询统计总数,这个范围就是(当前时间)到(当前时间-滑动窗口时间),然后将总数和限流次数进行比较,从而决定是否限流 那这个 zset 的 value 填什么比较合适呢?它只需要保证...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 547,242
精华内容 218,896
关键字:

怎么实现限流