springcloud-限流
限流算法
-
计数器
每个单位时间能通过的请求数固定,超过阈值直接拒绝。
通过维护一个单位时间内的计数器,每次请求计数器加1,当单位时间内计数器累加到大于设定的阈值,则之后的请求都被绝,直到单位时间已经过去,再将计数器重置为零。
-
漏桶算法
维持一个队列,所有请求先进队列,然后从队列取出请求的速率是固定。【保护请求】
漏桶算法可以很好地限制容量池的大小,从而防止流量暴增。漏桶可以看作是一个带有常量服务时间的单服务器队列,如果漏桶(包缓存)溢出,那么数据包会被丢弃。 在网络中,漏桶算法可以控制端口的流量输出速率,平滑网络上的突发流量,实现流量整形,从而为网络提供一个稳定的流量。
漏桶算法需要通过两个变量进行控制:一个是桶的大小,支持流量突发增多时可以存多少的水(burst),另一个是水桶漏洞的大小(rate)(从队列取出请求)
-
令牌桶算法
按一定额定的速率产生令牌,存入令牌桶,桶有最大容量(应该为微服务最大承载);服务过来时需要请求到一个令牌才可以进入服务执行;服务里就可以保持基本不会超过承载值。【保护服务】
令牌桶算法是对漏桶算法的一种改进,桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用的平均速率的同时还允许一定程度的突发调用。在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。放令牌这个动作是持续不断的进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这时进来的请求就可以直接拿到令牌执行,比如设置qps为100,那么限流器初始化完成一秒后,桶中就已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。
一、基于springcloud-gateway的Filter限流
SpringCloudGateway官方就提供了基于令牌桶的限流支持。基于其内置的过滤器工厂RequestRateLimiterGatewayFilterFactory
实现。在过滤器工厂中是通过Redis和lua脚本结合的方式进行流量控制。
-
redis 和 redis依赖
-
redis
下载redis,启动redis-server服务端,启动redis-cli客户端
-
依赖
springcloud项目需要引入redis的reactive依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifatId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
-
-
修改网关的aplication.yml
spring: application: name: api-gateway #指定服务名 cloud: gateway: routes: - id: order-service uri: lb://shop-service-order filters: - RewritePath=/order-service/(?<segment>.*), /$\{ segment} - name: RequestRateLimiter args: # 使用SpEL从容器中获取对象pathKeyResolver,根据这个对象来进行限流 key-resolver: '#{@pathKeyResolver}' # 令牌桶每秒填充平均速率 redis-rate-limiter.replenishRate: 1 # 令牌桶的总容量 redis-rate-limiter.burstCapacity: 3 redis: host: localhost port: 6379
-
配置redis中key的解析器KeySesolver(包含上面配置的key-resolver对象pathKeyResolver)
@Configuration public