> 文章列表 > 【微服务笔记18】微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)

【微服务笔记18】微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)

【微服务笔记18】微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)

这篇文章,主要介绍微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)。

目录

一、服务限流

1.1、几种限流算法

(1)计数器算法

(2)漏桶算法

(3)令牌桶算法

1.2、Gateway实现服务限流

(1)引入依赖

(2)添加配置信息

(3)指定令牌生成方式

(4)运行测试


一、服务限流

1.1、几种限流算法

限流就是指:限制服务的请求量,客户端每秒钟发起的HTTP请求数量(QPS,Queries Per Second),表示每秒钟的查询数量。为了能避免大量请求堆积,从而导致服务器宕机,所以就需要对请求进行限流操作。常见的限流算法有下面这些:

  • 计数器算法(Counter)。
  • 漏桶算法(Leaky Bucket)。
  • 令牌桶算法(Token Bucket)。

(1)计数器算法

计数器算法是指:设置一个计数器,当在指定的时间范围里面,某个接口有访问则将计数器加1,当计数器达到最大值,并且此时是在这个时间范围里面,那么此时就对这个接口进行限流操作。

这种算法虽然实现简单,但是存在一个问题,那就是如果在结束时间和下一次开始时间之间,刚好来了大量请求,那么此时就是1秒出现大量请求,有可能导致服务崩溃。

(2)漏桶算法

漏桶算法,是指:大量请求可以到达,但是这些请求会首先进入一个地方,我们这个地方叫做:桶,请求来了就放入桶里面,然后每次这个桶就分发一个请求给对应的微服务,从而实现限流操作。

这种算法虽然能够控制请求量,但是也有问题,那就是如果大量请求同时达到Gateway,那么Gateway可能会出现宕机情况,此外由于每次都是从桶中分发一个请求到下游系统,如果下游系统每次能够处于200个请求,显示浪费了下游系统的资源。

(3)令牌桶算法

令牌桶算法,是对漏桶算法的一个改进,它的思想是:对每次请求都需要获取一个令牌,只要拿到令牌的请求才能够继续执行,没有拿到令牌的请求,要么被阻塞,要么快速失败,令牌桶算法会有一个桶专门用于保存令牌,这个令牌会按照规则自动生成并放入令牌桶里面。

令牌桶算法是最优的一种限流算法,Gateway中的限流算法就是采用了令牌桶算法,支持三种令牌桶算法:基于URI限流、基于请求参数限流、基于IP限流。

1.2、Gateway实现服务限流

Gateway中提供的限流是采用的令牌桶算法,并且基于Redis + LUA脚本实现的限流,所以这里需要引入redis的依赖。

(1)引入依赖

  • 在gateway工程中,引入redis依赖、gateway依赖。
<!-- 引入 Gateway 依赖 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 引入 redis 依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<!-- 引入 commons-pool 连接池依赖 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

(2)添加配置信息

在application.yml配置文件中,添加如下内容:

server:port: 8888
spring:application:name: gateway-limiting# 配置 gateway 路由信息cloud:gateway:# 指定路由信息routes:- id: consumer-client # 路由唯一标识,一般和微服务应用名称相同即可# 目标路由的服务地址,这里采用的是静态路由(将微服务的地址写死在配置文件里面)uri: http://localhost:8081/# 配置断言,也就是请求的URI满足哪些规则,才可以匹配当前这个routes路由信息predicates:# 这里使用路由断言- Path=/**filters:# 指定限流过滤器- name: RequestRateLimiterargs:# 基于令牌桶算法,生成令牌的速率redis-rate-limiter.replenishRate: 1# 令牌桶的最大容量redis-rate-limiter.burstCapacity: 2# 指定生成令牌的算法解析策略,这里是使用了SpEL表达式,获取寻找名字是 keyResolver 的bean对象key-resolver: "#{@keyResolver}"# redis 配置redis:host: 127.0.0.1port: 6379database: 0lettuce:pool:max-active: 1024max-wait: 10000max-idle: 200min-idle: 5

(3)指定令牌生成方式

Gateway中可以有多种限流策略,例如:通过URI进行限流、通过请求参数限流、通过IP地址限流。要是有哪一种限流策略,只需要修改对应的KeyResolver即可。

package com.gitee.demo.config;import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;/*** @version 1.0.0* @Date: 2023/4/20 14:16* @Copyright (C) ZhuYouBin* @Description: 令牌桶算法中,令牌的生成算法*/
@Configuration
public class KeyResolverConfiguration {@Beanpublic KeyResolver keyResolver() {return new KeyResolver() {@Overridepublic Mono<String> resolve(ServerWebExchange exchange) {// 这里根据请求【URI】进行限流return Mono.just(exchange.getRequest().getPath().toString());}};}//    @Bean
//    public KeyResolver keyResolver() {
//        return new KeyResolver() {
//            @Override
//            public Mono<String> resolve(ServerWebExchange exchange) {
//                // 这里根据请求【请求参数username】进行限流
//                return Mono.just(exchange.getRequest().getQueryParams().getFirst("username"));
//            }
//        };
//    }
//
//    @Bean
//    public KeyResolver keyResolver() {
//        return new KeyResolver() {
//            @Override
//            public Mono<String> resolve(ServerWebExchange exchange) {
//                // 这里根据请求【IP地址】进行限流
//                return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
//            }
//        };
//    }}
  • 注意:KeyResolver只能够存在一个Bean对象。

(4)运行测试

启动redis服务、启动网关工程、启动消费者工程,浏览器访问某个接口,测试是否限流成功。假设现在是采用URI限流模式,并且配置文件中设置的是最大允许2个请求同时访问,超过2个请求,就会报错,客户端就会接收到【HTTP ERROR 429】的响应结果,这表示被限流了。

到此,Gateway服务限流就介绍完啦。

综上,这篇文章结束了,主要介绍微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)。