实战讲解SpringCloud网关接口限流SpringCloudGateway+Redis(图+文)
创始人
2024-01-28 10:21:30

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。

org.springframework.bootspring-boot-starter-parent2.2.8.RELEASE 

3.1.2 SpringCloud

SpringCloud提供微服务相关组件。

org.springframework.cloudspring-cloud-dependenciesHoxton.SR5pomimport

3.1.3 注册中心&网关&Redis

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

org.springframework.cloudspring-cloud-starter-netflix-eureka-client2.2.3.RELEASE

org.springframework.cloudspring-cloud-starter-gateway

org.springframework.bootspring-boot-starter-data-redis-reactive

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@BeanKeyResolver ipKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());}@BeanKeyResolver apiKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getPath().value());}@BeanKeyResolver 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: 9001eureka:client:fetch-registry: trueregister-with-eureka: trueservice-url:defaultZone: http://localhost:8001/eureka/eurekaspring: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: 0host: 127.0.0.1port: 6379password: 123456jedis: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”)。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
不用电脑怎么设置苹果铃声 ip... 需要一个app,加上苹果自带的app即可1、手机下载爱思极速版。因为之前换手机搬移数据时店员帮忙整理...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
才高八斗的主人公 三顾茅庐的主... 古代君王在建立自己的政治体系之时,大多会采取一些礼贤下士的手段,对于一些有卓越才能的人放低姿态。因为...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...