实战讲解SpringCloud网关接口限流SpringCloudGateway+Redis(图+文)

news2024/11/16 2:43:06

1 缘起

最近补充微服务网关相关知识,学习了网关相关概念,
了解网关在微服务中存在的意义及其使命,如统一用户认证、接口权限控制、接口限流、接口熔断、黑白名单机制等,
打算通过实践的方式逐步学习网关的相关功能,同时分享网关应用系列文章。
本文分享通过网关实现接口限流,构建相关服务,帮助读者轻松应对知识考核与交流。

2 架构

本文的服务架构如下图所示,
由图可知,应用架构共有三个部分:网关、注册中心和服务,
通过网关进行接口限流,当然是在网关中做文章,实现接口的流量控制。
本套架构基于Spring原生的组件,其中,网关:SpringCloudGateway,注册中心:Eureka,服务:SpringBoot。
在这里插入图片描述

3 Gateway配置

使用Gateway进行接口限流,注解当然是Gateway服务,
如下配置均是对Gateway服务进行的,其他的服务各自按照需要准备好即可,
需要注意的是:其他服务与网关应该在同一个注册中心。

3.1 依赖

学技术,讲版本。
SpringBoot与SpringCloud的版本对应关系如下表:
官网查询地址:https://start.spring.io/actuator/info

序号SpringCloud版本SpringBoot版本
1Edgware1.5.x
2Finchley2.0.x
3Greenwich2.1.x
4Hoxton.SR12[2.2.0.RELEASE, 2.4.0.M1)
52020.0.6[2.4.0.M1, 2.6.0-M1)
62021.0.0-M1[2.6.0-M1, 2.6.0-M3)
72021.0.0-M3[2.6.0-M3, 2.6.0-RC1)
82021.0.0-RC1[2.6.0-RC1, 2.6.1)
92021.0.5[2.6.1, 3.0.0-M1)
102022.0.0-M1[3.0.0-M1, 3.0.0-M2)
112022.0.0-M2[3.0.0-M2, 3.0.0-M3)
122022.0.0-M3[3.0.0-M3, 3.0.0-M4)
132022.0.0-M4[3.0.0-M4, 3.0.0-M5)
142022.0.0-M5[3.0.0-M5, 3.0.0-RC1)
152022.0.0-RC1[3.0.0-RC1, 3.1.0-M1)

3.1.1 SpringBoot

SpringBoot版本:2.2.8.RELEASE。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.8.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

3.1.2 SpringCloud

SpringCloud提供微服务相关组件。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

3.1.3 注册中心&网关&Redis

注册中心:网关为了发现注册中心的服务,配置uri进行限流;
网关:网关配置的基础组件;
Redis:存储限流使用的令牌(Token)。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.2.3.RELEASE</version>
</dependency>
<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-reactive</artifactId>
</dependency>

3.2 创建拦截类型Bean

为什么创建拦截类型Bean?
SpringCloud Gateway中可以自定义配置拦截方式,
通过Spring正则表达式(SpEL)匹配对应的拦截Bean,
所以,要创建接口拦截方式的Bean。
其中,拦截有三种方式:路径拦截、IP拦截和参数拦截,
配置样例如下:

package com.monkey.gateway_template.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import reactor.core.publisher.Mono;

/**
 * 请求限流配置.
 *
 * @author xindaqi
 * @since 2022-11-16 18:19
 */
@Configuration
public class RequestRateLimiter {

    @Primary
    @Bean
    KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }

    @Bean
    KeyResolver apiKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getPath().value());
    }
    @Bean
    KeyResolver paramKeyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("param-name"));
    }
}

3.3 限流配置

SpringCloud Gateway的限流算法采用令牌桶限流,
结合Redis,将令牌存储与Redis,提高读写性能。
网关限流配置的最核心部分如下,
其中,
(1)通过动态路由方式获取注册中心的服务:uri: lb://service-name;
(2)断言路径predicates Path,为了使限流生效,路径不可与服务名称相同;
(3)为使限流生效,需要去除配置的断言路径:StripPrefix=1;
(4)过滤器名称为RequestRateLimiter,Redis约定的名称,不可更改。
限流参数:
(1)key-resolver: “#{@ipKeyResolver}”: 限流方式:Bean名称
(2)redis-rate-limiter.replenishRate: 1生成令牌速率:个/秒
(3)redis-rate-limiter.burstCapacity: 令牌桶容量,突发流量通过网关进入该接口时可处理的最大请求数
(4)redis-rate-limiter.requestedTokens: 1 # 每次消费的Token数量

server:
  port: 9001

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://localhost:8001/eureka/eureka

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启以应用名代理服务,即通过应用名称访问接口
          lowerCaseServiceId: true # 微服务名称小写
      routes:
        - id: producer # 代理的服务ID,唯一
          uri: lb://producer # 代理的服务实例名称,开启微服务名称小写后,可使用小写的名称
          predicates:
            - Path=/producer-server/** # 断言路径,即通过该路径匹配代理的服务,为了使限流生效,路径不可与服务名称相同
          filters:
            - StripPrefix=1 # 去除producer-server,对后面的URI进行限流,保证限流生效
            - name: RequestRateLimiter # 使用Redis限流器
              args:
                key-resolver: "#{@ipKeyResolver}" # 限流方式:Bean名称
                redis-rate-limiter.replenishRate: 1 # 生成令牌速率:个/秒
                redis-rate-limiter.burstCapacity: 3 # 令牌桶容量
                redis-rate-limiter.requestedTokens: 1 # 每次消费的Token数量
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password: 123456
    jedis:
      pool:
        max-active: 1 # 连接池:最大连接数,-1不限制
        max-idle: 8 # 连接池:最大空闲连接数量
        max-wait: 2000 # 连接池:最大阻塞等待时间,-1不限制,单位:毫秒
        min-idle: 0 # 连接池;最小空闲连接数量
      timeout: 1000 # 连接Redis服务器超时时间,单位:毫秒

4 测试

4.1 Postman接口测试

通过接入网关接入接口,Postman测试结果如下图所示。

4.1.1 正常请求

成功响应的结果如下图所示,由图可知,响应头中包含配置的限流参数。

序号参数描述
1X-RateLimit-Remaining剩余可请求次数
2X-RateLimit-Requested-Tokens每次请求消耗的Token数量
3X-RateLimit-Burst-Capacity令牌桶容量,接口可承载的最大峰值请求数量
4X-RateLimit-Replenish-Rate令牌生成速率,个/秒

在这里插入图片描述

4.1.2 被丢弃的请求

请求次数超过配置后,响应结果如下图所示,
由图可知,响应的状态码为429,描述信息为:Too Many Requests。
在这里插入图片描述
SpringGateway生成的数据存储在Redis,样式如下图所示,
由图可知,键名前缀为:request_rate_limiter.
键名后缀为:tokens和timestamp。
在这里插入图片描述

4.2 JMeter测试

为了更好地体验接口限流功能,使用JMeter配置多线程请求接口,
测试结果如下图所示,由结果树可看到请求过程中,有正常的请求,有被拒绝的请求。

4.2.1 正常请求

正常的请求响应内容如下图所示。
在这里插入图片描述

4.2.2 被丢弃的请求

被丢弃的请求响应内容如下图所示。
在这里插入图片描述

5 小结

网关通过动态路由(lb:service-name)方式代理服务时,使限流生效需满足两个条件:
(1)断言中配置的路径前缀不能与服务名称相同,如代理的服务为producer,断言(predicates)路径中的前缀禁止配置为producer;
(2)过滤器(filters)必须配置StripPrefix=1,移除前缀,保证代理的接口可以进行限流;
(3)过滤器名称为RequestRateLimiter,Redis约定的名称,不可更改。
常用的限流方式有3钟,IP限流、路径限流和参数限流:
(1)IP限流:exchange.getRequest().getRemoteAddress().getHostName()
(2)路径限流:exchange.getRequest().getPath().value()
(3)参数限流:exchange.getRequest().getQueryParams().getFirst(“param-name”)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/12322.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零到一落地接口自动化测试

前段时间写了一系列自动化测试的文章&#xff0c;更多是从方法和解决问题思路角度阐述我的观点。 昨天花了几个小时看完了陈磊老师的《接口测试入门课》&#xff0c;有一些新的收获&#xff0c;结合我自己实践自动化测试的一些经验以及个人理解&#xff0c;这篇文章来聊聊新手…

主要控制系统之间的逻辑关系

电力行业 工控安全解决思路保障框架从电力行业对工控安全需求看&#xff0c;电力企业在主要是以合规性建设为主&#xff0c;在 2004 年原电监会 5 号令颁布开始&#xff0c;大部 分的电厂控制系统安全 建设已经按照 5 号令的要求进行了整改&#xff0c;形成“安全分区、网络专…

【2022硬件设计开源盛宴】一年一度的hackaday大赛结束,冠军便携式风力涡轮机,共提交326个电子作品,奖金池15万美元

https://hackaday.com/2022/11/05/ ... -years-competition/ &#xff08;1&#xff09;一年一度的Hackaday大赛结束&#xff0c;今年是第9届了&#xff0c;总奖金池是15万美元&#xff0c;冠军5万美元。前6届&#xff0c;冠军奖金非常高&#xff0c;像第3届冠军是最厉害的&am…

java设计模式之装饰者模式

一&#xff1a;装饰者模式 1.什么是装饰者模式? 装饰模式是一种结构型设计模式&#xff0c; 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 装饰者模式的基本介绍 1.装饰者模式&#xff1a;动态的将新功能附加到对象上。在对象功能扩展方面&#xf…

Jasper 中如何将数据拆成多行并跨行累计

【问题】 I have a query that returns some summary records. For instance, loan amount, loan term, interest rate. Then I want to have a second row that builds out the detailed payment schedule. so the report would look like this: Loan Amt Term …

SpringBoot2

文章目录1.简介1.1 SpringBoot优缺点1.2 官方文档结构2. SpringBoot入门2.1 HelloWord2.2 依赖管理2.3 自动配置2.4 容器功能组件添加原生配置文件引入2.5 配置绑定ConfigurationPropertiesEnableConfigurationProperties2.6 自动配置原理底层总结最佳实践2.7 开发小技巧Lombok…

UML类图简单认识

类 类图包括类、接口和关系。类中包含三元素&#xff0c;第一行是类名&#xff0c;如果是虚类则为斜体。第二行包括属性&#xff0c;如果是public则为&#xff0c;如果是private则为-&#xff0c;如果是protected则为#。第三行包括方法&#xff0c;方法前面的符号表示与属性的…

QSS的应用

盒子模型&#xff1a; margin 边距border 边框padding 内边距content 内容常用的一些属性&#xff1a; background背景background-color背景颜色background-image背景图片background-position对齐方式border-&#xff08;top、left、bottom、right&#xff09;边界border-…

单调栈问题---(每日温度,下一个更大元素Ⅰ)

代码随想录day 58 单调栈问题— 每日温度,下一个更大元素Ⅰ 文章目录1.leetcode 739. 每日温度1.1 详细思路及解题步骤1.2Java版代码示例2.leetcode 496. 下一个更大元素 I2.1 详细思路及解题步骤2.2Java版代码示例1.leetcode 739. 每日温度 1.1 详细思路及解题步骤 这题会用到…

Spark RDD编程模型及算子介绍(一)

文章目录RDD编程模型介绍RDD的两种算子及延迟计算常见的Transformation算子RDD编程模型介绍 RDD是Spark 对于分布式数据集的抽象&#xff0c;它用于囊括所有内存中和磁盘中的分布式数据实体。每一个RDD都代表着一种分布式数据形态。在RDD的编程模型中&#xff0c;一共有两种算…

Linux-服务管理

服务介绍 服务本质就是进程&#xff0c;但是是运行在后台的&#xff0c;通常都会监听某个端口&#xff0c;等待其他程序的ing求&#xff0c;比如mysqld&#xff0c;sshd&#xff0c;防火墙灯&#xff0c;因为又称为守护进程 如何管理服务 CentOS7.0前使用service命令 servi…

SpringBoot-配置

目录 起步依赖原理分析 配置文件分类 YAML YAML&#xff1a;基本语法 YAML&#xff1a;数据格式 YAML&#xff1a;参数引用 读取配置内容 profile Profile-小结 内部配置加载顺序 外部配置加载顺序 起步依赖原理分析 在spring-boot-starter-parent中定义了各种技术的…

[附源码]Python计算机毕业设计GuiTar网站设计

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【学习笔记】《模式识别》4:贝叶斯判别准则

贝叶斯判别准则 文章目录贝叶斯判别准则一、研究对象及相关概率1. 两类研究对象2.概率3. 条件概率4. 模式识别中的三个概率5. 两对条件概率的区别二、贝叶斯决策1.最小错误率贝叶斯决策2. 最小风险贝叶斯决策3. (0-1)损失最小风险贝叶斯决策4.正态分布模式的贝叶斯决策三、贝叶…

RFID在钢筋仓库管理中的应用

RFID在钢筋仓库管理中的应用 应用背景 随着经济的迅速发展&#xff0c;带动了钢材业的迅速发展&#xff0c;钢筋的使用量也在改革开放后有了近370多倍的增长&#xff0c;如此大量的钢筋在库存管理&#xff0c;盘点&#xff0c;防盗&#xff0c;各种型号发货、防窜货上等等一系…

图片链接或pdf链接通过浏览器打开时,有时可以直接预览,有时却是下载,为什么?

在前端开发中&#xff0c;有时候需要对一些文件链接进行特殊处理&#xff0c;比如对于一些图片链接或者PDF链接&#xff0c;有时我们需要通过浏览器打开进行预览&#xff0c;有时又不希望通过浏览器进行打开&#xff0c;而是希望能够直接下载到本地。但现实效果却往往跟我们相反…

硅麦驱动开发及调试(pdm>>I2S>>pcm)

pdm 协议 PDM接口只有两根信号线&#xff1a; PDM_CLK 时钟信号。 PDM_DATA 数据信号。 I2S协议 数据发送规格 I2S在BCLK的下降沿发送数据&#xff08;发送&#xff09;&#xff0c;在上升沿进行数据采样&#xff08;接收&#xff09;。每次是先发送最高位&#xff0c;最后…

Hadoop概述

Hadoop概述 Hadoop介绍 狭义上Hadoop值的是Apache的一款开源软件。 用java语言实现开源软件框架 允许使用简单的编程模型跨计算机集群对大型数据集进行分布式处理 Hadoop核心组件 Hadoop HDFS(分布式文件存储管理系统)&#xff1a;解决海量数据存储 Hadoop YARN(集群资源管理…

3-2、python内置数据类型(列表和元组)

文章目录序列列表列表的创建列表的基本特性连接操作符和重复操作符成员操作符&#xff08;in和not in&#xff09;索引切片for循环列表的常用方法增加修改&#xff08;通过索引和切片重新赋值&#xff09;查看删除其他操作元组&#xff08;和列表相比&#xff0c;不能增删改元素…

30分钟带你精通Git使用

一、 版本控制工具 1.1. 什么是版本控制系统&#xff1f; 版本控制系统&#xff08;Version Control System&#xff09;:是一种记录一个或若干文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。版本控制系统不仅可以应用于软件源代码的文本文件&#xff0c;而且…