springcloud-gateway限流

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: springcloud-gateway限流

正文


一、常见限流算法


1.漏桶算法(不推荐)


111.png


1.原理:将请求缓存到一个队列中,然后以固定的速度处理,从而达到限流的目的


2.实现:将请求装到一个桶中,桶的容量为固定的一个值,当桶装满之后,就会将请求丢弃掉,桶底部有一个洞,以固定的速率流出。


3.举例:桶的容量为1W,有10W并发请求,最多只能将1W请求放入桶中,其余请求全部丢弃,以固定的速度处理请求


4.缺点:处理突发流量效率低(处理请求的速度不变,效率很低)


2.令牌桶算法(推荐)


333.png


1.原理:将请求放在一个缓冲队列中,拿到令牌后才能进行处理


2.实现:装令牌的桶大小固定,当令牌装满后,则不能将令牌放入其中;每次请求都会到桶中拿取一个令牌才能放行,没有令牌时即丢弃请求/继续放入缓存队列中等待


3.举例:桶的容量为10w个,生产1w个/s,有10W的并发请求,以每秒10W个/s速度处理,随着桶中的令牌很快用完,速度又慢慢降下来啦,而生产令牌的速度趋于一致1w个/s


4.缺点:处理突发流量提供了系统性能,但是对系统造成了一定的压力,桶的大小不合理,甚至会压垮系统(处理1亿的并发请求,将桶的大小设置为1,这个系统一下就凉凉啦)


二、网关限流(springcloud gateway + redis实战)


1.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>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
    </dependency>


2.yaml配置


spring:
  application:
    name: laokou-gateway
  cloud:
    gateway:
      routes:
        - id: LAOKOU-SSO-DEMO
          uri: lb://laokou-sso-demo
          predicates:
          - Path=/sso/**
          filters:
          - StripPrefix=1
          - name: RequestRateLimiter #请求数限流,名字不能乱打
            args:
              key-resolver: "#{@ipKeyResolver}"
              redis-rate-limiter.replenishRate: 1 #生成令牌速率-设为1方便测试
              redis-rate-limiter.burstCapacity: 1 #令牌桶容量-设置1方便测试
  redis:
    database: 0
    cluster:
      nodes: x.x.x.x:7003,x.x.x.x:7004,x.x.x.x:7005,x.x.x.x:7003,x.x.x.x:7004,x.x.x.x:7005
    password: laokou #密码
    timeout: 6000ms #连接超时时长(毫秒)
    jedis:
      pool:
        max-active: -1 #连接池最大连接数(使用负值表示无极限)
        max-wait: -1ms #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 10 #连接池最大空闲连接
        min-idle: 5 #连接池最小空间连接


3.创建bean


@Bean(value = "ipKeyResolver")
    KeyResolver ipKeyResolver() {
        return exchange -> {
            String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
            log.info("ip:{}",ip);
            return Mono.just(ip);
        };
    }


三、测试限流(编写java并发测试)


@Slf4j
public class HttpUtil {
public static void apiConcurrent(String url,Map<String,String> params) {
        Integer count = 200;
        //创建线程池
        ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 200, 0L, TimeUnit.SECONDS, new SynchronousQueue<>());
        //同步工具
        CountDownLatch latch = new CountDownLatch(count);
        Map<String,String> dataMap = new HashMap<>(1);
        dataMap.put("authorize","XXXXXXX");
        for (int i = 0; i < count; i++) {
            pool.execute(() -> {
                try {
                    //访问网关的API接口
                    HttpUtil.doGet("http://localhost:1234/sso/laokou-demo/user",dataMap);
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    latch.countDown();
                }
            });
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
public static String doGet(String url, Map<String, String> params) throws IOException {
        //创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            //创建uri
            URIBuilder builder = new URIBuilder(url);
            if (!params.isEmpty()) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    builder.addParameter(entry.getKey(), entry.getValue());
                }
            }
            URI uri = builder.build();
            //创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            List<NameValuePair> paramList = new ArrayList<>();
            RequestBuilder requestBuilder = RequestBuilder.get().setUri(new URI(url));
            requestBuilder.setEntity(new UrlEncodedFormEntity(paramList, Consts.UTF_8));
            httpGet.setHeader(new BasicHeader("Content-Type", "application/json;charset=UTF-8"));
            httpGet.setHeader(new BasicHeader("Accept", "*/*;charset=utf-8"));
            //执行请求
            response = httpClient.execute(httpGet);
            //判断返回状态是否是200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            log.info("调用失败:{}",e);
        } finally {
            if (response != null) {
                response.close();
            }
            httpClient.close();
        }
        log.info("打印:{}",resultString);
        return resultString;
    }
}


111.png

222.png


说明这个网关限流配置是没有问题的





相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
算法 NoSQL Java
spring cloud gateway网关限流
一般开发高并发系统常见的限流有: 1)限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如 nginx 的 limit_conn 模块,用来限制瞬时并发连接数)、 2)限制时间窗口内的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_req 模块,限制每秒的平均速率); 3)其他还有如限制远程接口调用速率、限制 MQ 的消费速率。 4)另外还可以根据网络连接数、网络流量、CPU 或内存负载等来限流。 本文讨论在gateway集成的实现
|
Java API Maven
Sentinel 实现网关限流(Spring-Gateway)
Sentinel 不仅仅可以可以作用于服务之间,还可以完美的和服务网关 GateWay 或者 Zuul 一起使用来对网关实现流控。
656 0
Sentinel 实现网关限流(Spring-Gateway)
|
存储 JSON 算法
微服务网关鉴权:gateway使用、网关限流使用、用户密码加密、JWT鉴权(二)
微服务网关鉴权:gateway使用、网关限流使用、用户密码加密、JWT鉴权(二)
微服务网关鉴权:gateway使用、网关限流使用、用户密码加密、JWT鉴权(二)
|
算法 NoSQL 安全
SpringCloud Gateway 通过redis实现限流
SpringCloud Gateway 通过redis实现限流
1065 0
SpringCloud Gateway 通过redis实现限流
|
6月前
|
Java Spring
springcloud gateway sential 限流 自定义参数限流执行顺序问题
springcloud gateway sential 限流 自定义参数限流执行顺序问题
61 1
|
8月前
|
Java Sentinel 微服务
|
9月前
|
SpringCloudAlibaba Java Sentinel
十四.SpringCloudAlibaba极简入门-Sentinel对Gateway网关进行限流
服务网关在微服务架构中充当了请求访问入口的角色,是非常重要的一个部分,在高并发的系统中我们通常会在网关层通过流控降级等手段把多余的请求拒绝在外来防止微服务被高并发请求打垮,在之前我们有讨论过《服务网关Spring Cloud Gateway》和 《Sentinel流控》,一个是服务网关,一个是流控降级,本篇文章要讨论的是如何使用Sentinel对Gateway进行流控
|
9月前
|
Java API Maven
SpringCloud Gateway - 集成 Sentinel 流量限流、熔断
SpringCloud Gateway - 集成 Sentinel 流量限流、熔断
1126 0
|
12月前
|
JSON 监控 安全
Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!
Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!
|
数据采集 监控 Java
熔断限流与关网 Gateway|学习笔记(三)
快速学习熔断限流与关网 Gateway
113 0
熔断限流与关网 Gateway|学习笔记(三)